본문 바로가기
학습/IT

[IT] C언어 입문(10) Pointer, 역참조, swap 함수 활용, 배열과 포인터 비교

by 개성공장 2021. 8. 31.
반응형

□ Pointer, 포인터

 * Pointer dereferencing(포인터 역참조)

 - Obtaining the value pointed to by a pointer

a = *x;    // x라는 포인터가 가리키는 변수 값을 a에 저장

*x = a;    // a라는 값을 x가 가리키고 있는 변수 값에 저장

 - if a NULL pointer is dereferenced then a runtime error will occur and execution will stop likely with a "segmentation fault"

 - %p : the printf format to print the value of a pointer

 

 * Swap function

 - p와 q의 값을 서로 바꿔주는 swap 함수 예제

1. 포인터 사용

---

#include<stdio.h>
void swap(int*, int*);

int main(void)
{
	int x=4, y=5;
	swap(&x, &y);
	printf("%d %d\n", x, y);
	return 0;
}

void swap(int *p, int*q)
{
	int tmp;
	tmp = *p;
	*p = *q;
	*q = tmp;
}

---

 

2. 포인터 미사용

---

#include<stdio.h>
void swap(int, int);

int main(void)
{
	int x=4, y=5;
	swap(x, y);
	printf("%d %d\n", x, y);
	return 0;
}

void swap(int p, int q)
{
	int tmp;
	tmp = p;
	p = q;
	q = tmp;
}

---

 - 2번 코드는 swap 함수에서 정의된 지역변수를 바꾸는 작업만 시행할 뿐, main 함수의 실제 x, y 값은 변화하지 않음

 - 해결법 1. 서브루틴 없이 main 함수에서 직접 바꾸는 작업을 하는 것

 - 2. 포인터 개념을 사용하여 1번 코드와 같이 주소정보를 이용하여 직접 값을 바꿔주는 것

 - 즉, main 함수의 지역변수의 값을 다른 서브루틴에서 직접 바꾸기 위해서는 그 지역변수의 주소정보를 활용해 직접 바꿔줌

 

 

 * 예제

int i=4, j=6, *p=&i, *q=&j, *r;
p==&1                    // => p==(&i)
**&p                     //  => *(*(&p))    => *p와 같음, &와 *가 상쇄됨
9**p / *q + 8            // ( ((9*(*p))) / (*q) ) + 8
*(r = &i) *= *p          // (* ( r = ( &i ) ) ) *= (*p)     => i *= *p

int *p;
float *q;
void *v;                 // void 포인터, void* : 포괄적인 포인터 타입

p = 0;
p = v = q;              /* q의 값을 v에 저장, 이후 v의 값(q)를 p에 저장, 오른쪽부터 순서대로
                        타입이 다른 포인터 변수간의 대입연산은 문제가 생길 수 있음
                        p=q; 형식으로 쓰는 것은 타입이 달라 불가능(컴파일은 되나 warning 메시지 발생)
                        이럴 때는 void 타입을 중간에 넣어줌 */ ???
                        
p = (int *) 3;
p = (int *) q;           // 형변환

 

 

 Arrays vs Pointer

 - An array name is actually a 'constant' pointer. its value cannot be changed

 - When s is an array,  s[i] = * (x + i)      // int 타입은 4bytes인데 컴파일러가 자체적으로 4*i로 계산

 - When p is a pointer,  *(p + i) = p[i]

 

#define N 100
int a[N], i, *p, sum=0;

for(p=a; p<&a[N]; p++)     // 1번
	sum += *p;
    
for(i=0; i<N; i++)         // 2번
	sum += * (a + i);
    
for(p=a, i=0; i<N; i++)    // 3번
	sum += p[i];
    
/* 위의 3개의 for문 모두 같은 동작, 배열의 integer값을 모두 더함 */

 

 

 * Pointer Arithmetic

 - If p is a pointer to a particular type, the expression p+1 gives the address for the storage of the next variable of that type.

 

double a[10], *p *q;
p = a;       // p points to the first element of a
q = p + 2;   // q points to the third element of a
printf("%d\n", q-p);               // q-p = 2, 포인터간 연산은 변수타입의 크기를 고려하여 계산됨
printf("%d\n", (int) q - (int) p); //  = 16, 형변환이 되어 그대로 계산됨

 

 

 * Arrays as Function Argument

 - The base address of the array is passed to the function

 

double sum(double x[], int n)          // subroutine에 인수로 array의 값이 아닌 array의 주소가 전달된다!
/* double sum(double *x, int n) */
{
	int i;
	double sum = 0.0;
	for (i=0; i<n; i++)
		sum += x;
	return sum;
}

 

double y[100];

sum(y, 100);       // 100개의 배열값 모두 합산
sum(y, 20);        // y[0]부터 y[19]까지 합산
sum(&y[10], 20);   // y[10]부터 y[29]까지 합산
sum(y+10, 20);     // y[10]부터 y[29]까지 합산

 

※ C언어 입문 시리즈
1. Introduction - C언어의 역사와 기본 개념
2. Variables - 변수, 대입연산자, 구문규칙, 데이터타입 등
3. Data types, 데이터 타입(자료형)
4. Operators, 연산자 - scanf, 산술연산자, 관계연산자, 증감연산자, 대입연산자, 동등연산자 등
5. Operators, 연산자 - 논리연산자, 단축평가, 대입연산자, if문 및 while문 활용
6. Control flow, 제어흐름 - While문, For문, If문, do-while문 등 루프문
7. Function, 함수 - Goto문, getchar와 putchar, 함수 정의와 프로토타입 선언
8. Scope rules/recursion, 변수의 영역규칙과 재귀호출, 난수생성 예시
9. Array와 Pointers, 배열과 포인터
10. Pointer, 역참조, swap 함수 활용, 배열과 포인터 비교
11. File operation 파일연산, String, 다차원 배열 예시
12. structure, union, enumerated types - 구조체, 공용체, 열거체
13. 자료구조(data structure) 예시 - 연결리스트(linked list)
14. C 전처리기(C preprocessor), 함수 포인터(function pointer)
반응형

댓글