C

C언어(8) 기초8

사회적가치누리 2024. 11. 18. 13:41
목차
23. 포인터

 

 

23. 포인터

 

C언어에서 모든 변수는 메모리상 주소를 가지고 있습니다.

메모리는 데이터를 저장하는 공간으로, 그 위치를 식별할 수 있어야 합니다.

 

변수의 메모리 주소를 구하기 위해서는 변수 앞에 &(주소 연산자)를 붙입니다.

 

메모리 주소는 각 컴퓨터마다 다르고, 실행할때마다도 달라집니다.

int 철수 = 1;
int 영희 = 2;
int 민수 = 3;

printf("철수네 주소 : %d, 암호 : %d\n", &철수, 철수);
printf("영희네 주소 : %d, 암호 : %d\n", &영희, 영희);
printf("민수네 주소 : %d, 암호 : %d\n", &민수, 민수);

 

int 철수 = 1;
int 영희 = 2;
int 민수 = 3;

printf("철수네 주소 : %d, 암호 : %d\n", &철수, 철수);
printf("영희네 주소 : %d, 암호 : %d\n", &영희, 영희);
printf("민수네 주소 : %d, 암호 : %d\n", &민수, 민수);

int* 미션맨; // 포인터 변수
미션맨 = &철수;
printf("미션맨이 방문하는 곳 주소 : %d, 암호 : %d\n", 미션맨, *미션맨);

미션맨 = &영희;
printf("미션맨이 방문하는 곳 주소 : %d, 암호 : %d\n", 미션맨, *미션맨);

미션맨 = &민수;
printf("미션맨이 방문하는 곳 주소 : %d, 암호 : %d\n", 미션맨, *미션맨);

미션맨 = &철수;
*미션맨 = *미션맨 * 3;
printf("미션맨이 암호를 바꾼 곳 주소 : %d, 암호 : %d\n", 미션맨, *미션맨);

미션맨 = &영희;
*미션맨 = *미션맨 * 3;
printf("미션맨이 암호를 바꾼 곳 주소 : %d, 암호 : %d\n", 미션맨, *미션맨);

미션맨 = &민수;
*미션맨 = *미션맨 * 3;
printf("미션맨이 암호를 바꾼 곳 주소 : %d, 암호 : %d\n", 미션맨, *미션맨);

 

포인터 변수는 주소값을 알고있는 변수에 찾아가서 값도 직접 바꿀 수 있고,

그 변수가 존재하는 메모리공간의 주소도 알아올 수 있습니다.

 

int 철수 = 1;
int 영희 = 2;
int 민수 = 3;

printf("철수네 주소 : %d, 암호 : %d\n", &철수, 철수);
printf("영희네 주소 : %d, 암호 : %d\n", &영희, 영희);
printf("민수네 주소 : %d, 암호 : %d\n", &민수, 민수);

int* 미션맨; // 포인터 변수
미션맨 = &철수;
printf("미션맨이 방문하는 곳 주소 : %d, 암호 : %d\n", 미션맨, *미션맨);

미션맨 = &영희;
printf("미션맨이 방문하는 곳 주소 : %d, 암호 : %d\n", 미션맨, *미션맨);

미션맨 = &민수;
printf("미션맨이 방문하는 곳 주소 : %d, 암호 : %d\n", 미션맨, *미션맨);

미션맨 = &철수;
*미션맨 = *미션맨 * 3;
printf("미션맨이 암호를 바꾼 곳 주소 : %d, 암호 : %d\n", 미션맨, *미션맨);

미션맨 = &영희;
*미션맨 = *미션맨 * 3;
printf("미션맨이 암호를 바꾼 곳 주소 : %d, 암호 : %d\n", 미션맨, *미션맨);

미션맨 = &민수;
*미션맨 = *미션맨 * 3;
printf("미션맨이 암호를 바꾼 곳 주소 : %d, 암호 : %d\n", 미션맨, *미션맨);

int * 스파이 = 미션맨;

printf("\n ... 스파이가 미션 수행하는 중 ... \n");
스파이 = &철수;
*스파이 = *스파이 - 2; // 철수 = 철수 - 2;
printf("스파이가 방문하는 곳 주소 : %d, 암호 : %d\n", 스파이, *스파이);

스파이 = &영희;
*스파이 = *스파이 - 2; 
printf("스파이가 방문하는 곳 주소 : %d, 암호 : %d\n", 스파이, *스파이);

스파이 = &민수;
*스파이 = *스파이 - 2; 
printf("스파이가 방문하는 곳 주소 : %d, 암호 : %d\n", 스파이, *스파이);

printf("\n ... 철수,영희,민수는 집에 오고서는 바뀐 암호를 보고 깜놀 ...\n\n");
printf("철수네 주소 : %d, 암호 : %d\n", &철수, 철수);
printf("영희네 주소 : %d, 암호 : %d\n", &영희, 영희);
printf("민수네 주소 : %d, 암호 : %d\n", &민수, 민수);

printf("미션맨의 주소 : %d\n", &미션맨);
printf("스파이의 주소 : %d\n", &스파이);

 

포인터 변수라는 것은, 어떤 변수의 주소값을 가지는 포인터 자체가 그 변수의 값을 직접 바꿀 수 있습니다.

 

int arr[3] = { 5, 10, 15 };
int* ptr = arr;

for (int i = 0; i < 3; i++)
{
	printf("배열 arr[%d]의 값 : %d\n", i, arr[i]);
}
for (int i = 0; i < 3; i++)
{
	printf("포인터 ptr[%d]의 값 : %d\n", i, ptr[i]);
}

ptr[0] = 100;
ptr[1] = 200;
ptr[2] = 300;

for (int i = 0; i < 3; i++)
{
	printf("배열 arr[%d]의 값 : %d\n", i, *(arr + i));
}
for (int i = 0; i < 3; i++)
{
	printf("포인터 ptr[%d]의 값 : %d\n", i, *(ptr + i));
}

// *(arr + 1) == arr[i] 똑같은 표현
// arr == arr 배열의 첫번째 값의 주소와 동일 == &arr[0]

printf("arr 의 주소 : %d\n", arr);
printf("arr[0] 의 주소 : %d\n", &arr[0]);

printf("arr 자체의 값이 가지는 주소의 실체 값 : %d\n", *arr);
printf("arr[0] 의 실체 값 : %d\n", *&arr[0]);

// *& 는 아무것도 없는 것과 같다. & 는 주소이며, *는 그 주소의 값이기 때문에,
// *& 는 서로 상쇄된다.
printf("arr[0]의 실제 값 : %d\n", *&*&*&*&*&arr[0]);
printf("arr[0]의 실제 값 : %d\n", arr[0]);

int a = 10;
int b = 20;
printf("a의 주소 : %d\n", &a);
printf("b의 주소 : %d\n", &b);

printf("Swap 함수 전 => a : %d, b : %d\n", a, b);
swap(a, b);
printf("Swap 함수 후 => a : %d, b : %d\n", a, b);

// 값에 의한 복사 (Call by Value) -> 값만 복사한다는 의미

// 주소값을 넘기면? 메모리 공간에 있는 주소값 자체를 넘기면..?
printf("(주소값 전달)Swap 함수 전 => a : %d, b : %d\n", a, b);
swap_addr(&a, &b);
printf("(주소값 전달)Swap 함수 후 => a : %d, b : %d\n", a, b);

void swap(int a, int b)
{
	printf("Swap 함수 내 a의 주소 : %d\n", &a);
	printf("Swap 함수 내 b의 주소 : %d\n", &b);
	int temp = a;
	a = b;
	b = temp;
	printf("Swap 함수 내 => a : %d, b : %d\n", a, b);
}

void swap_addr(int *a, int *b)
{
	int temp = *a;
	*a = *b;
	*b = temp;
	printf("(주소값 전달)Swap 함수 내 => a : %d, b : %d\n", *a, *b);
}

 

// 배열일 때, arr2 -> 주소
int arr2[3] = { 10, 20, 30 };
//changeArray(arr2);
changeArray(&arr2[0]);

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

void changeArray(int* ptr)
{
	ptr[2] = 50;
}

 

 

배열은 연속된 공간에 연속된 주소에 배열공간을 할당하기 때문에

첫번째 배열 항목에 해당하는 주소를 넣어서

세번째 위치에 있는 배열의 값을 바꾸는 것은 올바른 동작이라고 말할 수 있습니다.

 

 

'C' 카테고리의 다른 글

C언어(10)  (0) 2024.11.20
C언어(9)  (0) 2024.11.19
C언어(7) 기초7  (0) 2024.11.16
C언어(6) 기초6  (0) 2024.11.13
C언어(5) 기초5  (0) 2024.11.12