Chapter 9 Arrays and Pointers

Slides:



Advertisements
Similar presentations
Chapter 12. 배열. 배열  동일한 항목들이 동일한 크기로 연속적으로 메모리에 저장되는 구조  동일한 자료 유형이 여러 개 필요한 경우에 이용할 수 있는 자료 구조.
Advertisements

1 08 배열. 한국대학교 객체지향연구소 2 C 로 배우는 프로그래밍 기초 2 nd Edition 배열  동일한 자료유형의 여러 변수를 일괄 선언  연속적인 항목들이 동일한 크기로 메모리에 저장되는 구조  동일한 자료 유형이 여러 개 필요한 경우에 이용할 수 있는.
1. 2 차원 배열  배열은 동일한 데이터 유형으로 여러 개의 변수를 사용할 경우 같은 이 름으로 지정하여 간편하게 사용할 수 있도록 하는 것으로서 앞에서 1 차원 배열을 공부하였습니다.  2 차원 배열은 바둑판을 생각하면 되며, 1 차원 배열에서 사용하는 첨자를 2.
C 언어 (STS ) 10. Pointer Applications.
ㅎㅎ 구조체 구조체 사용하기 함수 매개변수로서의 구조체 구조체 포인터와 레퍼런스 구조체 배열.
쉽게 풀어쓴 C언어 Express 제11장 포인터 C Express.
쉽게 풀어쓴 C언어 Express 제11장 포인터 C Express Slide 1 (of 27)
제 9 장 포인터.
쉽게 풀어쓴 C언어 Express 제11장 포인터 C Express.
2장. 프로그램의 기본 구성. 2장. 프로그램의 기본 구성 2-1"Hello, World!" 들여다 보기 /* Hello.c */ #include int main(void) { printf("Hello, World! \n"); return 0;
제14장 동적 메모리.
쉽게 풀어쓴 C언어 Express 제11장 포인터 C Express.
9장. C 언어의 핵심! 함수. 9장. C 언어의 핵심! 함수 9-1 함수의 정의와 선언 main 함수 다시 보기 : 함수의 기본 형태 { } 그림 9-1.
제 9 장 구조체와 공용체.
Report #2 - Solution 문제 #1: 다음과 같이 프로그램을 작성하라.
-Part2- 제3장 포인터란 무엇인가.
C 8장. 포인터 #include <stdio.h> int main(void) { int num;
자료 구조: Chapter 3 (2)구조체, 포인터
3장. 변수와 연산자. 3장. 변수와 연산자 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, / 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, /
개정판 누구나 즐기는 C언어 콘서트 제9장 포인터 출처: pixabay.
윤성우의 열혈 C 프로그래밍 윤성우 저 열혈강의 C 프로그래밍 개정판 Chapter 12. 포인터의 이해.
누구나 즐기는 C언어 콘서트 제8장 배열.
쉽게 풀어쓴 C언어 Express 제17장 동적메모리와 연결리스트 C Express Slide 1 (of 13)
Chapter 10 Pointer Applications.
5장. 참조 타입.
C++ 프로그래밍 년 2학기 전자정보공학대학 컴퓨터공학부.
C 프로그래밍.
Dynamic Memory and Linked List
11장. 포인터 01_ 포인터의 기본 02_ 포인터와 Const.
포인터 활용 포인터 활용.
쉽게 풀어쓴 C언어 Express 제14장 포인터 활용 C Express.
8장 함수 함수의 필요성 라이브러리 함수와 사용자 정의 함수 함수의 정의, 원형, 호출 배열을 함수 인자로 전달 재귀호출.
컴퓨터 프로그래밍 기초 #02 : printf(), scanf()
제8장 배열 1부 8.1 배열 8.2 배열의 초기화 8.3 배열의 응용 8.4 정렬과 탐색 8.5 다차원 배열.
프로그래밍 랩 – 7주 리스트.
14장. 포인터와 함수에 대한 이해.
11장. 1차원 배열.
C 8장. 포인터 #include <stdio.h> int main(void) { int num;
처음으로 배우는 C 프로그래밍 제4부 복합 데이터 형 제 8 장 배열, 주소, 포인터.
C#.
프로그래밍 개요
어서와 C언어는 처음이지 제14장.
박성진 컴퓨터 프로그래밍 기초 [09] 배열 part 1 박성진
13. 포인터와 배열! 함께 이해하기 IT응용시스템공학과 김 형 진 교수.
3장 상수 변수 기본 자료형 키워드와 식별자 상수와 변수 기본 자료형 형변환 자료형의 재정의.
Java의 정석 제 5 장 배 열 Java 정석 남궁성 강의 의
쉽게 풀어쓴 C언어 Express 제14장 포인터 활용 C Express Slide 1 (of 22)
3장. 변수와 연산자 교안 : 전자정보통신 홈페이지 / 커뮤니티/ 학술세미나
Chapter6 : JVM과 메모리 6.1 JVM의 구조와 메모리 모델 6.2 프로그램 실행과 메모리 6.3 객체생성과 메모리
컴퓨터 프로그래밍 기초 - 10th : 포인터 및 구조체 -
2장. 변수와 타입.
제 3 강.
프로그래밍 기초와 실습 Chapter 11 Recursion.
처음으로 배우는 C 프로그래밍 제4부 복합 데이터 형 제 7 장 배열.
김선균 컴퓨터 프로그래밍 기초 - 7th : 함수 - 김선균
컴퓨터 프로그래밍 기초 - 8th : 함수와 변수 / 배열 -
8주차: Strings, Arrays and Pointers
Fucntion 요약.
함수(Function) ◈ 함수의 개념 및 사용 이유 ◈ 함수 정의, 호출 및 선언 ◈ 지역변수와 전역변수 ◈ return 문
에어 PHP 입문.
7주차: Functions and Arrays
컴퓨터 프로그래밍 기초 - 9th : 배열 / 포인터 -
Summary of Pointers and Arrays
Numerical Analysis Programming using NRs
1. 지역변수와 전역변수 2. auto, register 3. static,extern 4. 도움말 사용법
어서와 C언어는 처음이지 제21장.
개정판 누구나 즐기는 C언어 콘서트 제13장 동적 메모리 출처: pixabay.
13. 포인터와 배열! 함께 이해하기.
Pointers summary.
2019 2학기 9장 배열과 포인터 1. 주소, 주소연산자(&) 2. 포인터, 역참조연산자(*) 3. 배열과 포인터.
Presentation transcript:

Chapter 9 Arrays and Pointers 프로그래밍 기초와 실습 Chapter 9 Arrays and Pointers

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

Contents Passing Arrays to Functions Passing Pointers to Functions Bubble Sort Dynamic Memory Allocation calloc() and malloc()

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

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을 저장

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

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

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으로 초기화 된다.

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는 같은 값을 갖는다.

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]를 사용하는 것은 범하기 쉬운 오류이다. 배열의 범위를 유의! .

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

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()로 입력받는다. 소문자는 대문자로 바꾼다. 배열에 저장된 문자들의 개수를 하나씩 출력한다.

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 : 1 2 3 4 5 6 7 8 9 10 In reverse order : 10 9 8 7 6 5 4 3 2 1

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이란 변수명을 선언하여 사용.

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 : 28212 ꎠ Repeated digit

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]

Two-Dimensional Arrays 이차원배열의 elements 이차원 배열의 기억장소를 앞 테이블 같이 그려보았지만 실제로 컴퓨터 메모리에 저장되는 기억장소는 다음과 같다. 일련의 메모리 공간에 차례대로 배열이 지정되는 것이다. row0 row1 row2 [Ex] int a[3][5]; col1 col2 col3 col4 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]

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

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 )

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

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] 으로 한 경우 문제

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

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으로 초기화 된다.

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

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);

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 1245052:1245052(address값)

The Relationship between Arrays and Pointers 어떤 값이 저장된 memory 주소를 값으로 하는 data item memory address를 값으로 하는 변수 [Ex] #define N 100 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번지 주소를 배정. 두 문장은 같다.

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]와 동일하다.

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의 주소를 바꿀 수가 없다.

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++ ) 로 변환이 가능하다.

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

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;

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;

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

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 참

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

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

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가 가리키는 곳의 값을 증가시킨 후 사용

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

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

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 실행

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]

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을 입력하면??? 7+6+5+4+3+2+1  28

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

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

Passing Pointers to Functions 포인터를 argument로 하는 함수 예제 위 예제의 메모리 공간 [Ex] void decompose (float, int *, float *); /* prototype */ main(){ int i, float f; …… decompose(3.14159, &i, &f); } void decompose (float x, int *int_part, float *frac_part){ *int_part = (int)x; *frac_part = x - *int_part; x 3.14159 int_part ? i frac_part ? f

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 3.14159 int_part 3 i frac_part ? f

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 3.14159 int_part 3 i frac_part .14159 f

Passing Pointers to Functions 포인터를 argument로 하는 함수 사용시 유의점 [Ex] void decompose (float, int *, float *); /* prototype */ main(){ int i, float f; …… decompose(3.14159, i, f); } & 연산자가 빠졌다 i값과 f값을 address로 인식하여 int_part, frac_part에 복사됨에 따라 알 수 없는 memory location에 결과를 write.  Unpredictable error

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] 3 4 4 3000 3 5 5 3000 15 5 5 3000

Problems 다음 페이지 부터 정답에 대한 해설이 있습니다. 답을 보기 전에 스스로 문제를 먼저 풀어 보시기 바랍니다. 변수명 기억장소 주소 기억장소내용(value) ①시점 ②시점 ③시점 a[1] 1000 p1 2000 p2 3000 p3 4000

문제 풀이 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

결과값 문제 풀이 변수명 기억장소 주소 기억장소내용(value) ①시점 ②시점 ③시점 a[1] 1000 4 5 p1 2000 3000 p3 4000

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가 제일 뒤에 있다. 3 2 1 5 4 2 3 1 5 4 2 1 3 5 4 2 1 3 5 4 2 1 3 4 5

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]); } 이 부분은 다음 슬라이드

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; }

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

Dynamic Memory Allocation 동적 메모리 할당의 필요성 행렬식같이 반복되고 복잡한 계산을 필요로 하는 프로그램은 배열에 관한 함수를 호출하여 사용하는 것이 편리하다. 아래와 같이 정의된 함수는 3 x 3 의 배열에 대해서만 이용 할 수 있다. 다른 크기의 배열에 대해 계산하고 싶으면 새롭게 함수를 작성해야 한다. 이러한 번거로움을 덜기 위해 동적 메모리 할당을 사용한다. [Ex] main() { … double a[3][3]; det = determinant(a); .. } double determinant ( double a[ ][3] ) { ... }

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)

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 );

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를 가짐

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를 해제하는 것이다.

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가 발생한다.

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) ); 와 같다.

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 한다.

수고하셨습니다 Arrays and Pointers