코딩 40일차 C/C++

마스터피스·2023년 11월 13일
0

C/ C++ 

목록 보기
11/35
post-thumbnail

포인터 - 예제 및 해결

1) 포인터도 기본 값 초기화가 가능하다.

    #include "Header.h"

    int main() {

        int* pointer = nullptr;

        if (pointer == 0) {
            printf("zero value 를 갖고 있습니다.");
        }
        else {
            printf("포인터는 실제 주소를 가르키고 있습니다.");
        }

        return 0;
    }

2) 0-value

  • 0-value는 변수들이 가질 수 있는 기본값, 0값, 최초값 등을 의미합니다. 포인터도 역시 0-value를 가질 수 있으며 포인터에서의 0-value는 nullptr 입니다.

3) free 이후에는 포인터 값이 이상한 값으로 초기화 된다. 그래서 포인터 주소값일 잘못 되지 않게 nullptr; 을 선언해준다.

3-1)일반적인 함수 벨류 0 초기화 예제 코드

#include "Header.h"

int main() {

    int* pointer = nullptr;

    pointer = (int*)malloc(sizeof(int));
    *pointer = 10;


    if (pointer == 0) {
        printf("zero value 를 갖고 있습니다.");
    }
    else {
        printf("포인터는 실제 주소를 가르키고 있습니다.\n");
        printf("%d", *pointer);
    }
    free(pointer);
    pointer = nullptr;


    return 0;
}

3-2) 구조체 예제코드

#include "Header.h"

struct Marine {
    int hp = 40;
    int atk = 6;

};

int main() {

    Marine* marine = nullptr;

    marine = (Marine*)malloc(sizeof(Marine));




    return 0;
}

3-3) 구조체 포인터의 배열 예제코드

#include "Header.h"

struct Marine {
    int hp = 40;
    int atk = 6;

};

int main() {

    Marine* marine[40] = { nullptr, };

    printf("%d", marine[0]);

    return 0;
}

3-4) 좀 더 복잡한 코드

#include "Header.h"

struct Marine {
    int hp = 40;
    int atk = 6;

};

int main() {

    Marine* marine[40] = { nullptr, };

    for (int i = 0; i < 40; i++) {
        marine[i] = (Marine*)malloc(sizeof(Marine));
        marine[i]->hp = 40;
        marine[i]->atk = 7;
    }

    for (int i = 0; i < 40; i++) {
        printf("marine[%d].atk = %d\n", i, marine[i]->atk);
    }
    return 0;
}

4) 0 value로 값을 초기화 해서 쓴다

  • 배열의 값을 0-value로 초기화하기 위해서는 { 0, }; 이라는 값을 집어넣어주면 됩니다. 포인터 타입의 배열일 경우에는 { nullptr, }; 이라는 값을 집어 넣어주면 됩니다. 이 두 가지 경우에 배열값을 손쉽게 0-value로 초기화 할 수 있습니다.

예제코드)

#include "Header.h"

int main() {

    int myArray[10] = {0,};



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



    return 0;
}

5) 포인터의 포인터 - 이중포인턴데 구조체면 동적 할당 된 1차원 배열로 보면 된다.

  • 이중 포인터일 경우 두 가지 경우에 대해서 생각하면 포인터의 포인터를 손쉽게 생각할 수 있습니다. 기본형 데이터 타입일 경우 2차원 동적 배열일 가능성을 가장 먼저 떠올리고 구조체 타입일 경우 1차원 포인터의 배열일 가능성을 가장 먼저 떠올리면 맞을 확률이 굉장히 높습니다.

예제코드)

#include "Header.h"

struct Marine {
    int hp = 40;
    int atk = 6;

};

int main() {

    //Marine* marine[20];
    Marine** marine;

    marine = (Marine**)malloc(sizeof(Marine*) * 20);

    for (int i = 0; i < 20; i++) {
        marine[i] = (Marine*)malloc(sizeof(Marine)* 4);
        for (int k = 0; k < 4; k++) {
            marine[i][k].atk = 9;
        }

    }

    for (int i = 0; i < 20; i++) {
        for (int k = 0; k < 4; k++) {
            printf("marine[%d][%d]->atk = %d\n", i,k, marine[i][k].atk);

        }

    }
    return 0;
}

6) 함수의 파라미터의 포인터

  • 함수의 파라미터에 관한 포인터는 주소값을 받기 위함일 수 있지만 배열변수를 받기 위함일 수 있습니다. 배열변수를 받는 함수라면 꼭 배열의 크기를 같이 받는 경향이 있으므로 이를 주의해서 잘 살펴보면 되겠습니다.

예제코드)

#include "Header.h"

void foo(int* a, int count) {
    for (int i = 0; i < count; i++) {
        printf("%d\n", a[i]);
    }
}

int main() {

    int myArray[5] = {4, 6 ,10, 20, 100};
    foo(myArray,5);


    return 0;
}

7) const char*

  • 파라미터로 가장 많이 쓰이는 포인터 타입 중 하나가 const char 입니다. const char 는 문자열임에도 특별히 strcpy를 사용하면 절대로 안 됩니다. 이콜 기호를 사용하여 하드 코딩된 문자열을 넣거나, 문자열 포인터의 시작값을 넣어주어야 하죠.

예제코드)

#include "Header.h"

void foo(const char* str) {
    printf("%c", str[1]);
}

int main() {

    foo("Hello World");

    return 0;
}

8) 파라미터의 const char*

  • 이 const char 의 경우 하드 코딩된 문자열을 넣기 위해 사용되고 이런 하드코딩된 문자열을 '파라미터로 받기 위해' 역시 정말 많이 사용됩니다. 파라미터로 받을 수 있다는 의미는 이콜( = ) 기호를 사용할 수 있다는 것 이죠. 즉, const char 에는 하드코딩된 문자열이나 char 변수의 이름을 넣어주어야 합니다.(사실 정확히 말하면 하드코딩된 문자열 그 자체가 const char 의 주소값을 만들어냅니다)

예제코드)

#include "Header.h"

void foo(const char* str) {
    printf("%c", str[1]);
}

int main() {

    char* str = (char*)malloc(sizeof(char) * 12);
    strcpy(str, "Hello World");
    foo("Hello World");


    return 0;
}
  1. void*
  • void는 어떤 포인터도 될 수 있는 자유로운 포인터입니다.모든 포인터의 기본형 포인터라고 할 수 있습니다. (정확히 깊게 들어가면 살짝은 틀린 말이지만, 지금 단계에서는 이렇게 이해하고 있으면 됩니다) 때문에 다른 포인터 타입에서 void 타입으로 변환될 때에는 자동으로 형변환이 되지만 void* 타입에서 다른 포인터 타입이 될 때는 형변환을 프로그래머가 명시해야 합니다. 때문에 malloc( ... ) 함수를 사용하고 포인터에 주소값을 넣을 때 malloc( ... ) 함수 앞에 형변환을 해 주는 것입니다

(malloc 함수의 리턴타입이 void* 입니다)

예제코드)

#include "Header.h"

void foo(const char* str) {
    printf("%c", str[1]);
}

int main() {

    char* str = (char*)malloc(sizeof(char) * 12);
    strcpy(str, "Hello World");
    foo("Hello World");

    void* vp = str;

    return 0;
}
profile
코딩 일지

0개의 댓글