테크매니아
Head First C 책 후기 본문
반응형
새로이 알게 된 점들
1. 쉘 명령어 중 gcc -o test test.c && ./test 처럼 && 연산자 사용이 가능하다.
2. 배열 인덱스가 0부터 시작하는 이유는 거리를 표현하기 위함이다.? 거리로 표현하면 메모리 주소 계산이 편해진다.
3. Bus error는 컴파일러가 허용하지 않는 방법으로 메모리를 접근하였을 경우 발생한다.
4. Pointer Decay(포인터로 퇴화)
배열을 매개변수로 받을 때, 배열 변수는 주소이므로, 받는 함수 입장에선 int func(char msg[]) 로 받게 되어도, 포인터로 받게 된다. 따라서 msg를 sizeof 연산자로 찍어보면, 포인터의 크기인 8이나 4 바이트가 찍히게 된다. 따라서 전달 받은 함수는 배열의 크기를 모르게 되는데 이를 Pointer Decay(포인터로 퇴화) 한다고 한다.
5. 배열 변수가 주소로 사용되니,
int doses[] = {1, 2, 3, 1000};?
printf(%i\n, 3[doses]);
출력
1000
위 처럼 컴파일 된다. 이는 doses[3] = *(doses +3) = *(3+doses) = 3[doses] 가 되기 때문이다.
- %i 지정자는 입력 받을 때 10 진수, 8진수 16진수로 입력을 받는다.
- 배열 생성시 배열 자체를 위한 메모리 공간은 할당이 되지만, 배열 변수를 위한 공간은 할당되지 않는다.
- 컴파일러는 배열의 시작주소를 코드에 넣어 준다. 따라서 실행 파일엔 배열 변수가 존재하지 않게 된다.
- 배열 변수가 공간 할당을 받지 않았기 때문에 변수에 값을 대입할 수 없다.
- 배열은 그래서 일반적으로 포인터 상수라고 부르는데, 즉 들어있는 주소를 바꾸거나 할 수 없는 상수라는 말이다.
- 그도 그럴 것이 메모리를 연속적으로 할당받는 배열이 시작주소가 바뀌면 안되기 때문이다.
6. 프로그램은 스택 - 힙 - 전역변수 - 상수 - 코드 세그먼트들로 이루어져 있는데, 이중 상수세그먼트에 문자열이 올라간다. 상수 세그먼트는 read only 속성이고 char *p = hello world
에서 p
는 hello world
의 주소를 가리키게 된다.
만약 p가 배열이라면 스택에 배열 공간을 만들고,?상수 세그먼트에 올라간 hello world를 복사해온다. 따라서 p는 포인터일 경우 원본을 가리키게 되고, 배열일 경우 사본을 받아와 스택에 저장되기 때문에?문자열 변경이 가능해진다.
아래 표처럼 상수와 코드 영역은 read only memory(rom) 속성을 가진다.
- 스택: 지역변수들이 저장. 함수에 들어갈 때 쌓였다가 나올 때 제거된다. 거꾸로 자란다.
char *p1 char p2[]`
- 힙: 할당 없음
- 상수:
hello world
- 코드: 컴파일된 코드가 로드
7. scanf 는 공백문자(띄어쓰기, 엔터)를 입력 받지 않는다.
8. 2> 는 표준 에러를 리디렉션한다.
9. unistd.h 의 getopt() 함수는 명령행 인자를 쉽게 처리할 수 있게 해준다.10. static 키워드를 사용하면, 변수는 전역 메모리에 보관된다.? 함수에 쓸 경우 해당 함수가 위치한 소스파일 내에서만 함수를 호출 할 수 있도록 숨길 수 있다.
11. -Werror : 엄격하게 컴파일 한다. -Wall : 모든 경고를 출력해준다.
-Ofast
: 최고 수준은 최적화하며 컴파일 속도가 느리다. 컴파일 된 코드는 C 표준 호환성이 떨어질 수 있다.
12. 초기화 필드 지정(c99 표준으로 c++ 지원 안함)
typedef struct {
int number;
int id;
}info
info i = {.number = 1, .id = 007};
13. 바인딩 했던 포트는 운영체제가 30초 동안은 다시 바인딩 하지 못하게 한다.
14. 소켓 통신에서 recv 함수는 문자열이 \0로 끝나지 않는다. \r\n으로? 언제나 끝난다.
반응형