C 언어 포인터 정리
C 언어의 포인터(Pointer)는 메모리의 주소를 저장하고 있는 변수이다.
메모리의 주소라면 아무런 의미도 없는 메모리 상의 주소는 아닐테고 어떤 한개의 값을 코드상의 다양한 위치에서 접근하려면 해당 값의 메모리 주소가 필요하고 그 주소를 저장할 공간도 필요하게 된다. 여기서 주소를 저장할 공간은 값을 저장하는 일반변수와 다르게 포인터라고 한다
#include <stdio.h> #include <time.h> #include <stdlib.h> void setAge(int *pAge); int * getRandom(); int main() { int cnt = 10; int *p = NULL; // 포인터 변수의 선언, NULL 포인터 printf("p에 저장된 주소=%d \n", p); // 0, 그러므로 포인터 변수에 0이 저장된 경우는 무효한 주소이다 //포인터 변수에 저장된 주소의 유효성을 검사하는 예 if (p) { printf("p에 저장된 주소는 정상적입니다\n"); } else { printf("p에 아직 유효한 주소가 할당되지 않았습니다\n"); } p = &cnt; // 주소연산자(&)를 이용한 변수의 주소 추출 printf("*p = %d \n", *p); // 포인터변수를 이용하여 주소가 가리키는 변수의 값을 참조하는 방법 // 포인터 연산(++, --, +, -) int point[] = { 90,88,82,98 }; printf("size=%d \n", sizeof(point)); // size=16 p = point; while (p <= &point[3]) { printf("*(p++)=%d ", *(p++)); } printf("\n"); int i; int length = sizeof(point) / sizeof(int); // 4 for (i = 0; i < length; i++) { printf("*(point + %d)=%d ", i, *(point + i)); } printf("\n"); // Array of Pointers (반시계방향 해석법 적용) int *pa[4] = { &point[0], &point[1], &point[2], &point[3] };//array of pointers to an integer for (i = 0; i < 4; i++) { printf("pa[%d]=%d ", i, *(pa[i]) ); } printf("\n"); // name is array of pointers to char char *name[3] = { "홍길동", "박찬호", "김연아" }; for (i = 0; i < 3; i++) { printf("name[%d]=%s ", i, name[i]); } printf("\n"); // Pointer to Pointer p = &cnt; // Pointer int **pp = &p; // Pointer to Pointer printf("**pp=%d \n", **pp); int age = 0; setAge(&age); // Call by Reference printf("age=%d \n", age); // 포인터를 리턴하는 함수호출 int * num = getRandom(); for (i = 0; i < 5; i++) { printf("random num[%d]=%d ", i, num[i]); } printf("\n"); return 0; } // 파라미터를 포인터로 선언한 함수 void setAge(int *pAge) { *pAge = 25; } // 배열을 생성하여 리턴할 때 포인터를 사용하는 함수 int * getRandom() { static int num[5]; srand((unsigned)time(NULL)); //임의의 수 추출을 휘한 시드 설정, stdlib.h , time.h int i; for (i = 0; i < 5; i++) { num[i] = rand() % 10 + 1; // 1~10 사이의 수를 추출함, stdlib.h } return num; }
포인터가 반드시 요구되는 작업
본함수에 선언된 변수의 값을 하위함수에서 변경하려면 하위함수의 파라미터는 반드시 포인터이어야 한다.
#include <stdio.h> #pragma warning(disable:4996) void swap1(int, int); void swap2(int*, int*); int main() { // 아래의 2개변수의 값을 서로 맞 바꾸는 swap()함수를 작성해보자 int a = 5; int b = 10; swap1(a, b); printf("swap1()결과 a=%d, b=%d \n", a,b); // a=5, b=10 swap2(&a, &b); printf("swap2()결과 a=%d, b=%d \n", a, b); // a=10, b=5 return 0; } void swap1(int a, int b) { int tmp = a; a = b; b = tmp; } void swap2(int* a, int* b) { int tmp = *a; *a = *b; *b = tmp; }
2중 포인터의 사용예
#include <stdio.h> void change_value1(int*); void change_value2(int**); void change_addr(int** p); int main() { int n = 100; int* p = &n; change_value1(p); // 포인터 전달 printf("n=%d \n", n); // 50 change_value2(&p); // 2중 포인터 전달 printf("n=%d \n", n); // 30 change_addr(&p); printf("*p=%d \n", *p); // 200 return 0; } // 하위 함수에서 본 함수의 변수 n의 내용을 변경하는 방법 void change_value1(int* p) { *p = 50; } // 2중 포인터를 이용하여 하위 함수에서 본 함수의 변수 p의 내용을 변경하는 방법 void change_value2(int** p) { **p = 30; } // 본 함수의 포인터 변수에 저장된 주소를 변경하는 방법 void change_addr(int** p) { static int n = 200; *p = &n; }