2 minute read

★포인터 : C언어는 포인터 변수를 이용하여 컴퓨터의 메모리에 직접 접근하여 값을 대입하거나 변경할 수 있다. 잘 사용하면 유용한 도구가 되지만 실수할 경우 프로그램이 구동되지 않는 상태가 될 수 있다.

int a = 10;

a라는 4byte공간을 할당하고 10을 대입

int *pa = &a;

pa라는 공간을 할당하고 &a(a변수의 주소)를 대입하여 a를 가리키게 한다

★포인터란 주소를 담는 자료형이다.

*(asterisk) : 포인터 변수를 선언하거나 대상을 참조할 때 사용. 변수 선언시에는 해당 변수가 포인터 변수임을 표시한다. 그 외에는 포인터 변수가 가지는 주소값의 위치(대상, 값, 내용물)을 참조한다.

printf("a : %d\n", a); // a = 10
printf("&a : %d\n", &a); // &a = 11795872
printf("pa : %d\n", pa); // pa = 11795872
printf("*pa : %d\n", *pa); // *pa = 10

포인터를 따라가면 값이 나오게 된다.

★포인터 변수의 자료형은 대상의 자료형과 일치해야 한다.

★주소는 무조건 정수

★포인터 변수로 대상이 되는 변수를 출력도 가능하고, 참조도 가능하다.

int num = 10;
int *pnum = #
printf("num : %d\t *pnum : %d\n", num, *pnum);
printf("%d + %d = %d\n", 13, *pnum, 13 + *pnum);

그냥 *pnum은 num이라고 생각하고 써도 된다.

★(*)와 (&)는 서로 역할이 반대다

★배열과 포인터 : 배열의 변수명은 사실 배열의 첫번째 값의 주소를 의미한다.

★만약 int arr[5]라는 배열이 있고, 어떤 함수에 이 배열의 이름을 넣는다면 배열의 주소를 넣는것과도 같다.

★arr[i] => 주소[인덱스] => *(주소 + 인덱스)임 그래서 아래 두줄은 같은 결과를 만듬

printf("test[3] : %d\n", test[3]);
printf("3[test] : %d\n", 3[test]);

★배열의 이름으로 값을 변경할수 없음. 왜냐면 주소값을 바꿀수는 없으니까, 근데 포인터값으로는 저장가능

char name[20] = "불꽃남자 강덕현";
name = "강덕현"; (x)

char *name2 = "불꽃남자 강덕현";
name2 = "강덕현"; (o)

★동적 할당 : 컴파일할때가 아니라 실행하면서 메모리 할당하는 것

  1. 컴파일 시점에서 변수의 개수가 정해지지 않았을 경우나
  2. 어디에서나 접근 가능한 변수를 생성하기 위해서(여러함수에서 접근할수 있게) 사용한다.

malloc()함수는 함수 내부의 메모리가 아니라 Heap영역에 공간을 할당해서 변수를 만들기 때문에 함수가 종료되어도 변수는 제거되지 않는다. 즉 malloc()함수로 만든 변수는 지역변수가 아니다. 따라서 그 어떤 함수에서도 Heap에 접근하면 해당 변수를 사용할 수 있다.(위에 2번이랑 같은말)

int *p = malloc(int);

()안의 수의 byte만큼 Heap이라고 하는 동적할당 전용의 메모리안의 공간을 배열형태로 만들고 그 시작점을 포인터변수로 반환한다

int *p = (void *)malloc(sizeof(int) * 5);

malloc() 함수는 (void *) 형태를 반환한다. 자료형이 지정되어 있지는 않지만 어떤 주소를 반환하는 함수이다. 위 경우에는 나중에 void를 int로 변환하게 됨.

★동적할당으로 생성한 변수는 사용자가 할당해제 하지 않는 한 소멸되지 않는다. 프로그램이 종료되도 소멸되지 않기때문에 꼭 해제 해줘야 한다.

★동적할당을 해제하는 함수free(해당 변수의 주소)

free(p);

★문자열 복사하기

int main() {
	char *str = "practice";
	char *dst = (char *)malloc(sizeof(char) * 20);

	/*char * ps = str;
	char * pd = dst;

	while (*ps != '\0') {
		*pd++ = *ps++;
	}
	*pd = '\0';*/

	for (char * ps = str, *pd = dst; *pd++ = *ps++;) {
		//	△포인터를 굳이 한개 더 만드는 이유는 원본의 위치는 건드리지 않는게 좋기때문
		//	나중에 못찾게 된다...

		printf("str : %s\ndst : %s\n", str, dst);
		//	'\0' (널 문자)의 아스키 코드 값 : 0
		//	0은 C언어에서 논리 거짓을 의미하므로
		//	for문의 조건절이 0이 되면 반복을 중단
	}

	free(dst);
	return 0;
}

Categories:

Updated: