Download presentation
Presentation is loading. Please wait.
1
Chapter 09. 포인터 1
3
01 포인터의 개요 02 포인터의 선언과 사용 03 포인터를 통한 배열의 사용 04 포인터 연산 05 포인터를 통한 문자열의 사용
4
01. 포인터의 개요 C 언어를 공부하면서 가장 어려운 부분 : 포인터pointer
포인터를 설명하기 위해서 이해해야 하는 부분 변수 주소의 개념과 주소 연산자 포인터 변수와 포인터 변수를 통한 간접 참조 연산자
5
01. 포인터의 개요 – 1.1 변수의 주소와 주소 연산자 & 변수에 저장된 값의 출력 : 실제로 컴퓨터에서 어떻게 실행?
C 언어는 컴파일러 언어이므로 위 프로그램은 기계어로 번역되어 실행 파일(*.exe)로 저장 프로그램은 로더loader 에 의해 실행 파일이 메모리에 적재되면서 실행 메모리에 적재된 프로그램이 어떻게 실행될까요? : 복잡한 과정이지만 간단하게 표현하면, 모든 변수는 컴파일 러에 의해 생성되는 심벌 테이블에 저장되고 심벌 테이블에는 변수명과 메모리의 주소(값이 저장된 주소)가 저 장 프로그램이 실행될 때 모든 변수는 심벌 테이블에 있는 주소에 의해 접근
6
01. 포인터의 개요 – 1.1 변수의 주소와 주소 연산자 & 변수에 저장된 값의 출력 : 실제로 컴퓨터에서 어떻게 실행?
7
01. 포인터의 개요 – 1.1 변수의 주소와 주소 연산자 & 변수가 저장된 메모리의 주소를 나타내는 연산자 : &
예제 9-1 %p는 32비트의 주소를 16진수 여덟 자리로 표시하는 형식 지정자 이 프로그램을 실행할 때마다 max의 주소 값이 다르게 출력되는데, 이는 프로그램이 실행될 때마다 운영체제가 프로그램을 서로 다른 위치에 로드하기 때문
8
01. 포인터의 개요 – 1.2 포인터 변수와 간접 참조 연산자 *
01. 포인터의 개요 – 1.2 포인터 변수와 간접 참조 연산자 * 포인터 변수 : 주소 연산자 &가 반환한 주소를 저장할 수 있는 특수한 변수 C 언어에서는 변수의 주소를 포인터라는 변수에서 직접 사용하는 것을 허용 기본적으로 포인터 변수도 일반 변수와 같은 개념이지만, 저장할 수 있는 값이 일반 데이터가 아니라 반드시 주소이다 포인터 변수에 일반 데이터의 저장을 시도하면 컴파일러에 의해 오류가 발생(단 정수형의 값은 배정 가능) 포인터 변수도 일반 변수와 같이 선언 하고 사용 포인터 변수는 이름 앞에 간접 참조 연산자indirection operator인 * 를 붙여 선언
9
01. 포인터의 개요 – 1.2 포인터 변수와 간접 참조 연산자 *
01. 포인터의 개요 – 1.2 포인터 변수와 간접 참조 연산자 * 예제 9-2 : 예제 9-1을 변환
10
01. 포인터의 개요 – 1.2 포인터 변수와 간접 참조 연산자 *
01. 포인터의 개요 – 1.2 포인터 변수와 간접 참조 연산자 * pmax = &max; 포인터 변수 pmax가 변수 max(사실은 max 값이 들어 있는 위치)를 가리킨다 *pmax 간접 참조 연산자 * 는 포인터 변수가 가리키는 변숫값을 의미 위와 같은 경우 *pmax는 max와 같고, pmax는 &max와 같다 간접 참조 연산자는 일반 변수에는 사용할 수 없으며, 만약 사용하면 컴파일러에 의해 오류가 발생
11
01. 포인터의 개요 – 1.2 포인터 변수와 간접 참조 연산자 *
01. 포인터의 개요 – 1.2 포인터 변수와 간접 참조 연산자 * 예제 9-3 : 예제 9-2의 변형 pmax = &max 이면 *pmax = max이다
12
01. 포인터의 개요 – 1.2 포인터 변수와 간접 참조 연산자 *
01. 포인터의 개요 – 1.2 포인터 변수와 간접 참조 연산자 * *pmax : 포인터 변수의 값은 메모리에 두 번 접근하여 값을 가져온다. 우선 포인터 변수의 값(가리키는 변수의 주소)을 가져온 다음, 그 값을 주소로 하여 다시 메모리에 접근하여 값 을 가져온다.
13
01. 포인터의 개요 – 1.2 포인터 변수와 간접 참조 연산자 *
01. 포인터의 개요 – 1.2 포인터 변수와 간접 참조 연산자 * 포인터의 사용 많은 개발자들이 처음 C 언어를 배울 때 포인터의 개념, 포인터와 관련된 형 변환, 포인터 배열의 사용 등을 어려워합니다. 최근 대부분의 프로그래밍 언어(자바 등)는 이러한 포인터의 개념을 개발자가 직접 다루지 못 하게 하고 있습니다(자바 언어는 포인터의 개념이 없습니다). 자바 같은 언어에는 포인터의 개념이 없기 때문 에 C 언어보다 배우기 쉽다고도 합니다. 그러나 포인터를 사용함으로써 메모리를 직접 제어할 수 있고, 효율 적인 자료 구조를 쉽게 사용할 수 있다는 것이 장점입니다. 메모리의 직접적인 제어는 하드웨어를 직접 제어 하는 시스템 및 네트워크 프로그래밍에서 큰 강점입니다. 결론적으로 포인터를 사용하는 것은 프로그래머의 몫입니다. 포인터를 완벽하게 이해하여 정확하게 구사한다면 효율적인 프로그래밍이 가능하지만, 불완전하 게 구사한다면 프로그램을 더욱 복잡하고 난해하게 만드는 요인이 될 것입니다.
14
02. 포인터의 선언과 사용 포인터 관련 연산자의 이해 & 연산자 : 뒤에 오는 변수의 값이 저장된 메모리의 주소를 반환
* 연산자 : 뒤에 오는 포인터 변수가 가리키는 변수의 값을 반환
15
02. 포인터의 선언과 사용 – 2.1 포인터 변수의 선언과 초기화
02. 포인터의 선언과 사용 – 2.1 포인터 변수의 선언과 초기화 포인터 변수는 주소를 저장하는 변수 일반 변수의 주소, 배열 주소, 함수 주소 등도 포인터 변수에 배정할 수 있다 포인터 변수의 선언 자료형은 포인터 변수가 가리키는 변수의 형식을 의미 포인터 변수는 선언만으로 값(주소)을 배정받을 수 없으며, & 연산자를 사용하여 변수의 주소로 초기화하든지 NULL(<stdio.h>에 0으로 선언된 상수) 값으로 초기화한 뒤에 사용.
16
02. 포인터의 선언과 사용 – 2.1 포인터 변수의 선언과 초기화
02. 포인터의 선언과 사용 – 2.1 포인터 변수의 선언과 초기화 포인터 변수의 선언과 초기화의 예 01 int num =100, *ipoint; 02 char c ='a', *cpoint; 가지 형의 변수와 포인터 변수 선언 03 double d = , *dpoint; 04 ipoint = # ipoint의 값으로 num의 주소 배정 05 *ipoint = # ipoint가 가리키는 변수의 값에 num의 주소 저장 06 ipoint = NULL; ipoint의 값을 NULL(0)로 초기화 07 *ipoint = NULL; ipoint가 가리키는 변수의 값을 NULL(0)로 변경 08 cpoint = &c; cpoint의 값으로 c의 주소 배정 09 cpoint = # char형의 포인터 변수에 int 값의 주소 배정 10 *cpoint = c; cpoint가 가리키는 변수의 값을 변수 c가 가진 값으로 변경 11 *dpoint = d * 3.2; dpoint가 가리키는 변수의 값을 (d*3.2) 값으로 변경 05번과 09번 라인에서 오류 발생 안 됨(교재 수정 요망) 05번 설명 : 변수의 형에 상관없이 주소 값은 4바이트로 구성된 정수 값이므로, 정수(int) 변수의 값으로 배정 가능. 반대의 경우 는 불가능 int num=100; double d=3.14, *dd; dd=&d; *dd = &d; // 오류 발생. 정수 값을 double에 배정할 수 없음. 09번 설명 : 포인터 변수는 4바이트로 구성된 정수 변수이므로, 어떠한 형의 주소라도 배정이 가능.
17
02. 포인터의 선언과 사용 – 2.1 포인터 변수의 선언과 초기화
02. 포인터의 선언과 사용 – 2.1 포인터 변수의 선언과 초기화 예제 9-4
18
02. 포인터의 선언과 사용 – 2.2 포인터 변수의 사용 일반 변수의 사용과 포인터 변수의 사용
02. 포인터의 선언과 사용 – 2.2 포인터 변수의 사용 일반 변수의 사용과 포인터 변수의 사용 위의 예에서 일반 변수 c와 포인터 변수 *cp는 같은 값을 출력하지만 실제 메모리에서 동작하는 방법은 다르다 일반 변수는 메모리에 한 번 접근해서 값을 가져오는 반면, 포인터 변수는 메모리에 두 번 접근해야 값을 가져 온다. 포인터 변수를 이용하여 메모리에 두 번 접근해서 값을 가져오는 방법을 간접 참조indirection 라고 함
19
02. 포인터의 선언과 사용 – 2.2 포인터 변수의 사용 일반 변수의 사용과 포인터 변수의 사용
20
02. 포인터의 선언과 사용 – 2.2 포인터 변수의 사용 포인터 변수에 저장된 변수에 배정된 주소 값의 변경
02. 포인터의 선언과 사용 – 2.2 포인터 변수의 사용 포인터 변수에 저장된 변수에 배정된 주소 값의 변경 01 int max =100, min =0, *pmaxmin; 02 double pi =3.14; 03 pmaxmin =&max; 포인터 변수 초기화 04 printf("pmaxmin의 값 : %d\n", *pmaxmin); 출력 05 pmaxmin =&min; 포인터 변수를 같은 형의 다른 주소 값으로 변경 06 printf("pmaxmin의 값 : %d\n", *pmaxmin); 출력 07 pmaxmin =π 다른 형의 주소 값으로 변경 가능하지만, 이 경우 포인터 --- 변수 *pmaxmin을 통해서는 예상치 못한 값이 출력됨 07 라인에서 오류 발생 안 됨(교재 수정 요망) 설명 : 포인터 변수의 주소 값에는 어떠한 형의 주소라도 배정 가능. 단 04번, 06번 라인의 경우 동일한 형이기 때문에 정확한 값이 출력되지만, 동일한 형이 아닐 경우 예상치 못한 값이 출력된다. 예를 들어 위의 예제에 08번 라인을 다음과 같이 추가하면 08 printf("pmaxmin의 값 : %d\n", *pmaxmin); -- 예상치 못한 “ ”가 출력됨 그 이유는 배정된 주소는 double 값이지만, int 형의 포인터 변수는 그 주소로부터 4바이트만 읽어 들여 정수로 인식하기 때문이다.
21
02. 포인터의 선언과 사용 – 2.2 포인터 변수의 사용 일반 변수와 포인터 변수의 값 변경
22
02. 포인터의 선언과 사용 – 2.2 포인터 변수의 사용 예제 9-5 05번 int i, *ip = &i는
02. 포인터의 선언과 사용 – 2.2 포인터 변수의 사용 예제 9-5 05번 int i, *ip = &i는 int i, *ip; ip = &i 와 같은 의미
23
02. 포인터의 선언과 사용 – 2.3 다중 포인터 변수의 사용
02. 포인터의 선언과 사용 – 2.3 다중 포인터 변수의 사용 C에서 포인터 변수의 주소를 또 다른 포인터 변수에 배정하는 것이 가능하며 이 과정이 계속 순환될 수 있다. 이러한 변수를 다중 포인터 변수라고 한다.
24
02. 포인터의 선언과 사용 – 2.3 다중 포인터 변수의 사용
02. 포인터의 선언과 사용 – 2.3 다중 포인터 변수의 사용 모두 10을 출력하는 다중 포인터 변수
25
02. 포인터의 선언과 사용 – 2.3 다중 포인터 변수의 사용
02. 포인터의 선언과 사용 – 2.3 다중 포인터 변수의 사용
26
02. 포인터의 선언과 사용 – 2.3 다중 포인터 변수의 사용
02. 포인터의 선언과 사용 – 2.3 다중 포인터 변수의 사용 예제 9-6
27
02. 포인터의 선언과 사용 – 2.3 다중 포인터 변수의 사용
02. 포인터의 선언과 사용 – 2.3 다중 포인터 변수의 사용 예제 9-6
28
02. 포인터의 선언과 사용 – 2.3 다중 포인터 변수의 사용
02. 포인터의 선언과 사용 – 2.3 다중 포인터 변수의 사용 포인터 변수는 값을 가져오기 위해 메모리에 두 번 접근해야 하므로 일반 변수를 사용하는 것보다는 효율성이 떨어짐. 그럼에도 불구하고 포인터 변수를 사용하는 이유 배열과 문자열의 조작에 포인터를 사용함으로써 간결하고 효율적인 처리가 가능 복잡한 자료 구조(배열, 구조체, 공용체)와 함수에 포인터를 사용하여 쉽게 접근 배열을 사용할 때 배열의 첨자보다 포인터를 사용하는 것이 더 빨리 처리 동적 자료의 처리나 순환 자료 구조의 표현, 참조에 의한 호출 등에는 포인터를 사용 포인터 변수 사용의 문제점 포인터 변수를 과다하게 사용하면 오류를 범하거나 스파게티 형태의 복잡한 프로그램 구조가 된다 포인터 변수를 많이 사용하여 작성한 프로그램은 유지·보수가 어렵다 포인터를 잘못 사용하여 메모리의 절대 번지에 접근(운영체제 영역에 접근)하는 경우 심각한 시스템 오류 발생
29
03. 포인터를 통한 배열의 사용 배열과 포인터 배열의 이름과 포인터 변수
배열을 제어할 때 배열의 첨자보다는 포인터를 사용하는 것이 더 효율적 배열은 모든 요소가 메모리의 연속된 기억 공간에 저장 배열의 이름은 포인터 변수와 같은 역할(배열의 이름은 그 배열의 첫 번째 요소를 가리키는 포인터) 배열의 이름은 배열 첫 번째 요소의 주소 상숫값을 가집니다. 배열의 이름과 포인터 변수 배열의 이름은 포인터 변수와 같은 역할을 하므로 포인터 변수 대신 직접 사용 가능 포인터 변수를 선언하고 배열의 이름으로 초기화를 수행하여 사용하는 것도 가능 두 방법의 차이 배열의 이름을 나타내는 변수는 기억 장소에 저장되지 않는다 별도의 포인터 변수를 선언하여 사용하는 것은 포인터 변수 자체가 메모리에 저장
30
03. 포인터를 통한 배열의 사용 배열과 포인터 변수의 사용 예
포인터 변숫값(*pscore)에 1을 더하는 것과, 포인터 변수(pscore)에 1을 더하는 것은 차이가 있다 포인터 변수에 1을 더하면, 해당되는 형의 크기만큼 주소 값이 가 증가한다.
31
03. 포인터를 통한 배열의 사용
32
03. 포인터를 통한 배열의 사용 예제 9-7
33
03. 포인터를 통한 배열의 사용 예제 9-7
34
03. 포인터를 통한 배열의 사용 예제 9-8
35
03. 포인터를 통한 배열의 사용 예제 9-8 계속
36
04. 포인터 연산 포인터 연산 : 포인터 변수 자체에 적용할 수 있는 연산 포인터 변수 자체에 대해서는 제한적 연산만 허용
배정 연산 간접 참조 연산 주소 연산 증감 및 정수 산술(덧셈과 뺄셈만 가능) 연산
37
04. 포인터 연산 일반 변수를 가리키는 포인터 변수에 증감 연산을 잘 못 수행하면 위의 예와 같이 예측 불가능한 값이 나타난다
38
04. 포인터 연산 배열을 가리키는 포인터 변수는 증감 연산을 수행할 때 배열의 범위를 벗어나지 않도록 주의해서 사용
배열 포인터 변수 간의 뺄셈은 배열에서 요소의 상대적인 위치를 구하는 데 사용
39
04. 포인터 연산 예제 9-9
40
05. 포인터를 통한 문자열의 사용 문자열을 사용하기 위해 문자 배열을 사용하는 방법(7장)과 문자열 포인터를 사용하는 방법이 있다. 두 방법의 차이
41
05. 포인터를 통한 문자열의 사용 문자 배열을 포인터 변수에 저장하여 사용하는 경우와 문자열 포인터를 직접 생성하여 사용하는 예 문자 배열이나 문자열 포인터도 일반 배열처럼 포인터를 사용하여 처리 가능 포인터 변수에 포인터 연산을 적용하여 문자 단위로 출력 가능.
42
05. 포인터를 통한 문자열의 사용 문자 배열을 통해 포인터 변수를 사용하는 것과 문자열 포인터를 직접 생성하여 사용하는 것의 차이 문자 배열을 포인터 변수에 저장하면 포인터 변수를 통해(첨자 사용) 문자 단위로 배열의 각 요소에 접근 가능 문자열 포인터로 직접 생성하면 첨자를 사용하여 문자열의 각 문자에 접근 불가능 문자 배열을 통해 포인터 변수를 사용하는 예
43
05. 포인터를 통한 문자열의 사용 문자열 포인터를 생성하여 사용하는 예 02번과 04번에서 실행시간 오류가 발생
Similar presentations