구조체: structure 와 포인터2

26
구구구 : Structure 구 구구구 2

Upload: roanna-barrett

Post on 04-Jan-2016

46 views

Category:

Documents


0 download

DESCRIPTION

구조체: Structure 와 포인터2. 집합적 변수 생성 가능. structure_declaration ::= struct_specifier declarator_list ; struct_specifier ::= struct tag_name | struct tag_name opt { { member_declaration } 1+ } tag_name ::= identifier member_declaration ::= type_specifier declaration_list ; - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: 구조체:  Structure  와 포인터2

구조체 : Structure 와포인터 2

Page 2: 구조체:  Structure  와 포인터2

집합적 변수 생성 가능

structure_declaration ::= struct_specifier declarator_list ;struct_specifier ::= struct tag_name

| struct tag_nameopt { { member_declaration}1+}tag_name ::= identifiermember_declaration ::= type_specifier declaration_list ;declaration_list ::= declarator { , declarator }0+

struct card { int pips; char suit;};

struct card { int pips; char suit;} c1, c2;

struct card c1, c2;

c1.pips = 3;c1.suits = ‘s’;c2 = c1;

Page 3: 구조체:  Structure  와 포인터2

typedef 구문 별명을 정하여 형정의를 할 수 있음

typedef struct card { int pips; char suit;} card;

typedef struct card card;

typedef int INTEGER;INTEGER a;

card c1, c2;

Page 4: 구조체:  Structure  와 포인터2

구조체의 함수에 적용 (1)typedef struct employee_data { char name[25]; int employee_id; struct dept department; struct home_address *a_ptr; double salary; …} employee_data;

employee_data update(employee_data e){ … e.department.dept_no = n; … return e;}

employee_data e1;e1 = update(e1);

함수 호출 절차(call-by-value)

1. 호출시에 , e1 을 e 에 복사2. 리턴시에 , e 를 e1 으로 복사

구조체의 복사시 memberwise copy

문제점 : 구조체의 메모리 요구량이 큰

경우 , 복사에 따른 부하가 커진다 .

Page 5: 구조체:  Structure  와 포인터2

구조체의 함수에 적용 (2)void update(employee_data *p){ … p->department.dept_no = n; (p->department).dept_no = n; (*p).dept_no = n;

… return e;}

employee_data e1;update(&e1);

이 경우 , 함수 호출에 따른 오버헤드는 포인터 변수 복사 .

구조체에 대한 포인터 변수 사용시 , 구조체의 내용을 접근하는 연산자 : ->

Page 6: 구조체:  Structure  와 포인터2

동적 메모리 할당 (1)

#include<stdlib.h>#include<string.h>…void f(){

char *s;s = (char*)malloc(sizeof(char)*8);s[0] = ‘d’; s[1] = ‘y’; s[2] = ‘n’;

s[3] =‘a’; s[4] = ‘m’; s[5] = ‘i’; s[6] = ‘c’; s[7] = ‘\0’;

strcpy(s, “dynamic”);free(s);

}

Page 7: 구조체:  Structure  와 포인터2

동적 메모리 할당 (2) 컴파일시에 메모리의 할당 크기가 정해지는

것이 아니라 , 프로그램 실행중에 가변적인 크기의 메모리를 할당 / 해제 할 수 있게 됨

함수내에서 할당된 동적 메모리는 함수 종료후에 자동 해제 되지 않음

반드시 , malloc/free 을 쌍으로 호출하는 습관을 익힐 것

Page 8: 구조체:  Structure  와 포인터2

동적 메모리 할당 (3) #include <stdlib.h> void *malloc( size_t size ); void free( void *memblock );

Page 9: 구조체:  Structure  와 포인터2

포인터 주소 연산000010ae000010a7000010b4000030ff00007f77

A

B

C

D

\0int *pI;pI = (int*)malloc(sizeof(int)*5);pI[0]=0x10ae; pI[1]=0x10a7;pI[2]=0x10b4; pI[3]=0x30ff;pI[4]=0x7f77;*(pI)=0x10ae; *(pI+1)=0x10a7;*(pI+2)=0x10b4;*(pI+3)=0x30ff;*(pI+4)=0x7f77;

char *pC;pC = (char*)malloc(sizeof(char)*5);pC[0]=‘A’; pC[1]=‘B’; pC[2]=‘C’;pC[3]=‘D’; pC[4]=‘\0’;*(pI)=‘A’; *(pI+1)=‘B’; *(pI+2)=‘C’;*(pI+3)=‘D’; *(pI+4)=‘\0’;

0x00430180

0x00430184

0x00430188

0x00430150

0x00430151

0x00430152

Page 10: 구조체:  Structure  와 포인터2

포인터 이해 (1)int p; /* p is integer */int p[7]; /* p is array[7] of integer */int *p; /* p is pointer to integer */int *p[7]; /* p is array[7] of pointer to integer */int (*p)[7]; /* p is pointer to array[7] of integer */int **p; /* p is pointer to pointer to integer */

void f(); /* f is function returning void */void *f(); /* f is function returning pointer to void */void (*fp)(); /* fp is pointer to function returning void */void *(*fp)(); /* fp is pointer to function returning pointer to void */Void (*fp[7])(); /* fp is array[7] of pointer to function returning void */

힌트 :•는 [] 나 () 보다 우선 순위가 늦음 .

Page 11: 구조체:  Structure  와 포인터2

포인터 이해 (2) 형변환

int a[5];int (*p)[5];p = (int (*)[5])a;

long al = 0x00001234;Short bl;bl = (short)al;

Page 12: 구조체:  Structure  와 포인터2

배열과 포인터 (1)int a[3][5];

col 1 col 2 col 3 col 4 col 5

row 1a[0][0]

a[0][1]

a[0][2]

a[0][3]

a[0][4]

row 2a[1][0]

a[1][1]

a[1][2]

a[1][3]

a[1][4]

row 3a[2][0]

a[2][1]

a[2][2]

a[2][3]

a[2][4]

a[i][j];*(a[i] + j);(*(a+i))[j];*((*(a+i)) + j)*(&a[0][0] + 5*i +j)

Page 13: 구조체:  Structure  와 포인터2

배열과 포인터 (2) 함수 인자로서의 배열int sum(int a[][5]){ int i, j, sum = 0; for(i=0; i < 3; i++) for(j=0; j < 5; j++) sum += a[i][j] return sum;}

int sum(int a[][5])int sum(int a[3][5])int sum(int (*a)[5])

int sum(int (*a)[5]){ int i, j, sum = 0; for(i=0; i < 3; i++) for(j=0; j < 5; j++) sum += a[i][j] return sum;}

int b[][5] = {1,2,3, …};c = sum(b); /* C- 스타일 */c = sum((int (*)[5])b); /*C++ 스타일 */

Page 14: 구조체:  Structure  와 포인터2

배열과 포인터 (3) 기본적으로 배열과 포인터는 동일한

인터페이스 3 차원 배열

int sum(int a[][5][7])int sum(int a[3][5][7])int sum(int (*a)[5][7])

a[i][j][k] == *(&a[0][0][0] + 5*7*i + 7*j +k)

Page 15: 구조체:  Structure  와 포인터2

char *

const char *p = “constant”;p[0] = ‘d’; /* not possible */

char *p = “constant”;p[0] = ‘d’; /* not possible */

const qualifier( 한정어 ) : 상수처럼 취급하게 해줌 . 즉 변수의 값이 변하지 않아야 한다는 것을 명시적으로 지정해 준다 .

Page 16: 구조체:  Structure  와 포인터2

char ** (1)

void swapstrings(char *l, char *r){ char *t; t = l; l = r; r = t;}

char *l, *r;l = “left”;r = “right”;swapstrings(l, r);

주소 메모리내용

1000 2000

1004 2008

2000 “left”

2008 “right”

3000

3004 2000

3008 2008

l

r

t

lr맞게 교환되었을까 ?

Page 17: 구조체:  Structure  와 포인터2

char ** (1)

void swapstrings(char *l, char *r){ char *t; t = l; l = r; r = t;}

char *l, *r;l = “left”;r = “right”;swapstrings(l, r);

주소 메모리내용

1000 2000

1004 2008

2000 “left”

2008 “right”

3000 2000

3004 2000

3008 2008

l

r

t

lr맞게 교환되었을까 ?

Page 18: 구조체:  Structure  와 포인터2

char ** (1)

void swapstrings(char *l, char *r){ char *t; t = l; l = r; r = t;}

char *l, *r;l = “left”;r = “right”;swapstrings(l, r);

주소 메모리내용

1000 2000

1004 2008

2000 “left”

2008 “right”

3000 2000

3004 2008

3008 2008

l

r

t

lr맞게 교환되었을까 ?

Page 19: 구조체:  Structure  와 포인터2

char ** (1)

void swapstrings(char *l, char *r){ char *t; t = l; l = r; r = t;}

char *l, *r;l = “left”;r = “right”;swapstrings(l, r);

주소 메모리내용

1000 2000

1004 2008

2000 “left”

2008 “right”

3000 2000

3004 2008

3008 2000

l

r

t

lr맞게 교환되었을까 ?

Page 20: 구조체:  Structure  와 포인터2

char ** (2)

void swapstrings(char **l, char **r){ char *t; t = *l; *l = *r; *r = t;}

char *l, *r;l = “left”;r = “right”;swapstrings(&l, &r);

주소 메모리내용

1000 2000

1004 2008

2000 “left”

2008 “right”

3000

3004 1000

3008 1004

l

r

t

lr맞게 교환되었을까 ?

Page 21: 구조체:  Structure  와 포인터2

char ** (2)

void swapstrings(char **l, char **r){ char *t; t = *l; *l = *r; *r = t;}

char *l, *r;l = “left”;r = “right”;swapstrings(&l, &r);

주소 메모리내용

1000 2000

1004 2008

2000 “left”

2008 “right”

3000 2000

3004 1000

3008 1004

l

r

t

lr맞게 교환되었을까 ?

Page 22: 구조체:  Structure  와 포인터2

char ** (2)

void swapstrings(char **l, char **r){ char *t; t = *l; *l = *r; *r = t;}

char *l, *r;l = “left”;r = “right”;swapstrings(&l, &r);

주소 메모리내용

1000 2008

1004 2008

2000 “left”

2008 “right”

3000 2000

3004 1000

3008 1004

l

r

t

lr맞게 교환되었을까 ?

Page 23: 구조체:  Structure  와 포인터2

char ** (2)

void swapstrings(char **l, char **r){ char *t; t = *l; *l = *r; *r = t;}

char *l, *r;l = “left”;r = “right”;swapstrings(&l, &r);

주소 메모리내용

1000 2008

1004 2000

2000 “left”

2008 “right”

3000

3004 1000

3008 1004

l

r

t

lr맞게 교환되었을까 ?

Page 24: 구조체:  Structure  와 포인터2

main 함수의 인자 전달

int main(int argc, char *argv[]){ … return 1;}

C:\a.exe this is a final homework.

argv[0]

argv[1]

argv[2]

argv[3]

argv[4]

argv[5]

a.exe

this

is

a

final

homework

Page 25: 구조체:  Structure  와 포인터2

과제 (6 월 10 일 자정까지 ) 프로그램 실행시 main 함수의 인자로

받은 문자열을 ASCII 순으로 정렬하여 출력하는 프로그램 작성

교재 6.13 참고 이메일 제출

소스코드 보고서

Page 26: 구조체:  Structure  와 포인터2

보고서 작성 요령 소스 코드 설명 정렬이 되는 과정을 설명 보고서 채점 비중 높음

6 월 11 일 기말 고사에서는 과제와 관련된 내용 출제될 예정