Upload
hoyoung-jung
View
1.203
Download
1
Embed Size (px)
DESCRIPTION
C언어 포인터의 기초 첫번째 슬라이드입니다.
Citation preview
C 언어와 포인터 (1)
포인터의 기초
"완전학습을 지향하는" NHN NEXT 정호영
나눔고딕 및 나눔고딕코딩 글꼴을 설치해 주세요 .
쉽게
씌어진
시
창밖에
밤비가
속살거려
육첩방은
남의
나라
.시인이란
슬픈
천명인
줄
알면서도
한
줄 시를
적어볼까
.
땀내와
사랑내
포근히
품긴
보내주신
학비 봉투를
받아
대학
노―
트를 끼고
늙은
교수의
강의 들으러
간다
.
생각해보면
어린
때
동무를
하나,
둘,
죄다
잃어버리고
나는
무얼
바라
나는
다만
,
홀로
침전하는
것일까
?
인생은
살기
어렵다는데
시가
이렇게
쉽게
씌어지는
것은
부끄러운
일이다
.
육첩방은
남의
나라
창밖에
밤비가
속살거리는데
등불을
밝혀
어둠을
조금
내몰고
시대처럼
올
아침을
기다리는
최후의
나
.
나는
나에게
적은
손을
내밀어
눈물과
위안으로
잡는
최초의
악수
.
쉽게 씌어진 C창밖에 밤비가 속살거려육첩방은 남의 나라 .
C 인이란 슬픈 천명인 줄 알면서도한 줄 C 를 적어볼까 .
땀내와 사랑내 포근히 품긴보내주신 학비 봉투를 받아
대학 노―트를 끼고늙은 교수의 강의 들으러 간다 .
생각해보면 어린 때 동무를하나 , 둘 , 죄다 잃어버리고
나는 무얼 바라나는 다만 , 홀로 침전하는 것일까 ?
인생은 살기 어렵다는데C 가 이렇게 쉽게 씌어지는 것은부끄러운 일이다 .
육첩방은 남의 나라창밖에 밤비가 속살거리는데
등불을 밝혀 어둠을 조금 내몰고C 대처럼 올 아침을 기다리는 최후의 나 .
나는 나에게 적은 손을 내밀어 눈물과 위안으로 잡는 최초의 악수 .
많은 초보들이 독학으로 C 언어를 배우는 과정
1. C 언어 책을 삽니다 .2. 책을 펼치고 열심히 공부합니다 .3. 포인터가 나옵니다 .4. 책을 덮습니다 .5. n 개월 휴식6. 1 번 또는 2 번으로 갑니다 .
이 슬라이드 목표는여러분이 포인터에 대한 작은 깨달음을 얻는 것입니다 .
그리고 진실과 다른 내용이 더러 나옵니다 .
기초 지식
비트와 바이트
비트 : 1 또는 0 을 저장할 수 있는 공간
바이트 : 1 비트 8 개의 집합0000 0000 ~ 1111 1111
예제 1)1 바이트로 표시할 수 있는 범위를 10 진수로 나타내면 ?
예제 2)1 바이트로 표시할 수 있는 범위를 16 진수로 나타내면 ?
예제 1)1 바이트로 표시할 수 있는 범위를 10 진수로 나타내면 ?
0 ~ 255 ( -128 ~ 127 도 정답 )
예제 2)1 바이트로 표시할 수 있는 범위를 16 진수로 나타내면 ?
00 ~ FF
예제 3) 다음 16 진수 덧셈을 해 봅시다 .
0 + 4 = 4 + 4 = 8 + 4 = C + 4 = C4 + 1C =
예제 3) 다음 16 진수 덧셈을 해 봅시다 . 0 + 4 = 4 4 + 4 = 8 8 + 4 = C C + 4 = 10 C4 + 1C = E0
16 진수 0x4, 0x8, 0xC, 0x10 은 각각 4, 8, 12, 16 에 해당되는 숫자입니다 . 자주 나오니 기억합시다 .
잠깐 메모리에 대해 알아보고 , & 연산자도 알아 봅시다 _
메모리
컴퓨터의 메모리는 연속적인 선형 저장공간입니다 .
각 바이트마다 고유한 주소를 가집니다 .
(32 비트 PC 에서 )
가장 앞 주소 : 0000 0000
가장 뒤 주소 : FFFF FFFF
...
0000 0000
FFFF FFFF
0000 0001
FFFF FFFD
OS 는 메 모 리의 일정 한 주소 를 묶 어 영 역 으로 만들었습니다 .각 영역마다 정해진 역할이 있습니다 .
어떤 게임에서 그린벨트 , 거주 구역 , 공업지구 등으로 나눈 거랑 비슷합니다 .
중 3 성적을 말아먹은 게임
메모리 영역은 크게 코드 , 데이터 , 스택 , 힙으로 나뉩니다 .각각의 역할은 조금 나중에…
물론 이 그림은 추상화입니다 .
예제 3)메모리 주소를 표현하기 위해서 필요한 최소한의 크기는 ?
...
0000 0000
FFFF FFFF
0000 0001
FFFF FFFD
예제 3)메모리 주소를 표현하기 위해서 필요한 최소한의 크기는 ?
4 바이트
# unsigned int = 4 바이트이므로 주소를 저장할 수 있다 .
...
0000 0000
FFFF FFFF
0000 0001
FFFF FFFD
* 참고옛날 16 비트 IBM DOS 시절에int 는 2byte(16bit) 지만 메모리 주소는 20bit 여서unsigned int 로 주소를 표현할 수 없었습니다 .
...
0 0000
3 FFFF
0 0001
3 FFFD
변수
1. 메모리의 어딘가에 필요한 크기만큼 자리를 잡고2. 이름을 붙여줌3. 적절한 값을 넣을 수 있음
int n = 10; //4 바이트char a = 'x'; //1 바이트double d = 5.23; //8 바이트
예제 4)
다음 문장을 보고 찍어 보세요 .
1. 위 문장에 필요한 공간은 ?
2. 위 변수의 이름은 ?
3. 위 변수의 타입은 ?
double doo[] = { 3.14, 1.414, 1.717 };
예제 4)
다음 문장을 보고 찍어 보세요 .
1. 위 문장에 필요한 공간은 ? 24 바이트
2. 위 변수의 이름은 ? doo
3. 위 변수의 타입은 ? 더블의 배열 타입 (?)
double doo[] = { 3.14, 1.414, 1.717 };
변수의 종류
전역 변수 (global variable)
정적 변수 (static variable)
지역 변수 (local variable) = 자동변수 (auto variable)
단항 연산자 &단항 연산자 (unary operator) & 는 주소 연산자입니다 .변수의 주소를 알고 싶을 때 사용합니다 .
printf 에서 주소를 출력할 때는 %p 입니다 .
변수의 주소 알아보기
전역변수의 주소지역변수의 주소정적변수의 주소포인터 ?함수 ?
결과주소를내림차순으로 정 렬해 봅시다 .
변수가 위치하는 영역의 이름
종류 위치 설명
함수 코드 소스코드 , 리터럴이 위치
전역 및 정적변수 데이터 데이터 영역
포인터 ( 동적 할당 ) 힙 동적 할당 영역
지역변수 스택 함수 내부 / 임시저장용
여기부터 진짜로 포인터 이 야기 _
포인터 (Pointer)
포인터는 주소를 저장하는 특이 (特異 ) 한 자 료형입니다 .그리고 저장한 주소에 가서 값을 읽어옵니다 .그게 전부예요 .
포인터 (Pointer)
포인터는 주소를 저장하는 특별한 자 료형입니다 .그리고 저장한 주소에 가서 값을 읽어옵니다 .그게 전부예요 .
거짓말 .한 3% 정도 됩니다 .
포인터 (Pointer)
주소를 저장한다구요 ? 그럼 , 이게 다 뭔가요 ?
놀라지 말고 차근차근 하나 씩 알아 봅시다 :D
int *ptr;char *ptr;void *ptr;int **pptr;int *ptr[5];int (*ptr)[3];int (*foo)(double a);
배우기 전에 그 림을 그리기 위한 규칙을 배웁시다 .그림으로 그리면 조금 이해가 잘 됩니다 .제가 고심해서 만들……
포인터 char intdouble
struct
일반 변수의 선언 및 초기화는 아래처럼 그 릴 수 있습니다 .
int a = 20;
아래의 희미한 건 실제 저장되는 메모리의 시작주소입니다 .
20a
0x080481AC
포인터 변수는 주소를 저장하는 변수입니다 .
형식은 타입 * 변수명 이 됩니다 .
변수 선언할 때 * 는 어떤 변수가 포인터라는 것을 나타 냅니다 .
아래 선언 코드는 "ptr 은 int 의 포인터다 " 라는 뜻입니다 .
ptr
int *ptr;
포인터에는 주소값이 저장 됩니다 .
이미 & 연산자를 이용해서 주소를 알아올 수 있으므로 사용해 봅시다 .
ptr
int a = 20;int *ptr;ptr = &a;
20a
0x080481AC
0x080481AC
동그라 미라서 칸이 모자 랍니다 .
어차피 a 의 주소를 가 르킨 거니까 그 냥 화살표로 연 결해 봅시다 .
a 의 주소도 귀찮으니까 지 웁니다 .
ptr
int a = 20;int *ptr;ptr = &a;
20a
포인터가 가 르키는 변수를 특별히 포인 티라고 합시다 .
다른 곳에서는 그렇게 안 부 르는데 미국의 S 대학 자 료에서 발견한 멋진 이름입니다 .
위 그 림의 해석" 포인터 변수 ptr 의 포인티는 int a 이고 20 이 저장되어 있다 ."
ptr
20a
포인터 규칙 1.
포인터와 포인티는 같은 타입이어 야 한다 .
포인터에는 아무 주소나 들어 갈 수 있을까요 ? 아닙니다 .
포인터 규칙 1.
포인터와 포인티는 같은 타입이어 야 한다 .
ptr
20a
ptr 은 int 의 포인터라는 걸 그림만 봐도 알 수 있어요 !
포인터에는 아무 변수의 주소나 들어 갈 수 있을까요 ? 아닙니다 .
포인터 규칙 1.
포인터와 포인티는 같은 타입이어 야 한다 .
int a = 20;int *ptr;ptr = &a;
문 ) 다음 코드에 문제가 없는지 그 림으로 확인해 보세요 .
double *ptr1, *ptr2, dnum; dnum = 3.14;ptr1 = &a;ptr2 = ptr1;
문 ) 다음 코드에 문제가 없는지 그 림으로 확인해 보세요 .
double *ptr1, *ptr2, dnum; dnum = 3.14;ptr1 = &a;ptr2 = ptr1;
문 ) 다음 그 림을 코드로 나타내 보세요 .
ptr1
h
c0
i
c1
ptr2
문 ) 다음 그 림을 코드로 나타내 보세요 .
ptr1
h
c0
i
c1
ptr2
char c0 = 'h';char c1 = 'i';char *ptr1 = &c0;char *ptr2 = &c1;
포인터 규칙 2.
포인터 변수는 반드시 초기 화 후에 사용해 야 한다 .
사실 그 냥 변수도 그렇습니다 .
포인터의 사용을 위해서는 * 연산자를 사용합니다 .
선언이 아 닌 곳에서 * 를 붙여서 포인 티의 값을 읽거나 쓸 수 있습니다 .
int a = 20;int *ptr = &a;printf("%d\n", *ptr) //*ptr 이 int 라는 걸 알겠죠 ?
ptr
20a
ptr 의 포인티는 a 이므로 *ptr 을 읽으면 20 이 나옵니다 .
포인터를 사용하려면 * 연산자를 사용합니다 .
선언이 아 닌 곳에서 * 를 붙이면 포인티의 값을 읽거나 쓸 수 있습니다 .
int a = 20;int *ptr = &a;printf("%d\n", *ptr) //20*ptr = 50;printf("%d\n", *ptr) //50printf("%d\n", a) //?
ptr
20 50a
*ptr 에 50 을 넣으면 자신이 아니라 포인 티가 50 이 됩니다 .Make
sense?Reasonable
?
LV?? 스마트 데이터 조봉수 팀장님
포인터를 사용한다라는 건 결국 * 을 사용한다는 것입니다 .
그런데 초기 화를 해 주지 않으면 포인 티가 존재하지 않습니다 .
아래 코드를 실 행하면 어 떻게 될까요 ? 그림으로 그리면 ?
int *ptr;*ptr = 50;printf("%d\n", *ptr) //?
ptr
초기화를 해 주지 않은 포인터는 절대 사용하면 안 됩니다 .
그래서 초기 화하지 않은 포인터는 아 래처럼 그 립니다 .
ptr
LV.99 가비지 포인터
< 엄청난 버그를 양산 >
다음 코드의 문제는 무 엇인지 실행도 해 보고그림으로 그려 봅시다 .
* 참고로 맥에서 GCC 로 컴 파일하면 잘 실행됩니다 .
main() { int *ptr; foo(ptr);}
void foo(int *p) { *p = 100; printf(“%d\n”, *p);}
포인터 규칙 3.
void* 는 읽을 수 없다 .
사실 그 냥 변수도 그렇습니다 .
void * 란 ? 어떤 타입의 주소도 닮을 수 있는 만 능 그릇int 도 double 도 char 도 누구라도 포인 티가 될 수 있습니다 !!
두 줄 동그라 미로 그리도 록 하겠습니다 .
ptr
To be continued…