목차
- 포인터 변수에 대한 산술 (+,-) 연산
- 배열의 이름과 주소
- 배열의 이름과 주소
- 배열 첨자 연산과 포인터
- 문자열과 포인터
- 배열 매개 변수와 포인터
- 배열 매개 변수 함수 호출에서의 배열 변경
- 문자열 입출력 함수 :gets()와 puts()
1. 포인터 변수에 대한 산술 (+,-) 연산
- 주소 값은 정수 값과 유사하게 보인다
- 포인터 변수에 대해 정수와 유사하게 +, -, ++, -- 연산을 할 수 있다.
- 그러나 정수와의 그 연산결과가 다르다.
- 포인터 변수가 참조하는 자료형의 크기에 따라 달라진다.
2. 배열의 이름과 주소
① 배열의 이름과 주소
- 배열의 이름은 배열의 시작 주소를 나타내는 포인터/주소 상수이다.
- 그렇기 때문에 '값'을 변화시키려는 연산은 모두 불가능.
- 배열 '이름'은 포인터이므로 + 연산이 가능하다.
- 배열 이름에 n을 더한 것은 첨자에 n을 사용하는 배열 요소의 주소와 같다.
- num + n = &num[n]
② 배열 첨자 연산과 포인터
✓ 배열의 이름과 주소에서
num + n = &num[n]이 성립함
→ *(num + n) = num[n]
※ 배열의 첨자 연산
- 본질적으로 포인터 연산이다.
- 첨자 연산과 포인터 연산은 동등하며 상황에 따라 교환하며 사용 가능하다.
※ 배열의 순회!! : c 프로그래밍에서 널리 쓰이는 방식이므로 꼭 익혀두자!
#include <stdio.h>
int main(void){
int num[10] = {1,2,3,4,5,6,7,8,9,-1};
int i, *pn;
for (i = 0; i<10; i++)
printf("%d\n", num[i]);
for (pn = num; pn < num+10; pn++)
printf("%d\n", *pn);
return 0;
}
3. 문자열과 포인터
문자열 char 형 배열
- Null 문자 ('\0')를 덧붙여 끝을 표시함
배열과 포인터
- pstr이 str을 pointing 하게 값 초기화; &연산자를 사용하지 않았음
- char *pstr = &str; 동일한 결과이나 거의 표현하지 않는 표현법이다.
- pstr이 문자열 str을 가르킨다고 일반적으로 표현하지만 엄밀하게 보면 pstr은 str의 제일 첫 항목을 가리키고 있다.
- str과 pstr은 포인터상수와 포인터 변수다.
- pstr은 배열과 구별되는 별도의 변수이다. str은 배열 주소를 나타내는 상수이다.
- Dereferencing, 첨자 연산 적용시 유사하다.
- pstr은 ++ 연산등을 통해 값을 바꿀 수 있지만 str은 값을 바꿀 수 없다.
포인터를 이용한 문자열 순회 Programming
#include <stdio.h>
int main(void){
char *pstr;// pointer
int num =0, sum=0;// number
char str []="123,456,789";
for( pstr = str; *pstr != '\0' ; pstr++) {
if (*pstr== ',') { // newnum
sum += num;
num= 0;
} else { // a digit
num= num *10 + (*pstr-'0');
}
}
sum += num;
printf("Sum of all values in");
printf(" CSV[%s] : %d", str,sum);
return 0;
}
4. 배열 매개 변수와 포인터
배열 매개 변수는 본질적으로 포인터 매개변수이다.
배열 형식으로 선언한 매개 변수는 실제로는 주소 값을 가지는 포인터 변수다.
함수 호출 시 배열 이름을 사용하면 배열의 이름이 나타내는 주소 값이 (포인터)매개 변수로 복사된다.
선언에 포함한 배열의 크기는 실제로는 이의미가 없으며 무시된다.
5. 배열 매개 변수 함수 호출에서의 배열 변경
C 함수는 Call by Value 특성으로 함수 호출에 쓰인 변수가 함수 호출에 의해 값이 변하지 않는다.
- 매개 변수의 형식이 배열인 경우, 함수 호출에 쓰인 배열의 주소가 매개 변수로 복사된다.
- 즉 배열 매개변수는 호출에 쓰인 배열과 별개의 배열이 아니라 그 배열의 시작 주소를 가지는 포인터 변수이다.
6. 문자열 입출력 함수: get()와 puts()
✓ gets()함수와 puts()함수
- 한 번에 한 문자열을 입력/출력 할 수 있다.
- scanf()를 통해 문자열을 입력 받을 수도 있지만 함수 호출 명령이 더 복잡하고 공백 문자 처리등의 문제로 문자열 입력에 적절하지 않은 경우가 많다.
- printf()를 통해 문자열을 출력할 수도 있지만 역시 함수 호출 명령이 더 복잡하고 내부 출력 처리 과정도 더욱 복잡해서 효율적이지 않다.
① char *gets(char *str);
- 표준 입력으로부터 문자열을 읽어 들여 문자형 포인터 str이 가리키는 기억 장소에 저장하고 포인터 str을 리턴한다
- 매개 변수 str은 함수 입력이 아니라 함수의 출력이다
- str이 가리키는 기억 장소는 입력 값을 쓸 수 있는 유효한 저장 공간이어야 한다.
② int puts(char *str);
- str이 가리키는 문자열을 표준 출력에 출력한다. str은 함수 입력이다.
- 문자열 마지막에 '\n'이 없어도 줄바꿈이 된다.
- 출력이 성공하면 0이 아닌 값을, 실패하면 EOF값을 리턴한다.
※ 포인터 변수는 초기화 하는 습관을!
- 변수를 초기화 하지 않으면 Garbage Value를 가진다.
- Pointer 변수의 초기화는 필수적이다. 적절한 초기화를 하지 않을 경우 부적절한 메모리 공간에 접근하여 값을 읽거나 쓰는 시도로 이루어 질 수 있다. (Run-Time Error)
- NULL == 0 (주소값 상수)
- 널 값이면 출력하지 않는다.
Programming - 배열 매개 변수와 포인터
mystrcpy(), mystrcpy2()는 Null-Terminated String인 src를 dest로 복사하는 함수이다.
mystrcpy()는 배열형 매개 변수를 사용하며 첨자를 이용하여 문자열 복사를 수행한다.
#include <stdio.h>
void mystrcpy(char dest[], char src[])
{
int i=0,j=0;
while (src[i])
dest[j++] = src[i++];
dest[j] = '\0';
}
void mystrcpy2(char *dest, char *src )
{
while(*src){
*dest = *src;
dest++;
src++;
}
*dest = NULL;
}
int main(void) {
char mystr1[256];
char mystr2[256];
char mystr3[256];
gets(mystr1);
mystrcpy(mystr2, mystr1);
puts(mystr2);
mystrcpy2(mystr3, mystr1);
puts(mystr3);
return 0;
}
배열 매개 변수와 포인터
- 배열의 이름은 포인터 상수로서 배열 이름 값을 변경하려는 연산은 모두 Syntax error 가 발생한다.
- mystrcpy()의 매개 변수는 배열형으로 선언되어 있다.
- 배열형 매개 변수에 대해서는 값을 변화시키는게 가능하다.
보조 - Assignment 연산과 *, ++
2 번째 코드에 mystrcpy3은 에러는 안뜰텐데 이건 값이 원하는 대로 안나올거임.
요약
① 포인터 변수에 대한 +, -, ++, -- 연산, 그리고 우선순위
- 포인터 변수가 참조하는 자료형의 크기에 비례하여 값이 더해지거나 빠진다
- 포인터 변수에 대해 단항 연산자인 *,++ 연산이 함께 쓰이면 오른쪽부터 왼쪽으로 연산을 적용한다
② 배열의 이름과 주소
- 배열의 이름은 배열의 시작 주소를 나타내는 포인터/주소 상수이다
- 배열의 첨자 연산은 본질적으로 포인터 연산이다
③ 포인터 제 2법칙: p[i] = *(p+n)
④ 배열의 순화(Traversal)
- 배열의 순회 방법으로는 1) 첨자를 이용하는 방법, 2) 포인터를 이용하는 방법이 있다.
- 포인터를 이용한 배열을 포함한 복합 자료구조의 순회는 C프로그래밍에서 널리 쓰이는 방식으로 자주 사용하며 익히는 것이 좋다.
⑤ 배엶 ㅐ개 변수는 본질적으로 포인터 매개 변수이다
⑥ 문자열 입출력 함수로 gets()와 puts()가 널리 쓰인다
'Language Study > C' 카테고리의 다른 글
[C/C++] 09 - 02 구조체 변수와 함수, 포인터 (0) | 2022.11.24 |
---|---|
[C/C++] 09 - 01 구조체 기초 (0) | 2022.11.23 |
[C/C++] 08 - 01 POINTER 기초 (0) | 2022.11.09 |
[C/C++] 07 - 03 함수와 Modular Programming (0) | 2022.11.02 |
[C/C++] 07 - 02 STANDARD LIBRARY 함수의사용 (0) | 2022.11.02 |