390 likes | 515 Views
C Programming Practice Time. Week 7. 다차원 배열. 다차원 배열 정의 다차원 배열의 메모리 구조 다차원 배열 함수 인자. 다차원 배열 정의. 배열을 한 줄 (1 차원 ) 이 아닌 면 (2 차원 ) 이나 그 이상의 차원을 사용하는 배열. 다차원 배열 메모리 구조. A[0][0] A[0][1] A[0][2] A[1][0] A[1][1] A[1][2] A[2][0] A[2][1] A[2][2] A[3][0] A[3][1] A[3][2]. A[0] A[1] A[2]
E N D
C Programming Practice Time Week 7.
다차원 배열 • 다차원 배열 정의 • 다차원 배열의 메모리 구조 • 다차원 배열 함수 인자
다차원 배열 정의 • 배열을 한 줄(1차원)이 아닌 면(2차원)이나 그 이상의 차원을 사용하는 배열
다차원 배열메모리 구조 A[0][0] A[0][1] A[0][2] A[1][0] A[1][1] A[1][2] A[2][0] A[2][1] A[2][2] A[3][0] A[3][1] A[3][2] A[0] A[1] A[2] A[3] • int A[4][3]; { {
다차원 배열함수 인자 void mult_table(int matrix[NROWS][NCOLS]){ /* compute the multiplication table */ int i, j; for (i=0; i<NROWS; i++) for (j=0; j<NCOLS; j++) matrix[i][j]=i*j; } void sum_table(int matrix[][NCOLS], int arr[]){ /* compute the sum of the numbers in each row */ int i, j; for (i=0; i<NROWS; i++){ arr[i] = 0; for (j=0; j<NCOLS; j++) arr[i] += matrix[i][j]; } }
To do • 포인터 • 함수 인자로서의 포인터 • 포인터와 배열 • 문자열 • 힙과 동적할당 • 오늘 소요 시간 : 약 1시간
포인터 • 주소 연산자 • Deference • 예제 • 곱과 Dereference 구분 • 타입검사 • 초기화하지 않은 포인터
주소 연산자 • 형태 : &VariableName • 뜻 : VariableName의 데이터가 있는 메모리 위치를 반환함 • 메모리 위치는 32bit 운영체제 기준으로 0x00000000 ~ 0xffffffff을 가짐
Deference • 형태 : *PointerVariableName • 뜻 : PointerVariableName에 현재 메모리 주소가 들어있다면, 그 주소에 있는 값을 가져옴 int iVar = 0; int* pVar = &iVar; //(*pVar) == iVar 성립 • 메모리 위치는 32bit 운영체제 기준으로 0x00000000 ~ 0xffffffff을 가짐
예제 • in notepad
곱과 Dereference 구분 • Deference의 연산자는 *으로 곱 연산과 동일함 • 포인터는 곱 연산을 할 수 없으므로, 포인터 앞에 *를 붙인 것은 Deference를 의미함 iWidth * (*piHeight);
타입검사 • 포인터에 주소를 넣으려면, 그 Source와 포인터의 데이터형이 같아야함 int iVar = 0; int* piVar = &iVar; //성립 float* pfVar = &iVar; //성립하지 않음
초기화하지 않은 포인터 • 포인터는 ‘주소값’이고, 포인터를 Deference 하는 일은 ‘해당 주소로 가서 데이터를 사용’하는 일임 • 변수는 초기화하지 않으면 임의의 값을 가지고 있음 • => 초기화하지 않은 포인터는 Deference 할 경우 ‘임의의 주소로 가서 데이터를 사용’하는 일이 발생하여 잡아내기 어려운 오류를 발생시킴
함수 인자로서의 포인터 • Call by Reference • 예제 scanf
Call by Reference • 함수는 인자를 복사해서 넘김 a=3; func(a); void func(int k) {k=5;} //int k=a; (=>) k=5; 순이므로 a는 아직도 3임 • 함수 인자로 ‘주소값’을 넘기고 ‘해당 주소로 가서 데이터를 사용’하면, 함수에서도 인자로 넘어오는 데이터를 수정할 수 있음
예제 scanf • 함수 원형 : int scanf(const char* strFormat, …); • …에는 strFormat에서 %와 함께 써준 형식에 맞는 변수들을 넣어줌 int iRead = 0; scanf(“%d”, &iRead); //그냥 iRead를 넘기면 0이라는 값만 넘어가고 iRead에 어떤 값을 넣을 수 없음 //iRead의 주소값을 알려줘서 함수에서 해당 주소로 접근해서 데이터를 수정함
포인터와 배열 • 포인터 연산 • 배열의 의미 • 예제 배열 출력 • 포인터의 포인터
포인터 연산 • 포인터는 덧셈 및 뺄셈을 할 수 있음 //덧셈 int iVar[5]; int* piVar = iVar;//piVar == iVar === &iVar[0] //(piVar+1) == (iVar+1) == (&iVar[1]) //만약 piVar의 값이 0x00000000이라면, //piVar+1의 값은 0x00000004(4는 int형 byte수)
배열의 의미 • 배열은 sizeof(type)*length 만큼의 메모리 공간을 확보해 둔 후, 그 공간 주소를 알려주는 것임
예제 배열 출력 • in notepad
포인터의 포인터 • 포인터를 연속적으로 이어서 사용하거나 포인터 및 데이터를 겸용하여 데이터 구조를 만들어낼 수 있음 • 메모리 공간을 디자인하고 그에 맞게 사용하는 개념의 기초가 됨
문자열 • 문자열 초기화 • 문자열 함수 • 문자 함수
문자열 초기화 • 문자열이란 char형 배열에 인식 가능한 문자들이 들어있고 그 끝이 NULL(‘\0’)로 구성되어 있는 데이터를 말함 char strData[10] = “Data”; char strData[10] = {‘D’, ‘a’, ‘t’, ‘a’, ‘\0’}; 선언할 때를 제외하고는 문자열을 대입할 수 없음
문자열 함수 • See Theory PPT
문자 함수 • See Theory PPT
힙과 동적할당 • 힙 • 동적할당 • 메모리 함수 • dangling 포인터 • void 포인터
힙 • 정적 할당된 데이터는 스택에 들어가며, 동적 할당된 데이터는 힙에 들어감 • 스택은 정확히 데이터 크기를 알아야 함 • 힙은 임의 크기의 데이터를 다룰 수 있음
동적할당 • 메모리 공간이 필요할 때 메모리 공간을 요청하여 받아 사용하는 개념 • 변수나 배열처럼 고정된 크기가 아닌 바이트 단위의 자유로운 크기를 할당 받을 수 있음
메모리 함수 • malloc(size) : size 크기의 메모리 공간을 할당 • calloc(n, el_size) : 결국 malloc(n * el_size) 형태 • free(pointer) : pointer가 가르키는 동적으로 할당된 메모리 공간을 할당 해제함
dangling 포인터 • 포인터로 접근이 불가능한 형태의 데이터 Variable Variable Memory Memory Memory Memory
void 포인터 • 임의의 데이터 타입을 나타내는 포인터로, 데이터를 읽고 쓰기 위해서는 다른 타입으로 casting 해야함
리뷰 • 포인터 • 함수 인자로서의 포인터 • 포인터와 배열 • 문자열 • 힙과 동적할당
포인터 • 주소 연산자 • Deference • 타입 • 예제 • 곱과 Dereference 구분 • 타입검사 • 초기화하지 않은 포인터
함수 인자로서의 포인터 • Call by Reference • 예제 scanf
포인터와 배열 • 포인터 연산 • 예제 배열 출력 • 포인터의 포인터
문자열 • 문자열 초기화 • 문자열 함수
문자열 • 문자열 초기화 • 문자열 함수 • 문자열 포인터 • 포인터의 배열 • 문자 함수
힙과 동적할당 • 힙 • 힙 관리 • 동적할당 • 메모리 함수 • dangling 포인터 • void 포인터