Difference between r1.1 and the current
@@ -15,7 +15,7 @@
* 함수 인자값으로서의 포인터
* 값에 의한 호출,,call by value,, , 참조에 의한 호출,,call by reference,,
* 포인터 배열/ 배열 포인터/이중 포인터/이차원 배열과 포인터
* 동적 메모리 할당
* 스택 영역/힙 영역
* 값에 의한 호출,,call by value,, , 참조에 의한 호출,,call by reference,,
* 포인터 배열/ 배열 포인터/이중 포인터/이차원 배열과 포인터
===============================================================================
{{{===============================================================================}}}
* 더 많은 포인터* 동적 메모리 할당
* 스택 영역/힙 영역
@@ -30,6 +30,82 @@
* ''{{{type}}}'' (*''{{{identifier}}}'')({{{[}}}''{{{[type]}}}'' ''{{{[, ...]}}}''{{{]}}});
* typedef
= 진행 =
= 기타 / 후기 / 방명록 =
-----------------------------------
* typedef
= 진행 =
* &=주소값
* %x = 주소값 출력
* 등호연산자에서 왼쪽 : l-value, 오른쪽 : r-value.
* 포인터의 특징 : 연산을 할 수 있다.
* *x+1 을 하면 1칸 이동인데 1칸의 기준은 자료형이다.(int 는 4칸...)
* 포인터와 일반 상수를 동시에 선언 할 수 있다.
* 포인터도 타입이기 때문에 한줄에 한 포인터를 선언하는 것을 권장함.
* 모든 자료형은 포인터를 가진다.
*void 포인터 같은 경우는 어떤 자료형이든 다 가르킬 수 있다. 근데 뭘 가르키고 있는지 몰라서 그냥 출력하면 error 남.
void *p_v; 에서 *p_v; 하면 error --> *(int*)p_v; 라고 해야됨. 괄호 안에껀 변환 시켜주고, 괄호 밖에 *은 주소 값 다시 찾아줌.
~~회장님 등장 포인터 쓰레기라는 말을 남기고 가심.~~
* scanf를 이용해서 다른데서 받아온 포인터 변경 가능.
* 배열은 일종은 포인터지만 정확히 포인터는 아님.
* int arr[5] = {1,2,3,4,5}가 있을때 *arr;은 1(첫번째 값), *(arr+1); 은 두번째 값 출력, arr[3] == *(arr+3);
* 함수 인자값으로서의 포인터
* call by value
* 값에 의한 호출.
* call by reference
* 참조에 의한 호출(c에는 없다.) 그래서 포인터 사용.
* swap 함수를 만들어 두 값을 바꿀 때 사용.
* 모든 타입에는 포인터 존재 ~~심지어 포인터라도~~
* 포인터에 배열이 존재 할 수 있고 배열이 포인터에 존재 할 수 있다.(포인터가 배열을 가르키거나 배열이 포인터를 가르키거나)
* int *arr_p[5]; - 5개 짜리 포인터가 저장된 배열을 가르킴.
* int (*p_arr)[4]; - 4개 짜리 배열을 가르키는 포인터.(4개만 저장 가능)
* 2차원 배열에서 [][]에서 앞에는 비울 수 있는데 뒤에는 못 비우는 이유 : 주소값을 저장하는 부분
* const도 변수처럼 어떤 저장 공간에 저장 됨.
* &x 는 가능하지만 x를 바꾸는 것은 안됨.
* 포인터, 배열에도 상수 존재 할 수 있다.
* 상수 포인터
상수를 가르키는 포인터
* 포인터 상수
상수인 포인터
*ex)
int a = 5;
int x = 10;
int const *cp_x = &x;
int *const pc_x = &x;
print(cp_x); -- 얘는 10출력
*cp_x = 7; --이러면 에러 발생
print(pc_x); -- 얘는 10출력
*pc_x = 7; -- 얘는 ok(얘가 가르키는 위치는 제약 없으므로)
pc_x = &x; -- 얘는 에러
=======================================================================================================
* os에 추가적으로 호출 요청 : 동적 메모리 할당(사이즈가 얼마나 필요 할 지 모르기 때문에)
* malloc 함수 : size 바이트 만큼의 메모리를 달라고 하면 메모리의 맨 처음 사이즈 만큼 반환함. 반환형은 void
* int *arr = (int*)malloc(sizeof(int)*size);
* 전역변수, static(제일 위에 쌓임) -> program
* 메모리 누수(memory leak)
* 막기 위해선 : free함수(void*를 받아서 할당 받은 영역을 os에게 돌려줘서 할당 되지 않은 상태로 만듦.)
* 허상 포인터(dangling pointer)
* 함부로 쓰면 안됨. free(a)를 쓰고 나서 다시 a을 사용했을 때 발생.
* null 포인터
* 그 무엇도 가르키고 있지 않다는 것을 나타냄. 값은 보통 0이다.
*ex)
int *p = NULL;
*p = 7; --> error 발생!
* realloc(void*, size_t)
* size 다시 할당 해줌.(size 변경 필요시 사용)
* 원래 size보다 작은 것으로 변경시 큰 부분은 지워짐.
* calloc(size-tn, size_t size)
* (몇개 넣을지, 한개당 사이즈)
* malloc 보다 많이 쓴다.
* malloc이랑 비슷하게 할당을 받는데, 차이점은 자료 하나의 사이즈와 개수를 받아서 전부 0으로 초기화 해서 할당 받은 위치에 둠.
* 함수 포인터
* int(*fp)(int, int); 이런식으로 쓴다(자료형(이름)(매개변수인자))
* void(*dp)(int*,int*) : 위에꺼랑 다른거임.(type 다르다.)
~~다음시간 예고 다시 쉬워질거야.....~~
= 실습 == 기타 / 후기 / 방명록 =
-----------------------------------
1. 예정 ¶
- 2시간 강의
- 함수 잠깐 복습
- 함수 선언, 선언 후 정의, main 함수, 재귀 함수
- 함수 선언, 선언 후 정의, main 함수, 재귀 함수
- 대망의 포인터
- C의 자료 저장 방식
- 포인터 : 주소값을 저장하는 변수
type
*identifier
[, ...]
;
- *(unary), &(unary)
- 주소 연산
- void 포인터
- 배열과 포인터의 관계
- [] 연산자
- 함수 인자값으로서의 포인터
- 값에 의한 호출call by value , 참조에 의한 호출call by reference
- 값에 의한 호출call by value , 참조에 의한 호출call by reference
- 포인터 배열/ 배열 포인터/이중 포인터/이차원 배열과 포인터
- C의 자료 저장 방식
===============================================================================
- 더 많은 포인터
- 동적 메모리 할당
- 스택 영역/힙 영역
- 스택 영역/힙 영역
- void* malloc(size_t size);
- free(void* ptr);
- 메모리 누수memory leak , 허상 포인터dangling pointer
- NULL 포인터
- void* realloc(void *ptr, size_t size);
- calloc 함수
- free(void* ptr);
- const * / * const(상수 포인터/ 포인터 상수)
- 함수 포인터
type
(*identifier
)([
[type]
[, ...]
]
);
- typedef
- 동적 메모리 할당
2. 진행 ¶
- &=주소값
- %x = 주소값 출력
- 등호연산자에서 왼쪽 : l-value, 오른쪽 : r-value.
- 포인터의 특징 : 연산을 할 수 있다.
- *x+1 을 하면 1칸 이동인데 1칸의 기준은 자료형이다.(int 는 4칸...)
- 포인터와 일반 상수를 동시에 선언 할 수 있다.
- 포인터도 타입이기 때문에 한줄에 한 포인터를 선언하는 것을 권장함.
- 포인터도 타입이기 때문에 한줄에 한 포인터를 선언하는 것을 권장함.
- 모든 자료형은 포인터를 가진다.
- void 포인터 같은 경우는 어떤 자료형이든 다 가르킬 수 있다. 근데 뭘 가르키고 있는지 몰라서 그냥 출력하면 error 남.
void *p_v; 에서 *p_v; 하면 error --> *(int*)p_v; 라고 해야됨. 괄호 안에껀 변환 시켜주고, 괄호 밖에 *은 주소 값 다시 찾아줌.
- void 포인터 같은 경우는 어떤 자료형이든 다 가르킬 수 있다. 근데 뭘 가르키고 있는지 몰라서 그냥 출력하면 error 남.
- call by value
- 값에 의한 호출.
- 값에 의한 호출.
- call by reference
- 참조에 의한 호출(c에는 없다.) 그래서 포인터 사용.
- swap 함수를 만들어 두 값을 바꿀 때 사용.
- 참조에 의한 호출(c에는 없다.) 그래서 포인터 사용.
- &x 는 가능하지만 x를 바꾸는 것은 안됨.
- 포인터, 배열에도 상수 존재 할 수 있다.
- 상수 포인터
상수를 가르키는 포인터
- 포인터 상수
상수인 포인터
- ex)
int a = 5;
int x = 10;
int const *cp_x = &x;
int *const pc_x = &x;
print(cp_x); -- 얘는 10출력
- cp_x = 7; --이러면 에러 발생
print(pc_x); -- 얘는 10출력
- pc_x = 7; -- 얘는 ok(얘가 가르키는 위치는 제약 없으므로)
pc_x = &x; -- 얘는 에러
- cp_x = 7; --이러면 에러 발생
- ex)
- 상수 포인터
=======================================================================================================
- malloc 함수 : size 바이트 만큼의 메모리를 달라고 하면 메모리의 맨 처음 사이즈 만큼 반환함. 반환형은 void
- int *arr = (int*)malloc(sizeof(int)*size);
- int *arr = (int*)malloc(sizeof(int)*size);
- 막기 위해선 : free함수(void*를 받아서 할당 받은 영역을 os에게 돌려줘서 할당 되지 않은 상태로 만듦.)
- 함부로 쓰면 안됨. free(a)를 쓰고 나서 다시 a을 사용했을 때 발생.
- 그 무엇도 가르키고 있지 않다는 것을 나타냄. 값은 보통 0이다.
- ex)
int *p = NULL;
- ex)
- p = 7; --> error 발생!
- realloc(void*, size_t)
- size 다시 할당 해줌.(size 변경 필요시 사용)
- 원래 size보다 작은 것으로 변경시 큰 부분은 지워짐.
- size 다시 할당 해줌.(size 변경 필요시 사용)
- calloc(size-tn, size_t size)
- (몇개 넣을지, 한개당 사이즈)
- malloc 보다 많이 쓴다.
- malloc이랑 비슷하게 할당을 받는데, 차이점은 자료 하나의 사이즈와 개수를 받아서 전부 0으로 초기화 해서 할당 받은 위치에 둠.
- (몇개 넣을지, 한개당 사이즈)
- 함수 포인터
- int(*fp)(int, int); 이런식으로 쓴다(자료형(이름)(매개변수인자))
- void(*dp)(int*,int*) : 위에꺼랑 다른거임.(type 다르다.)
- int(*fp)(int, int); 이런식으로 쓴다(자료형(이름)(매개변수인자))