C언어:6일차 (구조체와 포인터)

백준으로는 c언어의 개념을 채우지 못할 것 같아서
어느 정도 능숙하게 c를 다루게 된 지금...(내생각임... 능숙하다는건 내생각임..)
구조체랑 포인터 개념을 복습하기로 했다!

이걸 복습이라고 해야할지... 거의 안배운거나 마찬가지 !! 하하

인프런에 올라온 강좌를 토대로 개념학습을 할 것이당.

포인터 기본

int i = 1;
printf("%d %d\n", i, &i); //&i는 주소를 뜻한다.

int *pointer; //포인터 변수
pointer=&i; //포인터 변수가 i의 주소를 받는다.
printf("%d %d", pointer, *pointer); //pointer 자체는 주소를 나타내고, 그 앞에 *을 붙이면 주소가 가르키는 i값을 나타내게 된다.

"*"을 붙이는게 자꾸 헷갈리니 주의하자.

저 코드를 출력하면

1 주소
주소 1

으로 출력된다.

	//i에다가 3을 곱해보자!
	*pointer = *pointer * 3; //별포인터 자체가 i이다! 명심
    printf("%d", i);
    

포인터 변수에 "*"을 씌우면 그것은 주소가 가르키는 값 자체이다!

두개의 코드를 합쳐서 나온 결과
마지막 줄에서 i의 세배인 3이 나오는 것을 확인할 수 있었따.

포인터 변수는 변수가 존재하는 메모리 공간의 주소를 알아낼 수도 있고, 주소에 직접 가서 값도 바꿀 수 있다.

	int* spy = pointer;  //스파이 포인터 변수는 포인터의 값을 가져온다.
	//둘다 같은 하나의 메모리 주소를 가르키고 있다. 
	spy = &i;
	*spy = *spy - 5; // i = i-2; 와 동일하다.
	printf("주소 : %d /스파이를 통해 바꾼 값 :%d\n", spy, *spy);
	printf("i 자체의 값 : %d\n", i);

출력 결과

마지막 줄을 보면,
스파이를 통해 바꾼 값은 i 자체의 값의 변화라는 것을 알 수 있다.!

pointer & spy(포인터 변수)도 변수 중 하나이므로 그들도 주소를 갖고 있따.

printf("%d %d", &pointer, &spy);를 통해서 확인할 수 있다.


배열과 포인터

1. 배열 포인터

배열은 포인터이다.
char arr[3]={"cat","dog","monkey"};라고 할 때
arr[0]은 cat의 문자열 주소를 가르키고 있다. (따라서 포인터)
arr[1]은 dog의 문자열 주소를 가르키고 있다. (따라서 포인터)
arr[2]은 monkey의 문자열 주소를 가르키고 있다. (따라서 포인터)

int main() {
	int arr[3] = { 5, 10, 15 };
	int* pointer = arr; //배열 자체가 주소값 위에서 &i한 것과 다름없다.
	printf("%d\n", pointer);
	for (int i = 0; i < 3; i++) {
		printf("%d\n", &arr[i]);
	}
	return 0;
}

출력 결과

첫째줄 pointer의 주소와 arr[0]의 주소가 일치하는 것을 볼 수 있다.
또한 arr의 주소와 arr[0]의 주소가 일치한다는 것도 알 수 있다.

int arr[3] = { 5, 10, 15 };
	int* pointer = arr;
	
	for (int i = 0; i < 3; i++) {
		printf("%d\n", arr[i]);
	}
	pointer[0] = 100;
	pointer[1] = 200;
	pointer[2] = 300;

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

출력 결과
5
10
15
100
200
300

pointer배열과 arr배열은 동일하다고 볼 수 있다.

printf("%d\n", arr[i]);
printf("%d\n", *(arr+i));

두 줄은 완전히 동일하다.
아래의 문장에서는 arr에서 i번째 주소를 가져와 별을 붙였기 때문에 i번째에 들어있는 값이 프린트된다.

&는 주소이며, *은 주소의 값이기 때문에 둘은 만나면 상쇄된다.

printf("%d", *&*&*&*&*&*&*&*&*&*&*&*&*&arr[0]);
printf("%d", arr[0]);

위의 이유로 두 줄은 동일하다.

(참고로 나는 지금 디저트 39인데 개추워서 아무것도 못하겠다)


swap함수 만들기

int a, int b를 넘기는 swap함수와 int a, int b를 넘기는 swap_addres함수를 만들어볼것이다.

#include <stdio.h>

void swap(int a, int b) {
	int temp;
	temp = a;
	a = b;
	b = temp;
	printf("swap(in) a: %d b: %d\n", a, b);
}

int main() {
	int a = 10, b = 20;
	printf("before swap a : %d b : %d\n", a, b);
	swap(a, b);
	printf("after swap a : %d b : %d\n", a, b);
	return 0;
}

출력 결과
before swap a : 10 b : 20
swap(in) a: 20 b: 10
after swap a : 10 b : 20

swap함수 내에서는 a: 20 b: 10으로 출력되었으나 밖으로 나오니 원상복귀되엇다.
그 이유는 swap은 단지 값만 복사해서 넣었기 때문이다.
매개 변수를 x,y로 바꿔도 이 함수는 실행된다.

따라서 함수 밖에서는 아무일도 일어나지 않는 것이다.

이러한 이슈를 해결하기 위해서 a, b의 주소를 swap_addres함수에 넘길 것이다.

#include <stdio.h>

void swap_addres(int* a, int* b) {
	int temp;
	temp = *a;
	*a = *b;
	*b = temp;
	printf("swap_addres(in) a: %d b: %d\n", *a, *b);
}

int main() {
	int a = 10, b = 20;
	printf("before swap a : %d b : %d\n", a, b);
	swap_addres(&a, &b);
	printf("after swap a : %d b : %d\n", a, b);
	return 0;
}

출력 결과
before swap a : 10 b : 20
swap_addres(in) a: 20 b: 10
after swap a : 20 b : 10

아까의 swap함수와는 달리 함수 밖에서도 값이 변화된 모습을 확인할 수 있었다.
포인터를 통해 주소가 가르키는 값을 변경했기 때문이다.

좋은 웹페이지 즐겨찾기