Download presentation
Presentation is loading. Please wait.
1
Chapter 9 Arrays and Pointers
프로그래밍 기초와 실습 Chapter 9 Arrays and Pointers
2
Contents One-Dimensional Arrays Initialization Subscripting
An Example: Counting Each Letter Separately Two-Dimensional Arrays Multidimensional Arrays Review of Pointers The Relationship between Arrays and Pointers Pointer Arithmetic and Element Size Combining the * and ++ Operators
3
Contents Passing Arrays to Functions Passing Pointers to Functions
Bubble Sort Dynamic Memory Allocation calloc() and malloc()
4
One-Dimensional Arrays
Array – 같은 이름의 변수를 사용하여 여러 개의 type이 같은 값을 표현할 수 있게 하는 data type. Syntax 배열의 크기는 반드시 양수로 써야 한다. 배열 원소의 첨자는 항상 0 부터 시작한다. 위의 예제의 경우는 grade[0], grade[1],~ , grade[49]가 생성. [Ex] int grade0, grade1, grade2,……, grade49; 여러 개의 변수이름을 표시할 필요가 있을 때 element-type array_name[size]; [Ex] int grade[50]; size of Array data type variable Name
5
One-Dimensional Arrays
배열선언 예제 [Ex] int digit[10] = {0}; #define MAX 100; … double student[MAX]; float exp[13]; int a[10]; a[2] = 8; exp[10] = exp[11]; exp[2+3] = 100; exp[a[2]] = 100; 10개의 int형 배열을 0으로 초기화한다. 100을 MAX로 선언 double student[100]; 과 같다. a[2]에 8을 저장 exp[11]의 값을 exp[10]에 저장 exp[5]에 100을 저장 exp[8]에 100을 저장
6
One-Dimensional Arrays
[Ex] /* Fill and Print an Array */ #include <stdio.h> #define N 5 int main(void) { int a[N]; /*allocate space for a[0] to a[4] */ int i, sum = 0; for ( i = 0; i < N; ++ i) /* fill the array */ a[i] = 7 + i * i; for ( i = 0; i < N; ++ i) /* print the array */ printf(“a[%d] = %d “,i, a[i] ); for ( i = 0; i < N; ++ i) /* sum the elements */ sum += a[i]; printf(“\nsum = %d\n”, sum); /* print the sum */ return 0; } a[0] = 7 a[1] = 8 a[2] = 11 a[3] = 16 a[4] =23 sum = 65
7
One-Dimensional Arrays
int a[5]; 기억장소에 할당되어 있는 address number 1000 1004 1008 1012 1016 7 8 11 16 23 1 2 3 4 이 숫자는 각 array element에 저장되어 있는 값들 이 숫자들은 array의 index
8
Initialization 초기화 초기값이 배열 원소의 값보다 적을 때 지정된 array에 초기값을 할당하는 것. [Ex]
float x[7] = { -1.1, 0.2, 33.0, 4.4, 5.05, 0.0, 7.7 }; x[0] = -1.1, x[1] = 0.2,…, x[6] = 7.7 로 초기화된다. [Ex] int a[100] = { 0 }; a[0] = 0, a[1] = 0, … a[99] = 0처럼 남은 원소들은 모두 0으로 초기화 된다.
9
Initialization 배열의 크기를 지정하지 않을 때 문자 배열에서의 사용 예 . [Ex]
int a[] = { 2, 3, 5, 7}; int a[4] = { 2, 3, 5, 7}; 초기값의 수가 배열의 크기가 된다. 위의 두 예제는 같다. [Ex] char s[] = “abc”; char s[] = { ‘a’, ‘b’, ‘c’, ‘\0’}; . 위의 두 array는 같은 값을 갖는다.
10
Subscripting 배열의 첨자 배열 사용시 유의할 점 . int i, a[size]; [Ex]
배열은 a[expr]로 나타낼 수 있다. 여기서의 expr을 a의 첨자(Subscript) 또는 색인(index)라고 부른다. [Ex] int a[5] = { 1, 2, 3, 4, 5 }; printf(“%d”, a[5] ); a[0]~a[4] 까지 할당되나 a[5]를 사용하는 것은 범하기 쉬운 오류이다. 배열의 범위를 유의! .
11
cnt_abc Program [Ex] /* Count each uppercase letter separately */
#include <stdio.h> #include <ctype.h> int main(void) { int c, i, letter[26]; for ( i = 0; i < 26; ++i) letter[i] = 0; while(( c = getchar() ) != EOF){ c=toupper(c); if(isalph(c))++letter[c –‘A’]; } for ( i = 0; i < 26; ++i) { if ( i % 6 == 0 ) printf(“\n”); printf(“%4c:%3d”, ‘A’ + i, letter[i]); } /* end of for */ printf(“\n\n”); return 0; C Programming라고 입력하면 결과는 다음과 같이 출력된다. A: 1 B: 0 C: 1 D: 0 E: 0 F: 0 G: 2 H: 0 I: 1 J: 0 K: 0 L: 0 M: 2 N: 1 O: 1 P: 1 Q: 0 R: 2 S: 0 T: 0 U: 0 V: 0 W: 0 X: 0 Y: 0 Z : 0
12
Dissection of the cnt_abc Program
int main(void) { while (( c = getchar( ) ) != EOF) { c=toupper(c); if( isalph(c) ) ++letter[c – ‘A’]; } for ( i = 0; i < 26; ++i) { if ( i % 6 == 0 ) printf(“\n”); printf(“%4c:%3d”, ‘A’ + i, letter[i]); } /* end of for */ printf(“\n\n”); return 0; 문자가 끝날때까지 getchar()로 입력받는다. 소문자는 대문자로 바꾼다. 배열에 저장된 문자들의 개수를 하나씩 출력한다.
13
Example of Array Reverse a series of numbers [Ex]
#include <stdio.h> #define N 10 main() { int a[N], i; printf(“Enter %d numbers: “, N); for( i = 0; i < N; i++ ) scanf(“%d”, &a[i] ); printf(“in reverse order: “); for ( i = N – 1; i >= 0; i-- ) printf(“ %d”, a[i] ); printf(“\n”); return 0; } 배열에 저장된 수를 하나씩 출력하는 구문 10개의 배열에 각각의 수를 입력하는 구문 Enter 10 numbers : In reverse order :
14
Example of Array Check a Number for Repeated Digits
#include <stdio.h> #define TRUE 10 #define FALSE 0 typedef int Bool; main() { Bool digit_seen[10] = {0}; int digit; long int n; printf(“Enter a number: “); scanf(“%ld”, &n ); /* continue… */ int type을 Bool이란 이름으로 typedef를 선언 다른 사람들이 알아보기 편하게 digit_seen[ ]은 boolean형이란 것을 알려주기 위해 Bool이란 변수명을 선언하여 사용.
15
Example of Array Check a Number for Repeated Digits
while ( n > 0 ) { digit = n % 10; if (digit_seen[digit]) break; digit_seen[digit] = TRUE; n /= 10; } if ( n > 0 ) printf(“Repeated digit\n\n”); else printf(“No repeated digit\n\n”); return 0; digit_seen의 index는 0~9까지 이다. 처음 이 array의 기본값은 모두 0(false)이다. n의 숫자를 입력 받으면 마지막 자리 숫자를 digit_seen의 index로 해서, 해당 array의 값을 1(TRUE)로 지정한다. True가 되었다는 것은 해당 index숫자가 이미 나타났다는 표시 임으로 반복문을 빠져 나온다. 위의 while문에서 digit_seen[digit] 이 true(1)의 값을 갖게 되면, break문으로 인해 n/=10을 계산하지 않고 loop를 빠져 나오게 된다. 결국 n 의 값은 0보다 커서 반복된 숫자가 있다는 메시지를 출력한다. Enter a number : ꎠ Repeated digit
16
Two-Dimensional Arrays
2차원 배열 Syntax int b[2][7]의 기억공간 data_type variable_name[ number][ number ]; Array dimensions Declarations of arrays Remarks int a[100]; a one-demensional array int b[2][7]; a two-demensional array int c[5][3][2]; a three-demensional array col row 1 2 3 4 5 6 [0][0] [0][1] [0][2] [0][3] [0][4] [0][5] [0][6] [1][0] [1][1] [1][2] [1][3] [1][4] [1][5] [1][6]
17
Two-Dimensional Arrays
이차원배열의 elements 이차원 배열의 기억장소를 앞 테이블 같이 그려보았지만 실제로 컴퓨터 메모리에 저장되는 기억장소는 다음과 같다. 일련의 메모리 공간에 차례대로 배열이 지정되는 것이다. row row row2 [Ex] int a[3][5]; col col col col col5 row 1 a[0][0] a[0][1] a[0][2] a[0][3] a[0][4] row 2 a[1][0] a[1][1] a[1][2] a[1][3] a[1][4] row 3 a[2][0] a[2][1] a[2][2] a[2][3] a[2][4] a[0][0] a[0][1] … a[0][4] a[1][0] . a[1][4] a[2][0] a[2][4]
18
Two-Dimensional Arrays
Two-Demensional Arrays [Ex] #include <stdio.h> #define M 3 /* number of rows */ #define N 4 /* number of columns */ int main(void) { int a[M][N], i, j, sum = 0; for ( i = 0; i < M; ++i ) for ( j = 0; j < N; ++j ) a[i][j] = i + j; for ( i = 0; i < M; ++i ) { printf(“a[%d][%d] = %d “, i, j, a[i][j] ); printf(“\n”); } for ( i = 0; i < M; ++ i ) sum += a[i][j]; printf(“\nsum = %d\n\n”, sum); return 0; a[0][0] = 0 a[0][1] = 1 a[0][2] = 2 a[0][3] = 3 a[1][0] = 1 a[1][1] = 2 a[1][2] = 3 a[1][3] = 4 a[2][0] = 2 a[2][1] = 3 a[2][2] = 4 a[2][3] = 5 sum = 30
19
Two-Dimensional Arrays
2차원 배열 element를 access하는 여러 가지 방법 a[ i ]는 a의 i번째 행 a[ i ][ j ]는 배열의 i번째 행과 j번째 열의 원소 배열 이름 a는 &a[0]와 같다. Expressions equivalent to a[ i ][ j ] *( a[ i ] + j ) ( *( a + i ) ) [ j ] *( ( *( a + i ) ) + j ) *( &a[0][0] + 5 * i + j )
20
Two-Dimensional Arrays
[Ex] int a[2][3], *p ; p = &a[0][0]; p = a[0] /* a[0] : a[0][0]를 가리키는 address */ p + 1 &a[0][1] a[0] + 1 p + 2 &a[0][2] a[0] + 2 p + 3 &a[1][0] a[0] + 3 a[1] + 0 p + 4 &a[1][1] a[0] + 4 a[1] + 1 p + 5 &a[1][2] a[0] + 5 a[1] + 2 a[0][0] a[0][1] a[0][2] a[1][0] a[1][1] a[1][2] a[0] a[1] p
21
Two-Dimensional Arrays
int a[2][3], *p = &a[0][0] , i , j ; [Ex] for( i = 0 ; i < 2 ; i++) { for( j=0 ; j < 3 ; j++) a[i][j] = 0 ; } for( p = a[i] ; p < a[i]+3 ; p++) *p = 0 ; [Ex] for( p = &a[0][0] ; p <= &a[1][2] ; p++) *p = 0 ; 1 2 00 01 02 10 11 12 1 마지막 element의 address < &a[2][3] 으로 한 경우 문제
22
Multidimensional Arrays
3차원 배열 Syntax 배열a의 원소를 더하는 함수 i j data_type variable_name[ number][ number ][ number ]; [Ex] int sum( int a[ ][ 9 ][ 2 ] ) { int i, j, k, aum = 0; for ( i = 0; i < 7; ++i ) for ( j = 0; j < 9; ++j ) for ( k = 0; k < 2; ++k ) sum += a[ i ][ j ][ k ]; return sum; } 00 01 02 03 04 05 06 07 08 10 11 12 13 14 15 16 17 18 20 21 22 23 24 25 26 27 28 30 31 32 33 34 35 36 37 38 40 41 42 43 44 45 46 47 48 50 51 52 53 54 55 56 57 58 60 61 62 63 64 65 66 67 68 00 01 02 03 04 05 06 07 08 10 11 12 13 14 15 16 17 18 20 21 22 23 24 25 26 27 28 30 31 32 33 34 35 36 37 38 40 41 42 43 44 45 46 47 48 50 51 52 53 54 55 56 57 58 60 61 62 63 64 65 66 67 68 1 k
23
Multidimensional Arrays
다차원 배열의 초기화 i [Ex] int a[ 2 ][ 2 ][ 3 ] = { { {1,1,0}, {2,0,0} }, { {3,0,0}, {4,4,0} } }; k k k j k j [Ex] int a[ ][ 2 ][ 3 ] = { { {1, 1}, {2} }, { {3}, {4, 4} } }; [Ex] int a[ 2 ][ 2 ][ 3 ] = { 0 }; 모든 원소들은 0으로 초기화 된다.
24
Review of Pointers pointer operator p = &rate;
& : ‘address of’ operator gets the address of the variable * : ‘indirect’ operator gets the value at the address p = &rate; Pointer변수 ‘p’에 일반 변수 ‘rate’의 주소를 입력 *p = 10; ‘p’가 point하는 곳, 즉 ‘rate’에 10을 assign
25
Review of Pointers [Ex] int x, *p; x = 10; p = &x; [Ex]
Pointer변수 ‘p’에 ‘x’ 주소를 assign, 이 때 x의 값은 10 동일 int x, *p = &x; x = 10; ‘p’가point하는 곳의 값을 print 즉 x의 값이 되며 x 주소가 point하는 곳의 값이 됨 여기 동일이 무엇이 동일이라는 뜻이니??? [Ex] printf(“%d”, *p); 동일 printf(“%d”, x); printf(“%d”, *&x);
26
Review of Pointers x y &x &y *p1 *p2 &p &p [Ex] int x, y, *p1, *p2;
p1 = &x; p2 = &y; printf(“%d:%d\n”, *p1, x); *p1= 17; *p2 = *p1; printf(“%d:%d\n”, x, y); printf(“%u:%u\n”, &x, p1); x y -10 100 &x &y *p1 *p2 &x &y &p &p -10 : -10 17 : 17 : (address값)
27
The Relationship between Arrays and Pointers
어떤 값이 저장된 memory 주소를 값으로 하는 data item memory address를 값으로 하는 변수 [Ex] #define N int a[N], *p; 왼쪽 예제에서 memory byte number가 각각 300,304,308,…,696 이 배정되었다고 하면, a[0], a[1],…,a[99] 의 시작 주소는 300 이 된다. 같은 의미 p = a; p =&a[0]; p에 300번지 주소가 배정. pointer 산술 계산이 가능하다. 같은 의미 p = a + 1; p =&a[1]; p에 304번지 주소를 배정. 두 문장은 같다.
28
The Relationship between Arrays and Pointers
배열의 합을 구하는 code 1 배열의 합을 구하는 code 2 [Ex] sum = 0; for ( p = a ; p < &a[N] ; ++p ) sum += *p; p = &a[0] p <= &a[N-1] p는 &a[0], p + i응 &a[i]와 동일하다 같은 의미 [Ex] sum = 0; for ( i = 0 ; i < N ; ++i ) sum += *( a + i ); *(a + i) 는 a[i]와 동일하고, *(p + i)는 p[i]와 동일하다.
29
The Relationship between Arrays and Pointers
배열의 합을 구하는 code 3 틀린 사용 예 [Ex] p = a; sum = 0; for( i = 0; i < N; ++i ) sum += p[ i ]; [Ex] a가 상수 포인터이고 변수가 아닐 때, a = p ( wrong ) ++a ( wrong ) a += 2 ( wrong ) 포인터 변수 = 포인터 변수 X 더블 포인터 변수 = 포인터 변수 O 상수이므로 변화 X a의 주소를 바꿀 수가 없다.
30
The Relationship between Arrays and Pointers
배열 a의 합을 구하는 Program sum 11 [Ex] #define N 10 main() { int a[N]={11,34,82,7,64,98,47, 18,79,20}; int sum, *p; sum = 0; for ( p = &a[0]; p < &a[N]; p++ ) sum += *p; } p a 11 34 82 7 64 98 47 18 79 20 1 2 3 4 5 6 8 9 p sum 45 a 11 34 82 7 64 98 47 18 79 20 1 2 3 4 5 6 8 9 p sum 127 a 11 34 82 7 64 98 47 18 79 20 1 2 3 4 5 6 8 9 for( p = a ; p < a + N ; p++ ) 로 변환이 가능하다.
31
Pointer Arithmetic and Element Size
포인터 연산 변수 p가 포인터라면 p + 1은 그 type의 다음 변수를 저장하거나 access할 수 있도록 주소를 생성한다. 포인터의 정수 덧셈 연산이 가능하다. 포인터의 정수 뺄셈 연산이 가능하다. 두 개의 포인터의 뺄셈 연산이 가능하다. [Ex] int a[10], *p; p = &a[0]; p a 1 2 3 4 5 6 7 8 9 p [Ex] *p = 5; a 5 1 2 3 4 6 7 8 9
32
Pointer Arithmetic and Element Size
Adding an Integer to a Pointer p a 1 2 3 4 5 6 7 8 9 [Ex] p = &a[2]; p q +3 a 1 2 3 4 5 6 7 8 9 q = p + 3; q p +6 a 1 2 3 4 5 6 7 8 9 p += 6; p = p + 6;
33
Pointer Arithmetic and Element Size
Subtracting an Integer from a Pointer p [Ex] p = &a[8]; a 1 2 3 4 5 6 7 8 9 q p -3 a 1 2 3 4 5 6 7 8 9 q = p - 3; p q -6 a 1 2 3 4 5 6 7 8 9 p -= 6; p = p - 6;
34
Pointer Arithmetic and Element Size
Subtracting Pointers [Ex] p = &a[5]; q = &a[1]; i = p –q; /* i is 4 */ i = q – p; /* i is -4 */ i = 5-1 i = 1-5 q p a 1 2 3 4 5 6 7 8 9
35
Pointer Arithmetic and Element Size
Comparing Pointers 관계연산자 (relational operators) <, <=, >,>= 사용 가능. 동등연산자(equality operators) ==, != 사용 가능. [Ex] p = &a[5]; q = &a[1]; p <= q; /* result is 0 */ p >= q; /* result is 1 */ 5 <= 1 거짓 5 >= 1 참
36
Pointer Arithmetic and Element Size
포인터 연산의 예제 p q [Ex] int a[ ] = { 5,15,25,43,12,1,7,89,32,11} int *p = &a[1], *q = &a[5] ; 1. *(p + 3) ? 2. *(q - 2) ? 3. q - p ? 4. if ( p > q ) ? 5. if ( *p > *q )? 12 43 5-1 4 1. 12 2. 43 3. 4 4. false 5. true 1 > 5 false 15 > 1 true
37
Pointer Arithmetic and Element Size
포인터 연산의 예제 p q [Ex] #include <stdio.h> int main(void) { double a[2], *p, *q; p = &a[0]; /* points at base of array */ q = p + 1; /* equivalent to q = &a[1]; */ printf(“%d\n”, q – p ); printf(“%d\n”, (int) q – (int) p ); printf(“%d\n”, sizeof(double) ); return 0; } a[0] a[1] 1 – 0 1 8 바이트 차이 8 바이트 1 8
38
Combining the * and ++ Operators
(p+1)이 가리키는 곳의 value *++p *(++p) *p++ *(p++) (*p)++ p가 가리키는 곳의 value를 increment 하고 저장 point하는 값을 사용한 후 p의 값을 increment *p를 처리한 후, 포인터 p 를 이동시킨다. Expression Meaning *p++ or *(p++) 먼저 *p의 값을 계산한 후에, p를 증가시킨다. (*p)++ 먼저 *p의 값을 계산한 후에, *p를 증가시킨다. *++p or *(++p) p를 먼저 증가시키고 *p값을 계산한다. ++*p or ++(*p) P가 가리키는 곳의 값을 증가시킨 후 사용
39
Combining the * and ++ Operators
a &a b &b * operator 와 ++ operator 사용 예 3 5 [Ex] int a = 3, b = 5 , *p ; p = &a; printf(“%d %d %d\n”, a, b, (*p)++) ; &a 3 5 3 p &p a &a b &b 10 5 [Ex] int a = 10, b = 5 , *p; p = &b ; printf(“%d %d %d\n”, b, *p, ++(*p)) ; &b p &p 5 5 6
40
Combining the * and ++ Operators
* operator 와 ++ operator 사용 예 a[0] 1000 20 a[1] 1004 7 a[2] 1008 -9 [Ex] int a[3]={20, 7, -9}, *p, i ; p = &a[1] ; a[1] 값 변화 ① i = *p++; printf(“%d %d”, i, *p) ; /* i = *p ; p++; p 는 1008번지 */ 7 -9 ② i = *++p ; printf (“%d %d”, i, *p) ; /* ++p ; i = *p ; p 는 1008번지 */ -9 -9 개별 ③ i = ++*p ; printf (“%d %d”, i, *p) ; /* ++(*p); i = 8; p는 1004번지 */ 8 8 ④ i = (*p)++; printf (“%d %d”, i, *p) ; /* i = *p; (*p)++; p는 1004번지 */ 7 8
41
Combining the * and ++ Operators
push , pop functions top_ptr [Ex] /* 상용구처럼 사용 */ void push( int i ) { if ( is_full() ) stack_overflow(); else *top_ptr++ = i; } int pop(void) { if ( is_empty() ) stack_underflow(); return *--top_ptr; stack이 꽉 찬 상태에서 하나가 더 push될 때 실행 *top_ptr 후 top_ptr++ 실행 top_ptr 이 가리키는 곳에 i 를 넣고 top_ptr 을 이동 stack이 빈 상태에서 하나가 더 pop될 때 실행 --top_ptr 후 *top_ptr 실행
42
Passing Arrays to Functions
배열에서의 함수 배열이 함수에 전달될 때, 배열의 주소는 call by value로 전달. 배열 원소들 자체는 call by value로 복사되지 않고 call by reference로 전달된다. [Ex] int sum( int a[], int n) { int i, s = 0; for ( i = 0; i < n; ++i) s += a[ i ]; return s; } int a[ ]는 int *a와 같다. Various ways that sum() might be called Invocation What gets computes and returned sum(v, 100) v[0] + v[1] + … + v[99] sum(v, 88) v[0] + v[1] + … + v[87] sum(&v[7], k – 7 ) v[7] + v[8] + … + v[k -1] sum(v + 7, 2* k ) v[7] + v[8] + … + v[2 * k + 6]
43
Passing Arrays to Functions
Call by Value (값에 의한 호출) [Ex] #include <stdio.h> int sigma (int n ) { int r; for ( r = 0; n > 0; n-- ) r += n; return r; } void main(void) int a; printf(“Input number :”); scanf(“%d”, &a); printf(“Sigma 1 to %d is %d.\n”, a, sigma(a) ); 7을 입력하면??? 28
44
Passing Arrays to Functions
Call by Value (값에 의한 호출) [Ex] #include <stdio.h> void swap(int p, int q); main() { int i = 3, j = 5; swap(i, j); printf(“%d %d\n”, i, j); return 0; } void swap(int p, int q ) int tmp; tmp = p; p = q; q = tmp; i와 j의 값이 그대로 p와q에 복사된다 swap()함수 내에서는 i와j의 값이 서로 바뀌어지지만, 의도했던 대로 p와q의 값은 변하지 않는다. 복사본에 대해서만 swap했고 원본에는 swap을 하지 않았기 때문이다. 3 5
45
Passing Pointers to Functions
Call by Reference (참조에 의한 호출) [Ex] #include <stdio.h> void swap(int *, int *); main() { int i = 3, j = 5; swap(&i, &j); printf(“%d %d\n”, i, j); return 0; } void swap(int *p, int *q ) int tmp; tmp = *p; *p = *q; *q = tmp; swap()함수는 i와 j의 주소 값을 p와 q에 복사한다. swap()함수 내에서는 복사된 주소값에 대해 참조 연산과 할당을 하기 때문에 주소의 내용은 바뀌게 된다. 5 3
46
Passing Pointers to Functions
포인터를 argument로 하는 함수 예제 위 예제의 메모리 공간 [Ex] void decompose (float, int *, float *); /* prototype */ main(){ int i, float f; …… decompose( , &i, &f); } void decompose (float x, int *int_part, float *frac_part){ *int_part = (int)x; *frac_part = x - *int_part; x int_part ? i frac_part ? f
47
Passing Pointers to Functions
포인터를 argument로 하는 함수 예제 void decompose (float x, int *int_part, float *frac_part){ *int_part = (int)x; *frac_part = x - *int_part; } float로 받은 x의 값을 int형으로 casting. *int_part가 point하는 곳으로 3을 저장 x int_part 3 i frac_part ? f
48
Passing Pointers to Functions
포인터를 argument로 하는 함수 예제 void decompose (float x, int *int_part, float *frac_part){ *int_part = (int)x; *frac_part = x - *int_part; } x에서 정수부분을 뺀 부분의 값을 frac_part가 point하는 곳으로 저장 x int_part 3 i frac_part .14159 f
49
Passing Pointers to Functions
포인터를 argument로 하는 함수 사용시 유의점 [Ex] void decompose (float, int *, float *); /* prototype */ main(){ int i, float f; …… decompose( , i, f); } & 연산자가 빠졌다 i값과 f값을 address로 인식하여 int_part, frac_part에 복사됨에 따라 알 수 없는 memory location에 결과를 write. Unpredictable error
50
Problems pointer의 주소 할당 문제 5 4 3 2 1 main( ) {
아래 프로그램을 각 변수의 기억장소 할당 상태 변화를 유의하여 이해해 보십시오. 프로그램의 진행 상황에 따라서 각 기억장소의 내용은 어떻게 되겠는지를 다음 슬라이드의 빈칸을 채우시오. p3 &p[2] p1 &a[1] p2 &a[1] main( ) { int a[5] = {5, 4, 3, 2, 1}, *p1 , *p2 , **p3; p1 = a + 1; p2 = p1; p3 = &p2 ; /* ① */ printf(“%d %d %d %d\n”, a[2], *p1, *p2, *p3); (*p2)++; p3 = &p1 ; /* ② */ *(a + 2) = *p1 + *p2 + **p3; /* ③ */ } 5 4 3 2 1 a[0] a[1] a[2] a[3] a[4]
51
Problems 다음 페이지 부터 정답에 대한 해설이 있습니다. 답을 보기 전에 스스로 문제를 먼저 풀어 보시기 바랍니다.
변수명 기억장소 주소 기억장소내용(value) ①시점 ②시점 ③시점 a[1] 1000 p1 2000 p2 3000 p3 4000
52
문제 풀이 pointer의 예제 p2 = p1; p3 = &p2 ; /* ① */
*(a + 2) = *p1 + *p2 + **p3; /* ③ */ p3 5 4 3 2 1 p2 p1 p3 5 3 2 1 4 p2 p1 p3 5 15 2 1 3 4
53
결과값 문제 풀이 변수명 기억장소 주소 기억장소내용(value) ①시점 ②시점 ③시점 a[1] 1000 4 5 p1 2000
3000 p3 4000
54
Bubble Sort Bubble Sort 과정 설명 (첫번째 pass)
배열의 인접 요소들을 비교하여 교환하는 모양이 마치 거품이 보글보글하는 모양이라고 해서 붙여진 이름이다. 과정 설명 (첫번째 pass) S O R T I N G → S와 O를 비교하여 교환한다. O S R T I N G → S와 R를 비교하여 교환한다. O R S T I N G → S와 T를 비교하여 교환한다. O R S T I N G → T와 I를 비교하여 교환한다. O R S I T N G → T와 N를 비교하여 교환한다. O R S I N T G → T와 G를 비교하여 교환한다. O R S I N G T → 최대값 T가 제일 뒤에 있다.
55
Bubble Sort Bubble Sort 이 부분은 다음 슬라이드 #include <stdio.h>
#define N 10 main() { int a[10]={2, 4, 5, 3, 6, 1, 7, 8, 12, 54}; int i, j, tmp; for (i = 0; i < N; i++) printf("%d ", a[i]); } 이 부분은 다음 슬라이드
56
Bubble Sort Bubble Sort for ( i = 0; i < N-1; i++ ) {
for(j = 0; j < N-i-1; j++) if( a[j] > a[j+1] ) tmp = a[j]; a[j] = a[j+1]; a[j+1] = tmp; }
57
Elements of array a[] after each pass
Bubble Sort int a[] = { 7, 3, 66, 3, -5, 22, -77, 2 }; 으로 선언. bubble( a, 8 ) 로 함수를 호출하면 다음과 같은 과정으로 실행된다. Elements of array a[] after each pass Unordered data 7 3 66 -5 22 -77 2 First pass Second pass Third pass Fourth pass Fifth pass Sixth pass Seventh pass
58
Dynamic Memory Allocation
동적 메모리 할당의 필요성 행렬식같이 반복되고 복잡한 계산을 필요로 하는 프로그램은 배열에 관한 함수를 호출하여 사용하는 것이 편리하다. 아래와 같이 정의된 함수는 3 x 3 의 배열에 대해서만 이용 할 수 있다. 다른 크기의 배열에 대해 계산하고 싶으면 새롭게 함수를 작성해야 한다. 이러한 번거로움을 덜기 위해 동적 메모리 할당을 사용한다. [Ex] main() { … double a[3][3]; det = determinant(a); .. } double determinant ( double a[ ][3] ) { }
59
Dynamic Memory Allocation
동적 메모리 할당 program의 수행 중 new storage를 할당하는 process stdlib.h에 함수 calloc()와 malloc()가 정의. calloc()은 인접한 할당 (contiguous allocation)을 의미. malloc()은 메모리 할당 (memory allocation)을 의미. Compiled C program - 4영역으로 구성 stack , return address of function, parameters, local variables 저장 global variables 저장 program code 저장 heap(unallocated된 free memory)
60
Dynamic Memory Allocation
calloc() 각 원소가 object_size 바이트이고, 이 원소가 n개인 배열을 우해 메모리의 연속된 기억 공간을 할당한다. 각 원소는 0으로 초기화 된다. 호출이 성공하면 할당된 기억공간의 주소를 리턴한다. 호출이 성공하지 못하면 NULL을 리턴한다. calloc() Syntax calloc ( n, object_size ); number of objects size of each object calloc()은 size_t type의 두개의 argument를 가짐 [Ex] void *calloc ( size_t, size_t );
61
Dynamic Memory Allocation
malloc() object_size의 바이트의 메모리 블록을 할당한다 초기화 시키지는 않는다. 호출이 성공하면 할당된 공간의 주소를 리턴한다. 호출이 성공하지 못하면 NULL을 리턴한다. malloc() Syntax malloc ( object_size ); size of each object [Ex] void *malloc ( size_t size ); malloc()은 size_t type의 한개의 argument를 가짐
62
Dynamic Memory Allocation
free() ptr이 포인트하는 메모리 공간을 해제한다. ptr이 NULL이면 이 함수는 효과가 없고, ptr이 NULL이 아니라면 calloc(), malloc(), realloc()에 의해 생성된 주소이어야 하고 free()에 의해 해제되지 않았어야 한다. free()의 prototype은 stdlib.h에 있다. free() Syntax void free(void *ptr); [Ex] p = malloc(…); q = malloc(…); free(p); p = q; free를 호출하는 것은 p가 point하고 있는 memory block를 해제하는 것이다.
63
Dynamic Memory Allocation
Dangling Pointer free()로 할당 해지한 memory block은 deallocate 만 할뿐 실제로 pointer가 point하던 memory block는 유효하게 된다. garbage calloc(), malloc()로 할당한 메모리 block을 free()를 쓰지 않고 종료하면 다음부터는 해당 memory block는 접근 불가능하게 된다. 이렇게 쓸 수 없게 된 memory block를 garbage가 생성되었다고 한다. [Ex] char *p = malloc(4); … free(p); strcpy ( p, “abc” ); /*WRONG */ free로 할당 해지한 pointer를 고치려고 하면 error가 발생한다.
64
Dynamic Memory Allocation
[Ex] #include <stdio.h> #include <stdlib.h> int main(void) { int *a, i, n, sum = 0; printf(“\n%s”, “An array will be created dynamically.\n\n” “Input an array size n followed by n integers: “); scanf(“%d” , &n ); a = calloc(n, sizeof(int) ); /* get space for n ints */ for ( i = 0; i < n; ++i ) scanf(“%d”, &a[ i ] ); /* ( Continue…… ) */ calloc(), malloc(), free() 함수가 정의되어 있는 library 함수 a = malloc(n * sizeof(int) ); 와 같다.
65
Dynamic Memory Allocation
/* ( Continued. ) */ for ( i = 0; i < n; ++i ) sum += a[ i ]; free(a); /*free the space */ printf(“\n%s%7d\n%s%7d\n\n”, “Number of elements: ”, n, “Sum of the elements: “, sum ); return 0; } calloc()로 할당해준 memory block를 deallocation 한다.
66
수고하셨습니다 Arrays and Pointers
Similar presentations