-
[열혈강의 C]Part2. 13장 - 포인터와 배열! 함께 이해하기-두번째[포인터/배열 완전정복]Development/C 2013. 8. 23. 15:21반응형
포인터와 배열 완전 정복하기!!-두번째
날씨도 더운데 이 선풍기 바람좀 쐬면서 좀 더 시원해지세요~ ㅋㅋㅋ 겨울에 이 글을 보는사람은 어쩔수 엄슴..ㅠㅠ 추워도 참으셔야댐
▼이전 글 보기(클릭)▼
2013/08/22 - [ETC/▶프로그래밍] - [열혈강의 C]Part2. 13장 - 포인터와 배열! 함께 이해하기-첫번째[포인터/배열 완전정복]
13-3문자열 상수를 가리키는 포인터
[1]문자열 표현 방식의 이해 - 포인터가 표현하는 문자열 상수
이건 쫌 중요한문제입니다..ㅇ-ㅇ
문자열을 표현하실 때 어떻게 표현하시나요?
대부분 printf함수를 쓰거나 배열을 사용하여 표현하곤 합니다.
하지만, 포인터로도 문자열을 표현할 수 있다는 사실 알고 계셨나요~?
char string[5]="abcd";
char *pString[5]="ABCD"; //문자 ABCD를 가리킨다
<배열을 이용한 문자열 표현 string[5]="abcd";>
<포인터를 이용한 문자열 표현 pString[5]="ABDC";>
그림 보니까 한방에 이해되시죠~? ㅎㅎ
자~ 그렇다면 위 그림을 소스코드를 통해 자세히 살펴보겠습니다.
#include<stdio.h>
int main(void)
{
char str1[5]="abcd";
char *str2="ABCD";
printf("%s \n", str1);//문자열 변수 선언
printf("%s \n", str2);//문자열 상수 선언
/*문자열은 변수 앞에'*'를 안붙여도 값이 존재합니다.
배열자체가 주소를 가지기 때문입니다.*/
str1[0]='x'; //문자열 변수 변경
//str2[0]='x'; /문자열 상수 변경, Error 발생
printf("%s \n", str1);
printf("%s \n", str2);
return 0;
}
각 문자열 맨 앞의 요소를 'x'로 바꾸는 내용입니다.
변수인 str1[5] 배열은 올바르게 x로 변환이 되어 출력되었지만,
포인터는 변경이 불가능한 상수형태의 문자열로 에러가 발생하였습니다.
[2]문자열 상수에 대한 조금 더 깊은 이해
■ 위에서는 포인터로 문자열을 표현할 수 있는 대신에 상수(고정값)로 만 사용할 수 있다고 설명드렸습니다.
여기에 덧붙여 설명드리겠습니다.
우선, 아래 두가지를 기억하세요!
■ 1. 문자열 상수는 메모리 공간에 할당되면 주소를반환한다.
-char *str = "ABCDEFG";
[*str이 짝사랑한 '주소값'... 그러나 예기치 못한 ABCDEFG라는 여인이 나에게 다가왔는데...]
사건의 전말은 다음과 같습니다.
*str은 오른쪽에 있는 변수의 '주소값'이 오기를 대기하고 있음
하지만 주소값은 커녕 상수' ABCDEFG'가 와버렸음..
'*str'은 그래도 당황하지 않았음.. 나쁘지 않았던것임.. 생각보다 외모가 괜찮았음..
어떻게하면 ABCDEFG를 내 것으로 만들 수 있을까 순간 두뇌회전 RPM은 급상승함.
결론을 내림.
우선, ABCDEFG에게 메모리공간(0x10번지)를 사줌. Give & Take 사회라 ABCDEFG도 나에게 뭔가를 주게 되어있음.
알고보니 ABCDEFG의 여동생이 주소값이였던것임. 따라서, *str은 ABCDEFG와 그녀의 주소값을 얻게 됨.
그래도 모르겠으면 아래 그림 보믄 댐..;;
<글 읽기 귀찮은 분들을 위한 그림 보충설명..^_^>
그림은 알겠는데 그래도 이해가 안되면..아래 글 보믄 댐;;
교과서에 있는 그대로 적겠습니다.(펼치세요~)
■ 2. 똑같은 문자열을 선언하면 한번만 메모리 공간에 할당된다.
(일부 컴파일러에만 해당)
혹요나 여러분의 컴파일러가 해당되지 않더라도 알고있으면 도움이 많이 될 것입니다.
말그대로 같은 문자열은 동일한 주소에 할당됩니다. 우선 예제를 보시겠습니다.
※주의사항 : 반드시 정확하게 일치하는 문자열이어야함
#include<stdio.h>
int main(void)
{
char *str1="Good!";
char *str2="Good!";
printf("%d,%d\n",str1,str2);
return 0;
}
보시면 아시겠지만,두 포인터의 주소가 동일한 것을 확인 할 수 있습니다. 저의 컴파일러는 해당이되네요~ㅎㅎ
그렇다면!! 나는 두 가지의 포인터를 선언했는데 왜 메모리 공간에 하나만 저장이되는가!?
이는 바로 똑같은 코드라 할지라도 메모리를 효율적으로 사용하기 위한 메모리 최적화입니다.
앞서 포인터는 문자열상수를 가질 수 있다고 했습니다. 어차피 똑같은 "Good"라는 문자이며, 변경이 불가합니다.
따라서, 같은 주소를 가리킨다고 한들 문제될건 없잖아요?? ㅎㅎ
제컴은 똑똑한 컴파일러였음..!-☆
깨알 팁!(위에 해당하지 않는 컴파일러는?)
13-4 배열요소로 포인터를 지니는 포인터 배열
[1]포인터 배열의 이해
지금부터는 핵심인! 포인터배열 을 설명드리겠습니다.
여지껏 변수를 선언할 때
char *ptr=&a;
char *ptr=arr;
로 선언을 해왔습니다.
지금부터는 char *arr[100]; 과 같이 배열을 가진 포인터에 대해 알아보겠습니다.
int * arr1[10];
double* arr2[20];
char* arr3[30];
<포인터배열.안알랴줌>
다음은 포인터배열의 기능을 활용한 코드를 보겠습니다.
#include<stdio.h>
int main(void)
{
int a=10, b=20, c=30;
int *arr[3]={&a,&b,&c};//포인터배열
printf("%d \n",*arr[0]);
printf("%d \n",*arr[1]);
printf("%d \n",*arr[2]);
return 0;
}
포인터 *arr[0]은 'a'를 가리키고,
포인터 *arr[1]은 'b'를 가리키고,
포인터 *arr[2]은 'c'를 가리키고..
포인터 *arr[3]은 '\0(NULL)'를 가리킵니다.. 딱 봐도 아시겠죠??
출력결과는 당연히 10,20,30이 출력됩니다.
그럼 다음으로 넘어가겠습니다.
#include<stdio.h>
int main(void)
{
char *arr[3]={
"Hello.",
"My name is ",
"James."};
printf("%s \n",arr[0]);
printf("%s \n",arr[1]);
printf("%s \n",arr[2]);
return 0;
}
/*
문자열배열은 배열자체만으로 주소값을 가지고 있기 때문에 앞에 '*'를 안넣어도 된다고 앞서 설명했었습니다.
*/
<출력결과>
char *arr[3]={"Hello.","My name is ","James."};
↓
char *arr[3]={"0x1000","0x2000","0x3000"};
문자열 상수를 받는 즉시, 저장공간이 확보가 되고 주소값이 반환됩니다.(앞에서 설명했습니다.)
[13장 - 포인터와 배열! 함께 이해하기]총정리
1. 포인터 = 배열의 이름(첫번째 요소)
2. 포인터는 변수, 배열은 상수
3. arr이 변수이름이던 포인터이던 "arr[i]=*(arr+i]"는 항상 성립★★★
4. 포인터의 연산은 증가 혹은 감소만 되며 곱하기,나누기는 불가능하다.
5. 포인터는 문자열 상수를 나타낼 수 있다.(문자열 상수의 특징)
6. 1차원 배열은 그 종류가 어떤 것이라도 배열 이름의 포인터타입이 무엇인지 알 수 있다.(int형 배열은 int형 포인터)
끝. 감사합니다~
[C언어 다른 글 보기]
2013/07/04 - [ETC/▶프로그래밍] - [열혈강의 C]도전프로그래밍 ONE - 문제1
2013/07/04 - [ETC/▶프로그래밍] - [열혈강의 C]도전프로그래밍 ONE - 문제2
2013/07/04 - [ETC/▶프로그래밍] - [열혈강의 C]도전프로그래밍 ONE - 문제3
2013/07/07 - [ETC/▶프로그래밍] - [열혈강의 C]도전프로그래밍 ONE - 문제4
2013/07/08 - [ETC/▶프로그래밍] - [열혈강의 C]도전프로그래밍 ONE - 문제5
2013/07/25 - [ETC/▶프로그래밍] - [열혈강의 C]도전프로그래밍 ONE - 문제6
2013/07/25 - [ETC/▶프로그래밍] - [열혈강의 C]도전프로그래밍 ONE - 문제7
2013/07/25 - [ETC/▶프로그래밍] - [열혈강의 C]도전프로그래밍 ONE - 문제8
2013/08/01 - [ETC/▶프로그래밍] - [열혈강의 C]Part2. 11장 - 1차원 배열(연습문제11-1-1)
2013/08/01 - [ETC/▶프로그래밍] - [열혈강의 C]Part2. 11장 - 1차원 배열(연습문제11-1-2)
2013/08/06 - [ETC/▶프로그래밍] - [열혈강의 C]Part2. 11장 - 1차원 배열(연습문제11-1-3)
2013/08/07 - [ETC/▶프로그래밍] - [열혈강의 C]Part2. 11장 - 1차원 배열(연습문제11-2-1)
2013/08/07 - [ETC/▶프로그래밍] - [열혈강의 C]Part2. 11장 - 1차원 배열(연습문제11-2-2)
2013/08/07 - [ETC/▶프로그래밍] - [열혈강의 C]Part2. 11장 - 1차원 배열(연습문제11-2-3)
2013/08/09 - [ETC/▶프로그래밍] - [열혈강의 C]Part2. 12장 - 포인터의 이해(연습문제12-1-2)
2013/08/09 - [ETC/▶프로그래밍] - [열혈강의 C]Part2. 12장 - 포인터의 이해(연습문제12-1-3)
2013/08/22 - [ETC/▶프로그래밍] - [열혈강의 C]Part2. 13장 - 포인터와 배열! 함께 이해하기-첫번째[포인터/배열 완전정복]
반응형'Development > C' 카테고리의 다른 글
[C언어] 2차원 배열을 이용하여 각 셀의 합을 더하여라. (1) 2014.12.11 [열혈강의 C]Part2. 13장 - 포인터와 배열! 함께 이해하기(연습문제13-1-2) (1) 2013.08.27 [열혈강의 C]Part2. 13장 - 포인터와 배열! 함께 이해하기(연습문제13-1-1) (0) 2013.08.27 [열혈강의 C]Part2. 13장 - 포인터와 배열! 함께 이해하기-첫번째[포인터/배열 완전정복] (4) 2013.08.22 [열혈강의 C]Part2. 12장 - 포인터의 이해(연습문제12-1-3) (0) 2013.08.09 [열혈강의 C]Part2. 12장 - 포인터의 이해(연습문제12-1-2) (0) 2013.08.09 [열혈강의 C]Part2. 11장 - 1차원 배열(연습문제11-2-3) (0) 2013.08.07 [열혈강의 C]Part2. 11장 - 1차원 배열(연습문제11-2-2) (0) 2013.08.07 [열혈강의 C]Part2. 11장 - 1차원 배열(연습문제11-2-1) (0) 2013.08.07 [열혈강의 C]Part2. 11장 - 1차원 배열(연습문제11-1-3) (0) 2013.08.06