윤 홍 란 hryun@sookmyung.ac.kr 포인터 윤 홍 란 hryun@sookmyung.ac.kr.

Slides:



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

1 08 배열. 한국대학교 객체지향연구소 2 C 로 배우는 프로그래밍 기초 2 nd Edition 배열  동일한 자료유형의 여러 변수를 일괄 선언  연속적인 항목들이 동일한 크기로 메모리에 저장되는 구조  동일한 자료 유형이 여러 개 필요한 경우에 이용할 수 있는.
1. 2 차원 배열  배열은 동일한 데이터 유형으로 여러 개의 변수를 사용할 경우 같은 이 름으로 지정하여 간편하게 사용할 수 있도록 하는 것으로서 앞에서 1 차원 배열을 공부하였습니다.  2 차원 배열은 바둑판을 생각하면 되며, 1 차원 배열에서 사용하는 첨자를 2.
1 구조체 윤 홍 란 컴퓨터 프로그래밍 2 구조체 정의  구조체란 ? o 서로 다른 형의 변수들을 하나로 묶어주는 mechanism. (cf. 배열 : 같은 형의 변수들을 하나로 묶어주는 mechanism) o 예 : 카드의.
C 언어 (STS ) 10. Pointer Applications.
포인터란? 사전적 의미로써 지시자 혹은 가리키는 것으로 풀이할 수 있으나, C프로그래밍 언어에서는 메모리의 주소를 저장하는 변수이다. 포인터 자체가 하나의 변수이기 때문에 포인터도 메모리 내에서 선언이 되며 일반 상수를 저장하는 변수가 아닌 주소값을 저장하는 변수라는 점에서.
ㅎㅎ 구조체 구조체 사용하기 함수 매개변수로서의 구조체 구조체 포인터와 레퍼런스 구조체 배열.
ㅎㅎ 구조체 C++ 프로그래밍 기초 : 객체지향의 시작 구조체 사용하기 함수 매개변수로서의 구조체 구조체 포인터와 레퍼런스
쉽게 풀어쓴 C언어 Express 제11장 포인터 C Express.
쉽게 풀어쓴 C언어 Express 제11장 포인터 C Express Slide 1 (of 27)
제 9 장 포인터.
쉽게 풀어쓴 C언어 Express 제11장 포인터 C Express.
Part 11 문자열 ©우균, 창병모 ©우균, 창병모.
2장. 프로그램의 기본 구성. 2장. 프로그램의 기본 구성 2-1"Hello, World!" 들여다 보기 /* Hello.c */ #include int main(void) { printf("Hello, World! \n"); return 0;
쉽게 풀어쓴 C언어 Express 제11장 포인터 C Express.
9장. C 언어의 핵심! 함수. 9장. C 언어의 핵심! 함수 9-1 함수의 정의와 선언 main 함수 다시 보기 : 함수의 기본 형태 { } 그림 9-1.
제 9 장 구조체와 공용체.
컴퓨터 프로그래밍 기초 [Final] 기말고사
-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. 포인터의 이해.
5장 배열 작성자 : 변재현.
제15장 파일 입출력 문자열을 출력하는 여러가지 방법 (15-2쪽) 문자열만 처리하는 입출력 함수
제 6장. 생성자와 소멸자 학기 프로그래밍언어및실습 (C++).
쉽게 풀어쓴 C언어 Express 제17장 동적메모리와 연결리스트 C Express Slide 1 (of 13)
5장. 참조 타입.
C++ 프로그래밍 년 2학기 전자정보공학대학 컴퓨터공학부.
C 프로그래밍.
11장. 포인터 01_ 포인터의 기본 02_ 포인터와 Const.
포인터 활용 포인터 활용.
쉽게 풀어쓴 C언어 Express 제14장 포인터 활용 C Express.
8장 함수 함수의 필요성 라이브러리 함수와 사용자 정의 함수 함수의 정의, 원형, 호출 배열을 함수 인자로 전달 재귀호출.
컴퓨터 프로그래밍 기초 #02 : printf(), scanf()
14장. 포인터와 함수에 대한 이해.
11장. 1차원 배열.
C 8장. 포인터 #include <stdio.h> int main(void) { int num;
처음으로 배우는 C 프로그래밍 제4부 복합 데이터 형 제 8 장 배열, 주소, 포인터.
C#.
13. 포인터와 배열! 함께 이해하기 IT응용시스템공학과 김 형 진 교수.
3장 상수 변수 기본 자료형 키워드와 식별자 상수와 변수 기본 자료형 형변환 자료형의 재정의.
Java의 정석 제 5 장 배 열 Java 정석 남궁성 강의 의
쉽게 풀어쓴 C언어 Express 제14장 포인터 활용 C Express Slide 1 (of 22)
19. 함수 포인터와 void 포인터.
3장. 변수와 연산자 교안 : 전자정보통신 홈페이지 / 커뮤니티/ 학술세미나
Chapter6 : JVM과 메모리 6.1 JVM의 구조와 메모리 모델 6.2 프로그램 실행과 메모리 6.3 객체생성과 메모리
포인터 1차원 배열과 포인터 2차원 배열과 포인터 문자열 배열과 포인터 포인터 배열
컴퓨터 프로그래밍 기초 - 10th : 포인터 및 구조체 -
5장 배열과 문자열 C 프로그래밍.
8주차: Strings, Arrays and Pointers
Choi Seong Yun 컴퓨터 프로그래밍 기초 #03 : 변수와 자료형 Choi Seong Yun
Canary value 스택 가드(Stack Guard).
제 6 장 함수(functions).
Chapter 09. 포인터 1.
7주차: Functions and Arrays
컴퓨터 프로그래밍 기초 - 9th : 배열 / 포인터 -
구조체(struct)와 공용체(union)
Summary of Pointers and Arrays
Numerical Analysis Programming using NRs
Chapter 11 구조체.
제 4 장 Record.
제 29 강 스트링(string) 다루기 s a i s . s T i h t g r i n.
김선균 컴퓨터 프로그래밍 기초 - 12th : 문자열 - 김선균
어서와 C언어는 처음이지 제21장.
개정판 누구나 즐기는 C언어 콘서트 제13장 동적 메모리 출처: pixabay.
13. 포인터와 배열! 함께 이해하기.
Pointers summary.
2019 2학기 9장 배열과 포인터 1. 주소, 주소연산자(&) 2. 포인터, 역참조연산자(*) 3. 배열과 포인터.
Presentation transcript:

윤 홍 란 hryun@sookmyung.ac.kr 포인터 윤 홍 란 hryun@sookmyung.ac.kr

내용 포인터의 개념 포인터 연산 문자열과 문자 배열 그리고 문자열 포인터(배열 관점) 1차원 배열과 포인터(포인터 관점) 다차원 배열과 포인터 배열 포인터 배열을 함수의 인자로 전달하는 방법 포인터 배열 명령 라인 인수 프로그램 예제

포인터의 개념 개념 메모리의 특정 위치를 접근(access)하기 위한 mechanism. 포인터란 메모리의 임의의 주소를 지정하는 것. 포인터 변수란 임의의 주소를 저장하는 변수. 포인터 변수는 *기호로 선언. 예 int v; /* 변수 v */ &v /* v의 address */ int *vp; /* pointer 변수 */ vp = &v; 메모리 구조 주소 1 2 3 4 1000 메모리 끝       바이트 바이트 바이트 바이트

일반적인 변수의 경우 변수 선언의 의미 변수의 메모리 할당 구조 변수를 선언하면 컴파일러는 주소를 찾아 변수의 데어터형 크기만큼 메모리를 확보한다. 변수의 메모리 할당 구조 변수 TABLE 구조 변수 이름 시작 주소 데이터형 a 1000 int b 1002 float c 1006 int a = 10; float b = 10.11; float c; c = a + b a b c 각 변수가 독점적사용 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 10 10.11 20.11 2바이트 4바이트 결과값을 여기서부터 4 바이트 로 저장 c= a + b;

포인터사용 포인터의 의미 포인터는 자신이 가리키는 데이터가 있는 주기억장치의 주소를 갖고 있다. 포인터 이용 장점 데이터 접근 속도가 빠르다. 어떤 연산은 단지 포인터만을 사용해야 가능하다. 포인터가 할 수 있는 일 배열의 요소를 다룰 수 있다. 함수의 인수로 사용되어 데이터를 변경할 수 있다. 메모리를 동적으로 할당할 수 있다. 함수 호출을 동적으로 할 수 있다.

포인터사용 포인터의 선언 포인터 선언 형식 : 데이터형 *포인터 변수명, *포인터 변수명 ; 포인터의 선언 예 문자열 포인터 선언 : char *ps; 정수형 포인터 선언 : int *pi; 실수형 포인터 선언 : float *pf; Long형 포인터 선언 : long *pl; 주소 연산자(&): 단항 연산자로 대상체의 주소를 나타냄. 포인터 선언 형식 : 데이터형 *포인터 변수명, *포인터 변수명 ; 데이터형:포인터가 가리키는 대상체(object)의 데이터형 *:변수를 포인터로 정의하는 간접 연산자

포인터사용 포인터 변수의 초기화 포인터 선언과 동시에 초기화 : 데이터형 *포인터 변수명 = &변수명; int a=100; int *ip = &a; 포인터 선언 후 대입문을 이용한 초기화 : 포인터 변수명 = &변수명; int x = 100, *ip; ip = &x; int j = 100; char c = ‘A’; float f = 100.21; int *pj = &j; char *pc = &c; float *pf = &f; 100 102 104 1000 1001 1002 1003 1004 1005 1006 1000 1002 1003 100 ‘A’ 100.21 pj pc pf j c f pj pc pf

포인터사용 포인터 사용시 주의할 점 int형 변수의 주소 값은 int형 포인터 변수에, double형 변수의 주소 값은 반드시 double형 포인터 변수에 넣어야 한다. 포인터는 항상 기억장소를 가리키고 있어야 한다. 포인터는 사용하기 전에 어떤 변수를 가리키도록 초기화 되어야 한다.

포인터 연산 포인터 가능 연산 1) p = &x 포인터에 변수의 주소를 할당(p는 포인터 변수) 3) p++,p-- 증감 연산자를 이용한 포인터 증가, 감소 4) p1 – p2 두 개의 포인터의 뺄셈 5) p+4,p-2 포인터에 정수를 더하기, 빼기 6) if(pa<pb) 포인터 비교 포인터 불가능 연산 1) 포인터의 곱셈 p * 2 2) 포인터의 나눗셈 p/2 3) 모든 실수형 포인터 연산 p + 4.5

* 와 & i j p 1 2 ? i j p 1 2 i j p 1 2 i j p 2 2 * 는 '&'와 상반되는 연산자 임. (예) int i = 1, j = 2, *p; p = &i; /* i의 address를 p에 배정한다. */ p = &j; /* j의 address를 p에 배정한다. */ i = *p; /* i에 p가 point하는 값을 배정한다. */ /* == (i = j); */ i j p 1 2 ? i j p 1 2 i j p 1 2 i j p 2 2

포인터 연산 포인터에 정수를 더하거나 빼기의 의미 int * ip; /* 포인터 ip가 현재 주소 1000을 가리킨다 */ 포인터 변수에 정수를 더하는 것은 주소+정수가 아니다. 실제 주소 = 포인터가 가리키는 주소 + 정수 × 포인터 변수 데이터형 크기 (char: 1바이트, float: 4바이트, int: 2바이트, long: 4바이트, double: 8바이트) int * ip;    /* 포인터 ip가 현재 주소 1000을 가리킨다 */    ip + 1  → 1002 (1000 + 1 × 2바이트)      ip + 3  → 1006 (1000 + 3 × 2바이트)      ip - 2  →  996 (1000 - 2 × 2바이트)      float *fp;    /* 포인터 fp가 현재 주소 2000을 가리킨다 */      fp + 1 → 2004 (2000 + 1 × 4바이트)      fp + 3 → 2012 (2000 + 3 × 4바이트)

Call by Value와 Call by reference 값에 의하여 호출하고 인수의 값을 건네주는 방식 #include <stdio.h> void change(int x, int y); void main(void) { int a=3, b=5; printf("호출 전 a=%d, b=%d\n", a, b); change(a, b); printf("호출 후 a=%d, b=%d\n", a, b); } void change(int x, int y) { int temp; temp = x; x = y; y = temp; printf("change 함수 내 a=%d, b=%d\n", x, y); } 호출 전 a = 3, b = 5 Change 함수 내 a = 5, b = 3 호출 후 a = 3, b = 5

Call by Value와 Call by reference 참조에 의해 호출하고 인수의 address를 건네 주는 방식 void change(int *x, int *y)   /* 두 개의 매개변수는 포인터 변수이다 */ void main( ) {    ……          change(&a, &b);   /* 주소 연산자를 이용해서 변수의 주소를 넘긴다 */           …      }      void change(int *x, int *y)      {    int temp;           temp = *x;            *x = *y;              *y = temp;       }

(예). void swap(int. p, int. q). {. int temp;. temp =. p;. p =. q; (예) void swap(int *p, int *q) { int temp; temp = *p; *p = *q; *q = temp; } void main() { int i = 3, j = 5; swap(&i, &j); printf(" %d %d", i, j); } main swap p q 실행 결과 : 5 3 ↑ ↑ i j swap(&i, &j); temp 3 5

문자열과 문자 배열 그리고 문자열 포인터 문자열과 문자 배열의 차이점 문자 배열은 배열 원소인 문자가 연속적으로 메모리에 저장된 형태 문자열은 문자열의 각 원소가 연속적으로 메모리에 저장된 형태 char ch[5] = {‘a’, ‘b’, ‘c’, ‘d’, ‘e’}; 문자 배열의 메모리 구조 1000 1001 1002 1003 1004 a b c d e Ch[0] Ch[1] Ch[2] Ch[3] Ch[4] 문자열(“abcde”)의 메모리 구조 2000 2001 2003 2004 2005 2006 a b c d e \0

문자열과 문자 배열 그리고 문자열 포인터 문자열을 다루는 방법 문자열의 초기화 문자열을 문자 배열로 다루기 위해서는 마지막에 널(‘\0’)을 포함 시킨다. 문자열의 초기화 문자 배열 선언과 동시에 문자열 초기화 char ch[5]={‘a’, ‘b’, ‘c’, ‘d’, ‘e’}; char ch[5]={‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘\0’}; ① char ch[6] = “abcde”; →널(‘\0’) 문자를 포함한 크기만큼 개수를 지정 ② char ch[6] = {‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘\0’}; →문자열을 개별 요소처럼 저장 ③ char ch[ ] = “abcde”; ③과 같은 경우는 선언 후에는 대입 연산자를 이용해서 문자 배열에 대입할 수 없다.

문자열과 문자 배열 그리고 문자열 포인터  포인터를 이용한 문자열의 초기화 선언 후 문자열을 대입하기 위해서는 아래 방법을 사용해야 한다. 1) 문자열의 각 문자를 문자 배열 원소에 대입한다. ch[0] = ‘a’;ch[1] = ‘b’;ch[2] = ‘c’;ch[3] = ‘d’;ch[4] = ‘e’;ch[5] = ‘\0’; 2) 문자열을 복사하는 라이브러리 함수 strcpy( )를 이용한다. strcpy(ch, “abcde”);  포인터를 이용한 문자열의 초기화 문자열의 시작 주소를 포인터가 가리키게 하여 포인터를 마치 배열명 대신 사용하여 문자열을 다룰 수 있다. char *ps = “abcde”  또는  char *ps;ps = “abcde”;

표준 라이브러리에 있는 문자열 조작 함수(string.h) char *strcat(char *s1, char *s2); 두개의 문자열 s1과 s2를 결합하여 s1에 결과 저장. s1은 결과를 저장할 수 있을 만큼의 충분한 공간을 point할 수 있도록 해야 함. 문자열 s1이 return 됨. int strcmp(char *s1, char *s2); 두 문자열이 인자로 전달됨. s1과 s2를 사전적 순서로 비교하여 s1이 작으면 음수, 크면 양수, 같으면 0을 return. int strlen(char *); '\0'을 제외한 문자의 개수를 returen. char *strcpy(char *s1, char *s2); 문자열 s2를 '\0'이 나올때까지 s1에 복사. s1의 내용은 s2의 내용으로 overwrite 됨 s1에 충분한 공간이 마련되어야 함. pointer s1이 return됨.

선언 및 초기화 수식 문장 char s1[] = "beautiful big sky country", s2[] = "how now brown cow"; 수식 값 strlen(s1) 25 strlen(s2 + 8) 9 strcmp(s1, s2) 음의 정수 문장 출력되는 값 printf("%s", s1+10); big sky country strcpy(s1 + 10, s2 + 8); strcat(s1, "s!"); printf("%s", s1); beautiful brown cows!

1차원 배열과 포인터 배열 연산과 포인터 연산 px + 1의 의미 배열 연산 : 선언문에서 배열을 정의하거나 또는 수식 중 첨자를 사용해 배열 원소를 참조하는 것. 포인터 연산 : 포인터가 배열을 가리키고 포인터에 관계된 연산을 하는 것. px + 1의 의미 int  x[5] = { 1, 2, 3, 4, 5 };      int  *px;      px = x; /* px = &x[0]와 같다. */ 포인터 px는 현재 배열의 시작 주소

1차원 배열과 포인터 *(px + i)의 의미 배열 x의 i번째 값을 나타낸다. #include <stdio.h> void main( ) {   int a[4] = {1, 2, 3, 4};      int *pi, index;      pi = a;    /* pi = &a[0]와 동일, pi는 배열 a의 시작 주소를 갖는다. */      for(index = 0; index < 4; ++index)      printf(“a[%d]의 주소:%u, pi + %d의 주소: %u, *(pi+%d)의 값: %d                    \n”, index, &a[index], index, pi + index, index,*(pi+index)); } a[0]의 주소: 1000, pi + 0의 주소: 1000  *(pi + 0)의 값: 1 a[1]의 주소: 1002, pi + 1의 주소: 1002  *(pi + 1)의 값: 2 a[2]의 주소: 1004, pi + 2의 주소: 1004  *(pi + 2)의 값: 3 a[3]의 주소: 1006, pi + 3의 주소: 1006  *(pi + 3)의 값: 4

배열과 포인터 배열과 포인터의 공통점 배열과 포인터의 차이점 array와 ptr은 주소를 나타낸다. array[index]와 *(ptr + index)는 같다. array[index]와 ptr[index]는 같다. *array 혹은 *ptr이 가능하다. *(array + index) 혹은 *(ptr + index)가 가능하다. 배열과 포인터의 차이점 배열명은 상수이고 포인터는 변수이다. 배열명에 주소를 대입할 수 없다. 배열명에는 증감 연산자(array++, array--)를 쓸 수 없다.

배열과 포인터 따라서, 아래의 표현은 모두 같은 연산을 수행한다. /* int a[N], i, *p; p = a; */ for (p = a; p < &a[N]; ++p) sum = sum + *p; ≡ for (i = 0; i < N; ++i) sum = sum + *(a + i); sum = sum + a[i]; sum = sum + p[i]; 초과된 문자가 다른 변수가 사용하고 있는 메모리에 덮어 쓸 수 있다.

다차원 배열과 포인터 배열의 정의 2차원 배열 다루기 int x[3]; /* 1차원 배열의 정의 */ int y[3][2];       /* 2차원 배열의 정의 */ int z[3][2][2];    /* 3차원 배열의 정의 */ 2차원 배열 구조

배열을 함수의 인자로 전달하는 방법 함수에 인자를 전달하기 위해 메모리의 일부인 스택(stack)을 사용 함수 정의에서 배열 인자를 선언하는 방법 배열을 함수에 전달할 때 배열의 주소가 전달되므로 함수 정의에서 이 주소를 저장하기 위한 포인터 변수를 사용.

배열을 함수의 인자로 전달하는 방법 함수 내에서 배열의 크기(또는 끝)를 알 수 있는 방법 함수의 매개변수로 배열의 시작을 가리키는 포인터와 함께 배열의 크기를 동시에 전달한다. 프로그래머가 특별히 약속된 표시를 배열의 끝에 첨가하고 이 값이 발견 되면 배열의 마지막을 나타낸다. sum1(x, 12)  배열의 주소, 배열의 크기 문자열일 경우 ‘\0’ 같은 기호 사용

배열을 함수의 인자로 전달하는 방법 1차원 배열의 전달 #include <stdio.h>                /* 배열의 크기 지정 */ double sum1(double *px, int n);    /* 포인터 관점 */ double sum2(double x[ ], int n);   /* 배열 관점 */ void main(void) {    double x[ ] = {1., 2., 3., 4., 5., 6., 7., 8., 9., 10.};      printf(“sum1=%f\n”, sum1(x, sizeof(x)/sizeof(double)));      printf(“sum2=%f\n”, sum2(x, sizeof(x)/sizeof(double))); /* 배열의 크기를 계산 */      printf(“sum1(x, 5) = %f\n”, sum1(x, 5));  /* 배열 요소 [0]-[5] */ printf(“sum1(x +5, 5) = %f\n”, sum1(x+5, 5)); /* 배열 요소 [5]-[9] */      printf(“sum2(&x[5], 5) = %f\n”, sum2(&x[5], 5)); } double sum1(double *px, int n) {    double sum = 0;      while(n --> 0)             sum += *px++;  /* 포인터 관점 */      return sum; } double sum2(double x[ ], int n) {    int  i;      double sum = 0;      for(i = 0; i < n; i++)           sum += x[i];  /* 배열 관점 */      return sum; }

포인터 배열 포인터 배열이란 포인터 변수가 배열 요소인 배열을 말한다. 포인터 배열의 선언 선언 형식 : 데이터형 *포인터 배열명[개수];

포인터 배열 2차원 문자 배열에 의한 문자 배열의 구현과 문제점 2차원 배열의 메모리 구조 포인터 배열의 메모리 구조

명령 라인 인수 명령 라인 인수는 프로그램을 실행할 때 프로그램명 다음에 전달하는데이터를 말한다. 명령 라인 인수 형식 main( ) 함수의 형식 C:\> 프로그램명 인수_1 인수_2 인수_3 .... 인수_n void main(int argc, char *argv[ ]) argc: 명령 라인 인수의 수(정수)로 프로그램명을 포함하며 적어도 1 이상이다. argv: 명령 라인 인수들에 대한 포인터 배열로 첨자 범위는 0~(argc-1) 까지이다. argv[0]: 경로까지 포함한 프로그램명을 가리킨다.       argv[1]: 프로그램명 다음의 첫 번째 인수를 가리킨다. argv[2]: 두 번째 인수를 가리킨다.

명령 라인 인수 예제 #include <stdio.h> #include <string.h> void main(int argc, char *argv[]) { if (argc == 2 ) { /* 먼저 인수의 개수가 맞는지 검사 */ if (strcmp(argv[1], "test") == 0) printf("암호가 맞습니다\n"); else { printf("암호가 틀립니다\n"); } printf("인수의 개수가 틀립니다!!"); 실행               결과 C:\> test               암호가 틀립니다. C:\> test ttt       암호가 틀립니다. C:\> test test      암호가 맞습니다. → 실행됨

명령 라인 인수 예제 #include <stdio.h> void main(int argc, char *argv[]) { int i; printf("argc = %d\n", argc); for (i = 0; i < argc; ++i) printf("argv[%d] = %s\n", i, argv[i]); } argc = 5 argv[0] = my_echo argv[1] = a argv[2] = is argv[3] = for argv[4] = apple.