20150307 토론정리

2015. 3. 7. 19:46창고

728x90
728x90

오프라인 토론 - 혼자 연구하는 C/C++ 정리

11장 배열과 포인터

c에는 실제로 2차원 배열은 없다

- 왜냐면 메모리는 선형 구조이기 때문이다.

메모리상에는 선형으로 정의된다.


배열은 사실 포인터다. 첨자 연산은 내부적으로 포인터의 값 증가.

- 서기가 적어놓은 것이긴 하지만. 배열이 포인터란 말은 조금 이상하지싶다.

배열 접근의 내부적 연산이 배열과 같다는 것이지 배열이 포인터라고 표현하는건 조금 아닌거같다.

배열의 배열명은 시작 주소를 가지는 포인터 상수이다.

ar[10]이란 것이 있다면 컴파일러는 내부적으로 이것을 *(ar+10)으로 바꿔서 접근한다.

그렇기 때문에 일반적으로 배열이 포인터보다 아주 살짝 느리다.


포인터 배열 = 요소가 포인터인 배열. 끝.

이중 포인터 배열 **ptr[3]이라면 **ptr을 3개 담아놓는 배열. 끝.

배열 포인터 = 배열을 가리키는 포인터. 2차원 이상에서만 의미가 있다.

이차원 동적 배열 할당. 안된다. 이중 포인터 써라.

&ar. ar과 &ar은 다르다.

문자열 상수 - 정적 데이터 영역에 저장된다.


함수에 넘겨야하는 것이 이차원 이상의 배열인 경우, 이차원 포인터를 넘기면 안된다. (타입을 맞춰줘야한다.)

- 함수에 이차 배열을 넘기는 경우 포인터 배열, 배열 형태로 받는 것이 가장 깔끔하다고 생각한다.

func(char* arr[], char arr[][])


구조체란 뭔가? -> 동형 , 이형의 기본 자료형을 관리할 수 있는 자료형


구조체 패딩. 데이터를 넣는 순서에 따라서 구조체의 크기가 바뀔 수 있다!

typedef struct 

{

    int a; 

    double d; 

    char b;

    short c;

}PT;

typdef를 하게 되면 이렇게 태그명 없이도 사용할 수 있다.


단순히 struct로 할 경우 PT는 그냥 변수.


서기가 조금 빼먹은 내용

비트 필드

- 구조체에서 변수의 비트를 쪼개서 값을 넣는다.

활용? 교수님이 말씀해주신 직업 - 장비 검출 플래그용으로?

그 외에는 활용할 방법은 연구해봐야된다.


온라인 토론 - 포인터, 구조체, 배열

포인터의 정의

- 운영체제로부터 메모리 공간 어딘가에 자료형에 관계없이 4바이트의 메모리 공간을 할당받고

그 주소 위에 a라는 방을 만들고 그 안에는 쓰레기 주소값이 들어있다.


int* imsi; *imsi = 1024; 가 되는가?

- 쓰레기 주소값이 들어 있는 상태에서 그 곳에 정수를 넣으면 알 수 없는 메모리에 값을 넣게 된다.

컴파일 시점에는 아무 문제 없이 돌아가지만 런타임 시에는 초기화되지 않는 변수 에러가 난다.


포인터는 왜 타입이 존재하는가?

- 두 가지 이유. 첫 번쨰는 포인터가 가리키는 곳을 해석하기 위해서. 두 번째는 포인터 연산을 위해서.

간단하게 해석과 연산을 위해.


포인터 배열 vs 배열 포인터

- 포인터 배열은 배열, 배열 포인터는 포인터.

포인터 배열 - 그 원소가 포인터인 배열.

배열 포인터 - 배열의 번지를 담는 포인터 변수.


char* str vs char str[]

- 정적데이터에 들어가는 문자열 상수가 있다고 가정했을 때,

포인터 변수는 그 주소를 직접 가리키게 되고 배열은 그 값을 복사하여 문자열을 넣는다.

그래서 포인터 변수로는 문자열 내부를 수정할 수 없고 배열에선 문자열을 수정할 수 있다.


포인터 변수 초기화 시 왜 NULL을 쓰는가?

- 포인터 변수가 데이터 저장공간을 지정하지 않았다는 명시이다.

NULL은 실제로 0으로 정의된 정수 상수지만 이 상수는 아주 특별하게 포인터 변수와 연산을 허용한다.


BSS에 대한 재논란

- 포인터책에서 BSS영역이 전역변수 한정이라는 글을 발견. 

초기화 하지 않으면 BSS영역에 메모리 공간이 잡히고 0으로 초기화 된다. (일단 결론)

조금 더 논의가 필요한 부분.


*ptr++에 대한 이해, 논란

- 이해 : ptr의 값을 먼저 접근하고 ptr의 포인터를 한 번 증가한다.

- 논란 : 연산자 우선순위로 *가 먼저냐 ++이 먼저냐. 갑론을박

"++가 연산자 우선순위가 높기 때문에 ++가 먼저 실행되지만

실제로 후치연산이기 때문에 *ptr이 먼저 실행되고 포인터가 증가."

이 생각이 맞다고 생각했는데 또 어셈블리 코드를 봐선 또 그게 아닌거같고....

조금 더 논의가 필요한 부분.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
getnumber = *ptr++;
//< ptr의 주소를 eax에 대입
00AA3C42  mov         eax,dword ptr [ptr]  
//< eax의 값을 ecx에 대입
00AA3C45  mov         ecx,dword ptr [eax]  
//< ecx에 있는 값을 getnumber에 대입(즉 getnumber = 1)
00AA3C47  mov         dword ptr [getnumber],ecx  
//< ptr의 주소를 edx에 대입
00AA3C4A  mov         edx,dword ptr [ptr]  
//< edx에 4를 더함
00AA3C4D  add         edx,4  
//< edx의 값을 ptr에 대입
00AA3C50  mov         dword ptr [ptr],edx  
//< 마지막에 포인터의 이동이 된다.(edx는 ptr의 주소에서 4를 증가
//시킨 주소 값을 갖고있으므로
cs






728x90
반응형

'창고' 카테고리의 다른 글

국기3기 정규수업 8일차 메모  (0) 2015.03.09
20150308 토론정리  (0) 2015.03.08
혼자 연구하는 C/C++ 13장 정리(구조체)  (0) 2015.03.07
20150306 토론정리  (2) 2015.03.07
국기3기 정규수업 6&7일차 메모  (0) 2015.03.07
(과제)입출력 함수들 비교  (0) 2015.03.06
국기3기 정규수업 5일차  (0) 2015.03.05