C언어

인프런_ C로 배우는 자료구조 및 여러가지 예제 실습

road23 2023. 2. 15. 16:46

https://www.inflearn.com/course/c%EB%A1%9C-%EB%B0%B0%EC%9A%B0%EB%8A%94-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EB%B0%8F-%EC%97%AC%EB%9F%AC%EA%B0%80%EC%A7%80-%EC%98%88%EC%A0%9C-%EC%8B%A4%EC%8A%B5/dashboard

 

[무료] C로 배우는 자료구조 및 여러가지 예제 실습 - 인프런 | 강의

부경대학교 권오흠 교수님의 '자료구조 및 실습' 강의입니다. C를 사용하여 예제 및 실습을 통해 자료구조를 익히게 됩니다., - 강의 소개 | 인프런

www.inflearn.com

#포인터는 정수를 값으로 가지는 변수이고 그 정수는 메모리 주소이다. 즉, 포인터는 메모리 주소를 값으로 가지는 변수이다. (정수현 변수는 정수를 값으로 가지는 변수이고, 실수형 변수는 실수를 값으로 가지는 변수이다.)

#포인터 사용 방식 : type-name * variable name;
ex) int * ptr;
ptr은 당연 변수의 이름이고 변수이름 앞의 *은 이 변수가 포인터변수라는 것을 의미한다. 그러면 앞에 있는 int라는 type명은 왜 적혀있나면, 이 변수가 포인터 변수이기 때문에 이 변수에 적혀있는 값은 메모리 주소이다. 그리고 이 메모리 주소에 가면 들어있는(저장되어 있는) 데이터 값이 int(type명)라는 것을 나타내기 위해 맨 앞에 타입명을 적는다. -> 정수형 포인터 변수라고 말한다.

#&(앰퍼센트 연산자) : C언어에서 포인터와 관련해서 제공하는 연산자
-> 변수로부터 그 변수의 주소를 추출하는 연산자이다. 즉, 그 변수가 포인터 변수이므로 그 변수가 가지는 메모리 주소 값을 추출한다.
ex 1)
int c = 12;
int *p; //p라는 이름의 정수형 포인터 변수 선언
p = &c; //&c는 변수 c의 주소를 추출하는 연산자로, 변수 c의 메모리 주소를 포인터 변수 p에 저장한다.
ex 2)

ex)2

int x=1, y=2;
int * ip; //ip라는 이름의 정수형 포인터 변수 선언
ip = &x; //정수형 포인터 변수 ip에 변수 x의 메모리 주소를 저장
y = *ip; //정수형 포인터 변수 ip에 저장된 메모리 주소 값을 
*ip = 0;

-> y = *ip;처럼 어떤 포인터 변수 앞에 *가 등장하고 치환문(=) 오른쪽에 있으면, 이것은 그 포인터 변수가 저장하고 있는 메모리 주소에 저장된 값을 의미하게 된다.
: *ip라는 포인터 변수가 값으로 가지고 있는 메모리 주소에 저장된 값을 의미한다.

-> *ip = 0;처럼 어떤 포인터 변수 앞에 *가 등장하고 치환문(=) 왼쪽에 있으면, 이것은 그 포인터 변수가 저장하고 있는 메모리 주소가 참조하고 있는 자리를 의미한다.
: *ip라는 포인터 변수가 현재 저장하고 있는 주소를 의미한다.

 

 

#포인터 arithmetic
배열 a[]가 있다고 가정하면, a가 사실은 배열의 첫 번째 칸을 가리키는 주소이기 때문에, *a는 포인터 변수 a가 가리키고 있는 그 주소에 저장된 값이므로, *a = a[0]이다.

추가적으로 c언어에서는 포인터에다가 덧셈을 하는 연산이 가능하다. (a는 포인터 변수이므로 메모리 주소이고, 메모리 주소는 하나의 32비트의 정수 값이다. 그래서 그 값에 더하기를 한다는 게 이상한 건 아니다.)(그런데 a가 1000이라고 가정하면 c언어에서는 a+1이 1001이 아니라 1004가 된다. 왜냐하면 a가 정수형 포인터 변수이고 하나의 정수가 4바이트로 표현되기 때문에 a+1은 1004번지 즉, 그 다음 정수의 주소가 되도록 하는 기능을 제공한다.) 따라서 *(a + 1) = a[1]이고, *(a + i) = a[i]이다. 이런 연산을 포인터 arithmetic이라고 부른다.
ex)
int data[] = {1, 2, 3};
int *p = &data[0];
printf("%d %x\n", p, p);  //1344982060 502acc2c
printf("%d %x\n", p+1, p+1);  //1344982064 502acc30
printf("%d %x\n", p+2, p+2);  //1344982068 502acc34


#메모리 할당하는 방법
1) 변수 선언
2) 동적 메모리 할당 : malloc 함수 사용
  |
 V
#동적메모리 할당(dynamic memory allocation)
변수를 선언하는 대신 프로그램의 요청으로 메모리를 할당하는 것이다.
malloc 함수를 호출하여 동적메모리할당을 요청하면 요구하는 크기의 메모리를 할당하고 그 시작 주소를 반환한다.  (malloc  = Memory + ALLOCation(할당하다))

#malloc 함수
malloc(a) : a는 바이트의 단위로 정수가 들어간다. 할당받을 메모리의 크기를 byte 단위로 지정한다.
malloc이 반환하는 주소는 타입이 없는 주소(void *)이다. 정수들을 저장하기 위해서 이것을 int*로 변환한다.(반드시 필요한 건 아님)
할당받을 메모리의 크기를 byte 단위로 지정한다.
-> malloc 함수를 사용해서 동적메모리 할당을 요청하면 그 메모리가 어디를 가리키는지 모르기 때문에, malloc이 return 해주는 주소를 반드시 보관을 해야 한다. 멜록이 할당해준 주소를 잊어버리면 애써 할당받은 메모리를 사용할 방법이 없기 때문에, 멜록이 할당해준 메모리 주소를 반드시 보관해야 한다. 보관은 메모리 주소를 변수에 저장해서 보관한다. 그리고 그 변수의 타입은 반드시 포인터 변수여야 한다. 포인터라는 건 메모리 주소를 저장해둘 수 있는 변수의 타입이기 때문이다.
-> 즉,  멜록이 할당해준 메모리 주소를 포인터 변수에 저장해서 보관해야 한다.

 

 

#포인터와 배열은 긴밀하게 연관되어 있어서, 포인터를 배열인 것처럼 배열을 포인터인 것처럼 쓸 수 있다.

#배열 키우기
c언어에서 배열을 선언할 때 항상 배열의 크기를 지정한다.

 

39~