IT공부/IT서적

[윤성우 열혈 C프로그래밍] Part3. 포인터와 배열의 완성

shine94 2024. 7. 24. 22:25

** 가로 행, 세로 열

 

** 다차원 배열

 : TYPE arr[세로길이][가로길이];

 

** 2차원 배열도 메모리상에서는 1차원 형태로 존재

            ▲ int arr [3][2];

 

** 3차원 배열은 여러 개의 2차원 배열이 모여있는 형태

 

** **(포인터의 포인터, 더블 포인터)

 : 포인터 변수를 가리키는 이중 포인터 변수

 

** 포인터 변수 대상의 Call-by-reference

void Swap (int* ptr1, int* ptr2)
{
    int temp = *ptr1;
    *ptr1 = *ptr2;
    *ptr2 = temp;
}

▲  두 변수에 저장된 값 바꾸기

 

void Swap (int* p1, int* p2)
{
    int* temp = p1;
    p1 = p2;
    p2 = temp;
}

▲ 두 싱글 포인터 변수에 저장된 값을 바꾸기 - 실패

 

왜?

 : p1과 p2는 바꿨지만,

   이는 main에 있는 ptr1과 ptr2와는 별개의 변수이기 때문

 

void SwapIntPtr(int** dp1, int** dp2)
{
	
    int* temp = *dp1;
    *dp1 = *dp2;
    *dp2 = temp;
}

▲ 두 싱글 포인터 변수에 저장된 값을 바꾸기 - 성공

 

성공 이유?

 : 함수 내에서 포인터 변수 ptr1과 ptr2에직접 접근이 가능하여 두 변수에 저장된 값을 바꿔줘야 함

   따라서 더블포인터 사용 필요 → 교환 성공

 

** 1차원 배열

int arr[10];

int* ptr = arr;

 

** 2차원 배열

int arr_2d[3][4];

int (*ptr)[4] = arr_2d;

 

** arr_2d는 첫 번째 요소를 가리키면서 배열 전체를 의미

    arr_2d[0]는 첫 번째 요소를 가리키되 1행 만을 의

 

** int (*ptr) [4];

   ㄴ int : int형 변수를 가리키는 포인터

   ㄴ (*ptr) : 포인터

   ㄴ [4] : 포인터 연산시 4칸씩 건너뛰는 포인터

 

** 2차원 배열에서도 arr[i] == *(arr + i) 성립

 

** 포인터 배열과 배열 포인터는 혼동하기가 쉬움

   1) 포인터 배열 : 배열 선언, int형 포인터 변수로 이뤄진 int형 포인터 배열

int 포인터_배열 = { &num1, &num2, &num3, &num4 };

 

    2) 배열 포인터  : 포인터 변수 선언, 가로길이가 4인 int형 2차원 배열을 가리키는 용도의 포인터 변수

int (*배열_포인터)[4] = arr_2d;

 

** 함수 포인터

: 함수의 이름은 함수가 저장된 메모리 공간의 주소 값을 의미

   ㄴ 함수의 이름도 그 형태가 상수임

 

** 함수 이름의 포인터 형(type)

 : 반환형과 매개변수의 선언을 통해서 결정짓도록 약속

 

int SimpleFunc(int num) { /* 함수 몸통 */ }

 

1) 반환형이 int이고, 매개변수로 int형 변수 하나 선언된 포인터 형(type)

2) int (*fptr) (int)

    ㄴ int : 반환형이 int인 함수 포인터

    ㄴ (*fptr) : fptr은 포인터

    ㄴ (int) : 매개변수 선언이 int 하나인 함수 포인터

 

** 형(type)이 존재하지 않는 void 포인터

 : void형 포인터 변수에는 어떠한 변수의 주소 값이든 담을 수 있음, 함수의 주소 값도 포함

 

** void형 포인터 변수를 가지고는 아무런 포인터 연산도 하지 못한다.

   ㄴ 값의 변경이나 참조도 불가능

   ㄴ void형 포인터 변수에는 가리키는 대상에 어떠한 형(type) 정보도 담겨있지 않기 때문

   ㄴ 일단 주소 값에만 의미를 두고, 포인터 형은 나중에 결정할 때 유용하게 사용

 

** main 함수로의 인자 전달

#include <stdio.h>

int main(int argc, char* argv[])
{
    printf("Number of strings passed : %d\n", argc);

    for (int i = 0; i < argc; i++)
        printf("%d string : %s \n", i + 1, argv[i]);

    return 0;
}

 

 

** void SimpleFunc(TYPE * arr) == void SimpleFunc(TYPE arr[])

    void SimpleFunc(char** arr) == void SimpleFunc(char* arr[])

 

** 도전 프로그래밍3

1.

#include <stdio.h>

int main(void)
{
    int arr1[4][4];
    int arr2[4][4];
    int arr3[4][4];
    int arr4[4][4];

    int num = 1;
    for (int i = 0; i < 4; i++) 
    {
        for (int j = 0; j < 4; j++) 
        {
            arr1[i][j] = num;
            num += 1;
        }
    }

    num = 1;
    for (int i = 3; i >= 0; i--) 
    {
        for (int j = 0; j < 4; j++)
        {
            arr2[j][i] = num;
            num += 1;
        }
    }

    num = 1;
    for (int i = 3; i >= 0; i--)
    {
        for (int j = 3; j >= 0; j--)
        {
            arr3[i][j] = num;
            num += 1;
        }
    }

    num = 1;
    for (int i = 0; i < 4; i++)
    {
        for (int j = 3; j >= 0; j--)
        {
            arr4[j][i] = num;
            num += 1;
        }
    }

    // 출력
    for (int i = 0; i < sizeof(arr1) / sizeof(arr1[0]); i++)
    {
        for (int j = 0; j < sizeof(arr1[i]) / sizeof(int); j++)
        {
            printf("%d ", arr1[i][j]);
        }
        printf("\n");
    }

    printf("\n");

    for (int i = 0; i < 4; i++)
    {
        for (int j = 0; j < 4; j++)
        {
            printf("%d ", arr2[i][j]);
        }
        printf("\n");
    }

    printf("\n");

    for (int i = 0; i < 4; i++)
    {
        for (int j = 0; j < 4; j++)
        {
            printf("%d ", arr3[i][j]);
        }
        printf("\n");
    }

    printf("\n");

    for (int i = 0; i < 4; i++)
    {
        for (int j = 0; j < 4; j++)
        {
            printf("%d ", arr4[i][j]);
        }
        printf("\n");
    }

    return 0;
}

 

 

2.

#include <stdio.h>

// 4 X 4 고정
int main(void)
{
    int arr1[4][4] = {};
    int num = 1;

    for (int idx = 0; idx < 2; idx++) 
    {
        for (int i = 0 + idx; i < 4 - idx; i++) 
        {
            printf("[%d][%d] : %d\n", 0 + idx, i, num);
            arr1[0 + idx][i] = num;
            num += 1;
        }
        printf("\n");
        for (int i = 1 + idx; i < 4 - idx; i++) 
        {
            printf("[%d][%d] : %d\n", i, 3 - idx, num);
            arr1[i][3 - idx] = num;
            num += 1;
        }
        printf("\n");
        for (int i = 2 - idx; i >= 0 + idx; i--)
        {
            printf("[%d][%d] : %d\n", 3 - idx, i, num);
            arr1[3 - idx][i] = num;
            num += 1;
        }
        printf("\n");
        for (int i = 2 - idx; i >= 1 + idx; i--)
        {
            printf("[%d][%d] : %d\n", i, 0 + idx, num);
            arr1[i][0 + idx] = num;
            num += 1;
        }
        printf("====================================\n");
    }
    printf("\n");

    // 출력
    for (int i = 0; i < 4; i++)
    {
        for (int j = 0; j < 4; j++)
        {
            printf("%d ", arr1[i][j]);
        }
        printf("\n");
    }

    return 0;
}

 

#include <stdio.h>
#include <math.h>>

int main(void)
{
    // 유동적으로 input 받기
    printf("input number : ");
    int inputSize;
    scanf("%d", &inputSize);

    int arr1[inputSize][inputSize] = {};

    const int frontNum = 0;
    const int backNum = inputSize - 1;

    int num = 1;

    for (int idx = 0; idx < ceil(inputSize / 2.0f); idx++) 
    {
        for (int i = 0 + idx; i < inputSize - idx; i++) 
        {
            printf("[%d][%d] : %d\n", frontNum + idx, i, num);
            arr1[frontNum + idx][i] = num;
            num += 1;
        }
        printf("\n");
        for (int i = 1 + idx; i < inputSize - idx; i++)
        {
            printf("[%d][%d] : %d\n", i, backNum - idx, num);
            arr1[i][backNum - idx] = num;
            num += 1;
        }
        printf("\n");
        for (int i = backNum - 1 - idx; i >= 0 + idx; i--)
        {
            printf("[%d][%d] : %d\n", backNum - idx, i, num);
            arr1[backNum - idx][i] = num;
            num += 1;
        }
        printf("\n");
        for (int i = backNum - 1 - idx; i > 0 + idx; i--) 
        {
            printf("[%d][%d] : %d\n", i, frontNum + idx, num);
            arr1[i][frontNum + idx] = num;
            num += 1;
        }
        printf("====================================\n");
    }
    printf("\n");

    // 출력
    for (int i = 0; i < inputSize; i++)
    {
        for (int j = 0; j < inputSize; j++)
        {
            printf("%d ", arr1[i][j]);
        }
        printf("\n");
    }

    return 0;
}

 

 

3.

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    printf("Range of random numbers: 0 ~ %d\n", RAND_MAX);
    for (int i = 0; i < 5; i++)
    {
        printf("Random number output : %d\n", rand());
    }

    printf("\n\n================================\n");
    for (int i = 0; i < 5; i++)
    {
        printf("Random number output : %d\n", (rand() % 99) + 1);
    }
    
    return 0;
}

 

 

4.

** 도전 3에서 사용한 난수는 출력되는 난수가 규칙적이라는 것

   ㄴ 즉, rand 함수는 pseudo-random number → 난수를 흉내내기 위한 알고리즘으로 생성된 값

        https://ko.wikipedia.org/wiki/%EC%9C%A0%EC%82%AC%EB%82%9C%EC%88%98

 

유사난수 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. 유사난수(pseudorandom number)는 난수를 흉내내기 위해 알고리즘으로 생성되는 값을 가리킨다. 이때 유사난수를 생성하는 알고리즘을 유사난수 생성기(pseudorandom num

ko.wikipedia.org

 

** 규칙적인 rand 함수를 극복하고자 나온 srand 함수

 : 발생한 난수의 씨드 값 지정 필요 → 매번 시드값 받는거 귀찮 주로, 시스템 시간 받아서 사용

 

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(void)
{
    int seed;
    printf("input seed value : ");
    scanf("%d", &seed);

     // 1. 시드를 심는다
    srand(seed);

    for (int i = 0; i < 5; i++)
    {
        // 2. 열매를 수확한다
        printf("Random number output : %d\n", rand());
    }

    printf("\nUse current time===========\n");

    // 현재 시간을 이용해서 난수 출력해보기
    srand((int)time(NULL));
    for (int i = 0; i < 5; i++)
    {
        // 2. 열매를 수확한다
        printf("Random number output : %d\n", rand());
    }

    return 0;
}

 

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(void)
{
    srand((int)time(NULL));
    for (int i = 0; i < 2; i++)
    {
        printf("The result of dice %d : %d\n", i + 1, rand() % 6 + 1);
    }
    return 0;
}

 

 

5.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(void)
{
    int same = 0, win = 0;
    int whileFlag = 1;

    srand((int)time(NULL));

    while (whileFlag)
    {
        int inputValue;
        printf("rock 1, scissors 2, paper 3 : ");
        scanf("%d", &inputValue);

        const int computer = rand() % 3 + 1;
        printf("computer : %d / me : %d\n", computer, inputValue);

        if (inputValue == computer)
        {
            printf("same\n");
            same += 1;
            continue;
        }

        switch (inputValue)
        {
            case 1:
            {
                if (computer == 3)
                {
                    printf("you select rock, computer select paper, you lose.\n");
                    whileFlag = 0;
                    break;
                }
                printf("you select rock, computer select scissors, you win.\n");
                win += 1;
                break;
            }
            case 2:{
                if (computer == 1)
                {
                    printf("you select scissors, computer select rock, you lose.\n");
                    whileFlag = 0;
                    break;
                }
                printf("you select scissors, computer select paper, you win.\n");
                win += 1;
                break;
            }
            case 3:{
                if (computer == 2)
                {
                    printf("you select paper, computer select scissors, you lose.\n");
                    whileFlag = 0;
                    break;
                }
                printf("you select paper, computer select rock, you win.\n");
                win += 1;
                break;
            }
            default:
                break;
        }
    }

    printf("win : %d, same : %d\n", win, same);

    return 0;
}

 

 

6.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(void)
{
    srand((int)time(NULL));

    for (int i = 0; i < 3; i++)
    {
        int inputNum[3];
        printf("Select three numbers(0 ~ 9) : ");
        scanf("%d %d %d", &inputNum[0], &inputNum[1], &inputNum[2]);

        const int computer[3] = {
            rand() % 9, rand() % 9, rand() % 9
        };
        printf("computer number : %d, %d, %d\n", computer[0], computer[1], computer[2]);

        int strike = 0, ball = 0;
        for (int j = 0; j < 3; j++)
        {
            if (inputNum[j] == computer[j])
            {
                strike += 1;
                continue;
            }
            ball += 1;
        }

        printf("strike : %d, ball : %d\n", strike, ball);
    }

    return 0;
}

 

 

** 해당 글은 윤성우의 열혈 C프로그래밍 도서를 읽고 정리한 글입니다.

  https://product.kyobobook.co.kr/detail/S000001589148

 

윤성우의 열혈 C 프로그래밍 | 윤성우 - 교보문고

윤성우의 열혈 C 프로그래밍 | 윤성우 열형강의『C 프로그래밍』은 C언어에 대한 기본을 배울 수 있는 개론서이다. 이 책은 총 4개의 파트로 구성이 되어 있다. C언어의 기본이 되는 내용들을 다

product.kyobobook.co.kr