11장. 포인터 01_ 포인터의 기본 02_ 포인터와 Const.

Slides:



Advertisements
Similar presentations
03 변수와 자료형 세종대학교 최옥경 교수 참고 : 한빛미디어 뇌를 자극하는 C, INFINITY Perfect C.
Advertisements

2013 년 목 차 용어의 정의 위기경보 수준 국가 생물테러 대응 체계도 반 · 팀별 소방의 임무.
YES C 제 1 장 C 언어의 개요 1/34 제 1 장 C 언어의 개요 문봉근. YES C 제 1 장 C 언어의 개요 2/34 제 1 장 C 언어의 개요 1.1 프로그램과 C 언어의 특징 1.2 C 언어의 프로그램 구성 1.3 비주얼 C++ 통합 환경 들어가기.
제 3 장 변수와 자료형.
제 11 장 구조체.
컴퓨터 응용 및 실습 Part1. OOP&Java Programming data type Review
C++ Espresso 제3장 배열과 포인터.
C++ Espresso 제3장 배열과 포인터.
C++ Espresso 제1장 기초 사항.
쉽게 풀어쓴 C언어 Express 제11장 포인터 C Express.
쉽게 풀어쓴 C언어 Express 제13장 구조체 C Express Slide 1 (of 25)
컬러 LED바 이해하기 목차 재료준비 및 브레드 보드 배선 구성하기 컬러 LED바 이해 및 프로그램 실습 응용 작품 만들기.
강좌명 : C++프로그래밍 (C++ Programming)
C로 쉽게 풀어쓴 자료구조 © Copyright 생능출판사 2011
C로 쉽게 풀어쓴 자료구조 © Copyright 생능출판사 2005
제 2 장 배열과 스트링.
구조체 활용 구조체 활용.
쉽게 풀어쓴 C언어 Express 제13장 구조체 C Express.
쉽게 풀어쓴 C언어 Express 제13장 구조체 C Express.
제 6 장 데이터 타입 6.1 데이터 타입 및 타입 정보 6.2 타입의 용도 6.3 타입 구성자 6.4 사례 연구
8. 객체와 클래스 (기본).
C++ 프로그래밍 년 2학기 전자정보공학대학 컴퓨터공학부.
2강. JAVA 프로그래밍이란?-II & 변수 JAVA 프로그램 환경설정과 실행 방법 변수란?
11장 구조체와 열거형 구조체의 정의 구조체 변수의 선언 구조체 초기화 및 사용 구조체 재정의 포인터를 이용해서 구조체 사용
제3장 추가 실습 3장 관련 C 언어 프로그래밍 실습.
C 11장. 포인터의 활용 #include <stdio.h> int main(void) { int num;
Chapter 03 배열, 구조체, 포인터.
구조체 struct 구조체와 함수 구조체의 배열, sizeof 연산자 열거형 enum 형 정의 typedef
쉽게 풀어쓴 C언어 Express 제4장 변수와 자료형 C Express.
CHAP 3:배열, 구조체, 포인터.
자료 구조: Chapter 3 (2)구조체, 포인터
C 9장. 구조체 #include <stdio.h> int main(void) { int num;
C++ 프로그래밍 년 2학기 전자정보공학대학 컴퓨터공학부.
14장. 함수 1 01_ 함수의 기본 02_ 인자의 전달.
C++ 프로그래밍 년 2학기 전자정보공학대학 컴퓨터공학부.
Chapter 05. 클래스 완성. chapter 05. 클래스 완성 01. 복사 생성자 복사 생성(Copy Construction) 생성될 때 자신과 같은 타입의 객체를 변수로 받아, 이 객체와 같은 값을 갖는 새로운 객체를 생성하는 것 명시적인 생성 과정뿐만.
C 프로그래밍.
11장. 포인터 01_ 포인터의 기본 02_ 포인터와 Const.
제 2 장 변수와 상수.
프로그래밍2 및 실습 C언어 기반의 C++ 2.
제 3 장 상수와 변수
임베디드 시스템을 위한 C프로그래밍 기법 3.7 ~ 4.5 장 Raphael.
쉽게 풀어쓴 C언어 Express 제4장 변수와 자료형 C Express.
5장. 상수와 기본 자료형. 5장. 상수와 기본 자료형 5-1 C 언어가 제공하는 기본 자료형 자료형(data type) 기본 자료형 사용자 정의 자료형 int val; "선언할 변수의 특징을 나타내기 위한 키워드" 기본 자료형 기본적으로 제공이 되는 자료형 사용자.
쉽게 풀어쓴 C언어 Express 제4장 변수와 자료형 C Express.
23강 API - II - 약방의 감초 Random 클래스 - Scanner 및 Sysout - Wrapper 클래스의 이해
adopted from KNK C Programming : A Modern Approach
Arrays 요약.
컴퓨터의 기초 제 2강 - 변수와 자료형 , 연산자 2006년 3월 27일.
타입, 연산자 Chapter 5, 6 Kum Deuk Kyu , Ph. D. Spring 2015
Java의 정석 제 2 장 변수(Variable) Java 정석 남궁성 강의
제 12장. 사용자 정의형으로서의 클래스 학기 프로그래밍언어및실습 (C++).
프로그래밍 원리 Chapter 04 자료 처리와 연산자 신한대학교 IT융합공학부 박 호 균.
3장. 변수와 연산자. 3장. 변수와 연산자 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, / 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, /
4장 자료형.
포인터.
2 배열과 구조.
03. 메모리 관리 C++ 프로그램에서 다룰 수 있는 메모리의 종류
자바 5.0 프로그래밍.
빛 의 합 성 과 학 1 학년 Ⅱ. 빛 > 2. 빛의 색( 8/8 ) [초기 화면]
포인터와 배열 조 병 규 한 국 교 통 대 학 교 SQ Lab..
토론을 위한 질문 배열의 이름에는 무엇이 저장되는가? C언어에서 배열 추상데이터의 store는 어떻게 구현 되는가?
제 8장. 클래스의 활용 학기 프로그래밍언어및실습 (C++).
혼색 color mixture.
컴퓨터 프로그래밍 기초 - 11th : 파일 입출력 및 구조체 -
[색채지각 ] Color Perception.
박성진 컴퓨터 프로그래밍 기초 [03] 변수와 자료형 박성진
개정판 누구나 즐기는 C언어 콘서트 제11장 구조체, 공용체, 열거형 출처: pixabay.
printf("Global Korea\n");
윤성우의 열혈 C++ 프로그래밍 윤성우 저 열혈강의 C++ 프로그래밍 개정판 Chapter 02. C언어 기반의 C++ 2.
Presentation transcript:

11장. 포인터 01_ 포인터의 기본 02_ 포인터와 Const

포인터의 개념 포인터 변수는 다른 변수를 가리키는 변수다. 포인터 변수에는 다른 변수의 주소 값을 저장할 수 있다. 예를 들어서 포인터 변수 A가 다른 변수 B의 주소 값을 보관하고 있다면, 포인터 변수 A가 변수 B를 가리키고 있다고 말한다.

변수의 주소 변수의 주소란 변수가 포함하고 있는 제일 첫번째 바이트의 주소를 말한다. 예를 들어서 int 타입의 변수 a가 있다고 하면, 변수 a는 4바이트의 메모리 공간을 소유하게 된다. 메모리의 각 바이트 마다 주소가 있다. 그 중에서 첫번째 바이트의 주소를 변수 a의 주소라고 말한다.

포인터 변수에 변수의 주소를 보관하기 포인터 변수 p가 변수 a를 가리키도록 만드는 예 실행 결과 // 일반적인 변수를 정의한다. int a = 123; // 포인터 변수를 정의한다. int* p; // p가 a를 가리키도록 만든다. p = &a; // 관련 정보를 출력한다. cout << "&a = " << &a << "\n"; cout << "p = " << p << "\n"; cout << "&p = " << &p << "\n";

포인터 변수의 정의 포인터 변수를 정의할 때는 가리키고자 하는 변수의 타입을 지정해 두어야 한다. 다양한 타입의 포인터 변수 char c = 'C'; char* pc = &c; float f = 700.5f; float* pf = &f; bool b = true; bool* pb = &b; short int s = 456; short int* ps = &s;

가리킬 타입을 지정해야 하는 이유 메모리에는 타입에 대한 정보가 보관되지 않는다. 그러므로, 포인터 변수의 타입을 통해서 데이타의 크기나 종류를 알아낸다.

void 포인터 void* 타입의 포인터 변수는 어떤 타입의 변수라도 가리킬 수 있다. void* p;

주소를 사용해서 정보에 접근하기 포인터 변수가 가리키는 변수에 접근하는 예 실행 결과 // p가 a를 가리키도록 만든다. int a = 123; int* p = &a; // p가 가리키는 변수의 값을 얻는다. cout << "*p = " << *p << "\n"; // p가 가리키는 변수의 값을 변경한다. *p = 789; // 관련 정보를 출력한다. cout << "a = " << a << "\n";

포인터 안전하게 사용하기 잘못된 주소를 가진 포인터를 사용하는 것은 매우 위험하기 때문에, 포인터를 사용할 때는 다음의 가이드 라인을 따른다. 포인터 변수는 항상 0 혹은 NULL 값으로 초기화 한다. 포인터 변수를 사용하기 전에는 0 혹은 NULL 값을 가지고 있는지 확인한다. // 포인터 변수를 정의하고 초기화한다. int* p = NULL; // 이 상태에서 포인터를 사용해보자. if (NULL != p) *p = 30; // p가 변수를 가리키게 만들자 int a = 100; p = &a; if (!p)

Const 속성을 가진 변수 변수의 값이 변경되는 것을 막기위해서 Const 속성을 사용해서 변수를 정의할 수 있다. const int a = 123; // a의 값을 바꾸려고 했으므로 컴파일 에러 발생!! a = 456; // 배열의 크기를 const 변수에 보관한다. const unsigned int arraySize = 100; // 배열을 정의한다. char characters[ arraySize ] = {0}; // 배열을 사용한다. for (int i = 0; i < arraySize; ++i) characters[i] = i + 1;

Const 와 포인터 (1) 포인터 변수에 Const 속성을 부여할 때는 다음의 두 변수를 고려할 수 있다. 포인터 변수 자체 포인터 변수가 가리키는 변수

Const 와 포인터 (2) 포인터 변수에 Const 속성을 적용한 3가지 경우를 비교해보자. int i1 = 10; int i2 = 20; const int* p = &i1; p = &i2; // OK *p = 30; // FAIL int i1 = 10; int i2 = 20; int* const p = &i1; p = &i2; // FAIL *p = 30; // OK int i1 = 10; int i2 = 20; const int* const p = &i1; p = &i2; // FAIL *p = 30; // FAIL

01_ 포인터의 기본 02_ 포인터와 Const 03_ 포인터와 구조체 12장. 배열과 구조체와 포인터 01_ 포인터의 기본 02_ 포인터와 Const 03_ 포인터와 구조체

배열의 원소를 가리키는 포인터 포인터 변수를 사용해서 배열의 원소를 가리키는 예 int arrays[10]; int* p = &arryays[5]; [그림 12-1]

포인터 변수에 정수를 더하기 i 번째 원소를 가리키는 포인터 변수에 정수 n을 더하면 포인터 변수는 i + n 번째 원소를 가리키게 된다. 실행 결과 int array[10]; // 포인터가 array[5]를 가리키도록 만든다. int* p = &array[5]; cout << "p = " << p << "\n"; cout << "&array[5] = " << &array[5] << "\n"; // 포인터가 array[6]을 가리키도록 만든다. p++; cout << "&array[6] = " << &array[6] << "\n"; [그림 12-3] [그림 12-2]

포인터 변수간의 뺄셈 i 번째 원소를 가리키는 포인터 변수에서 j번째 원소를 가리키는 포인터 변수를 빼면 결과는 i-j 가 된다. 실행 결과 short sArrays[10]; short* ps1 = &sArrays[3]; short* ps2 = &sArrays[7]; // 결과를 출력한다. cout << "ps1 = " << ps1 << "\n"; cout << "ps2 = " << ps2 << "\n"; cout << "ps2 - ps1 = " << ps2 - ps1 << "\n"; [그림 12-6] [그림 12-5]

포인터를 사용한 원소의 탐색 일반적인 방법을 사용한 원소의 탐색 포인터를 사용한 원소의 탐색 int nArray[10]; // 배열을 탐색하면서 값을 넣는다. for (int i = 0; i < 10; ++i) nArray[i] = i; int nArray[10]; int* p = &nArray[0]; // 배열을 탐색하면서 값을 넣는다. for (int i = 0; i < 10; ++i) *(p + i) = i;

배열의 이름 배열의 이름은 첫번째 원소의 주소가 된다. 배열의 이름을 사용해서 배열을 탐색하는 예 float f[5]; if ( f == &f[0] ) { // 항상 이곳이 실행된다. } int nArray[10]; // 배열을 탐색하면서 값을 넣는다. for (int i = 0; i < 10; ++i) *(nArray + i) = i;

배열을 가리키는 포인터 배열의 원소가 아닌 배열 전체를 포인터 변수로 가리키는 예 실행 결과 long lArray[20]; // 포인터가 이 배열을 가리키게 만들자 long (*p)[20] = &lArray; // 포인터를 통해서 배열을 사용하자. (*p)[3] = 300; // 결과를 확인하자 cout << "lArray[3] = " << lArray[3] << "\n"; [그림 12-7]

연산자 우선순위 배열을 가리키는 포인터 변수의 정의 배열을 가리키는 포인터 변수의 사용 [그림 12-8] [그림 12-9]

포인터의 배열 포인터 변수의 배열을 정의하는 예 // 참조될 변수들을 정의한다. double a, b, c; // 3개의 원소를 가진 포인터의 배열을 정의한다. double* pArray[3]; // 각 원소가 변수들을 가리키도록 만든다. pArray[0] = &a; pArray[1] = &b; pArray[2] = &c;

배열을 포함하는 구조체 배열을 멤버로 갖는 구조체의 예 실행 결과 struct StudentInfo { char name[20]; // 이름 int stdNumber; // 학번 float grade[2]; // 최근 2학기 평점 }; StudentInfo si = { "Kim Chol-Su", 200121233, {3.2f, 3.5f} }; cout << si.name << "\n"; cout << si.stdNumber << "\n"; cout << si.grade[0] << ", " << si.grade[1] << "\n"; [그림 12-11]

구조체의 배열 구조체 변수의 배열을 정의하는 예 struct StudentInfo { char name[20]; // 이름 int stdNumber; // 학번 float grade[2]; // 최근 2학기 평점 }; StudentInfo stdInfos[5] = { { "Kim Chol-Su", 200121233, {3.2f, 3.5f} }, { "Lee Chol-Su", 200223517, {4.5f, 4.5f} }, { "Park Chol-Su", 200321131, {1.7f, 2.0f} }, { "Yang Chol-Su", 200222289, {0.4f, 4.1f} }, { "Yoon Chol-Su", 199921444, {2.7f, 2.8f} } [그림 12-14]

구조체를 가리키는 포인터 구조체 변수를 가리키는 포인터를 정의하는 예 실행 결과 struct Rectangle { int x, y; int width, height; }; Rectangle rc = { 100, 100, 50, 50}; // 포인터가 이 변수를 가리키게 만든다. Rectangle* p = &rc; // 구조체의 멤버에 접근한다. (*p).x = 200; p->y = 250; cout << "rc = ( " << rc.x << ", " << rc.y << ", "; cout << rc.width << ", " << rc.height << ")\n"; [그림 12-15]

포인터를 포함하는 구조체 포인터 변수를 멤버로 갖는 구조체를 정의하는 예 실행 결과 struct Dizzy { int id; // 구조체 변수마다 갖는 고유한 값 Dizzy* p; // Dizzy 구조체를 가리키는 포인터 }; // Dizzy 객체를 3개 만들고, 서로를 가리키도록 만든다. Dizzy a, b, c; a.id = 1; a.p = &b; b.id = 2; b.p = &c; c.id = 3; c.p = &a; // a 만 사용해서 a, b, c 모두에 접근한다. cout << "a.id = " << a.id << "\n"; cout << "b.id = " << a.p->id << "\n"; cout << "c.id = " << a.p->p->id << "\n"; cout << "a.id = " << a.p->p->p->id << "(again)\n"; [그림 12-17] [그림 12-16] 그림 넣을 공간이 부족하기는 하지만 잘 맞춰서 넣어봐.. ㅎㅎ

01_ 나머지 복합 타입들 02_ 배열, 구조체, 포인터의 나머지 기능 13장. 복합 타입의 모든 것 01_ 나머지 복합 타입들 02_ 배열, 구조체, 포인터의 나머지 기능

공용체(Unions) 공용체의 모든 멤버는 같은 메모리 공간을 공유한다. union ManyMembers { char c; short s; int i; float f; double d; }; [그림 13-3]

공용체의 사용 공용체의 멤버가 같은 공간을 공유한다는 점을 확인하는 예 실행 결과 union MyUnion { int i; void* p; }; MyUnion uni; cout << "&uni.i = " << &uni.i << "\n"; cout << "&uni.p = " << &uni.p << "\n"; uni.i = 0x12345678; cout << hex; cout << "uni.i = " << uni.i << "\n"; cout << "uni.p = " << uni.p << "\n"; uni.p = (void*)0x87654321; [그림 13-2]

열거체(Enumerations) 열거체를 사용해서 상수값에 대한 심볼을 정의하는 예 enum JOB_KINDS { JOB_DWARF, JOB_WARRIOR, JOB_SORCERER }; struct Character { JOB_KINDS jobType; // 다른 멤버들이 더 있다. }; Character c; // c 가 누군가에 의해 초기화 된다. // c가 마법사인 경우 if (JOB_SORCERER == c.jobType) // 필요한 일을 한다. }

열거체와 심볼의 값 열거체의 심볼들은 자동적으로 0 기반의 인덱스 값을 갖는다. = 열겨체의 심볼에 값을 대입한 경우, 뒤쪽의 심볼들은 해당 값을 기반으로 증가한다. enum { JOB_DWARD, JOB_WARRIOR, JOB_SORCERER }; = enum { JOB_DWARD = 0, JOB_WARRIOR = 1, JOB_SORCERER = 2}; enum { JOB_DWARD, JOB_WARRIOR = 3, JOB_SORCERER }; = enum { JOB_DWARD, JOB_WARRIOR = 3, JOB_SORCERER = 4};

열거체와 정수 타입 열거체를 사용해서 산술 연산을 할 수 없다. 정수를 열거체 변수에 대입할 수 없다. 열거체의 심볼들은 암시적으로 정수 타입으로 형변환 된다. 명시적인 형변환을 사용해서 정수 타입의 값을 열거체 변수에 담을 수 있다. enum Color { RED, BLUE, GREEN, SKYBLUE, MAGENTA, YELLOW }; Color color1 = RED; color1 = SKYBLUE + YELLOW; // Error Color1 += 3; // Error Color color2; color2 = 5; // Error int n = MAGENTA; // n 은 4가 된다. int m = BLUE + 2; // m 은 3이 된다. Color color3 = (Color)2 // color3은 GREEN이 된다. Color color4 = (Color)5000 // 결과를 알 수 없다.

레퍼런스(References) 레퍼런스 변수를 사용해서 변수의 별칭을 만드는 예 int target = 20; // 레퍼런스 변수를 정의한다. int& ref = target; cout << "ref = " << ref << "\n"; cout << "target = " << target << "\n"; cout << "&ref = " << &ref << "\n"; cout << "&target = " << &target << "\n"; // ref의 값을 바꿔보자. ref = 100; [그림 13-4]

레퍼런스 변수의 초기화 레퍼런스 변수의 초기화와 대입은 다른 의미를 갖는다. // 변수를 정의한다. float a = 100.0f; float b = 12.34f; // r을 a에 대한 별명으로 만든다. (초기화) float& r = a; // r에 200.0f를 대입한다. (대입) r = 200.0f; // r에 b의 값 12.34f를 대입한다. (대입) r = b; // r에 56.7f를 대입한다. (대입) r = 56.7f

레퍼런스 변수와 Const Const 속성을 가진 레퍼런스 변수만 상수로 초기화할 수 있다. const int& rci = 100; // OK int& ci = 100; // Error [그림 13-7] char c = ‘A’; const int& rci = c; // OK int& ci = c; // Error [그림 13-8]

typedef typedef를 사용해서 타입의 별칭의 만드는 예 typedef unsigned char* uc_ptr; unsigned char uc = ‘A’; uc_ptr p = &uc; [그림 13-9]

비트 필드(Bit Fields) 구조체의 멤버 변수들이 차지하는 비트 수를 지정하는 예 struct Flags { int a : 3; int b : 4; int : 5; // 이 5비트는 쓰지 않는다. bool c : 1; }; [그림 13-11]

구조체를 포함하는 구조체 구조체 변수를 멤버로 갖는 구조체를 정의하는 예 struct A { int i; float f; }; struct B char c; A a; [그림 13-14]

다차원 배열 다차원 배열 (= 배열의 배열)을 정의하는 예 좌측의 그림은 이해하기 편하게 그린 것이고, 우측의 그림은 실제로 다차원 배열이 메모리에 자리잡는 모습을 그린 것이다. int arr[10][5]; // 배열의 모든 원소에 10을 대입한다. for ( int i = 0; i < 10; ++i ) { for ( int j = 0; j < 5; ++j ) arr[i][j] = 10; } [그림 13-15] [그림 13-16]

포인터를 가리키는 포인터 포인터 변수를 가리키는 포인터 변수를 정의하는 예 char c = ‘1’; char* pc = &c; char** ppc = &pc; if ( *ppc == pc ) { // 이곳은 항상 실행된다. } if ( **ppc == c ) [그림 13-17]