본문 바로가기

Basic Programming Language/C

C언어 - 포인터, 포인터배열

포인터(Pointer)

- 메모리의 주소값을 저장하는 변수


- 연산자 : 주소(번지) 연산자(&), 참조 연산자(*)


 - 주소(번지) 연산자(&) : 변수의 이름 앞에 사용 / 해당 변수의 주소값을 반환


 - 참조 연산자(*) : 포인터의 이름이나 주소 앞에 사용 / 포인터에 가리키는 주소에 저장된 값을 반환


- 선언 형식 : 타입* 포인터이름;


- 선언 + 초기화 : 타입* 포인터이름 = &변수이름; or 타입* 포인터이름 = 주소값;


- 포인터를 선언한 후 참조 연산자(*)를 사용하기 전에 포인터는 반드시 먼저 초기화되어야한다 -> 그렇지 않으면 의도하지 않은 메모리의 값을 변경하게 되기 때문


- 포인터의 타입은 참조 연산자를 통해 값을 참조할 때, 참조할 메모리의 크기를 알려주는 역할

Pointer 연산

- 제한된 연산만 가능 / 규칙 존재
1. +, *, / = 의미X
2. - =  두 포인터 사이의 상대적 거리 => 빼기 연산하면, 메모리 크기가 줄어드는게 아니라 두 메모리 사이의 거리가 데이터 타입의 크기만큼 늘어나는 것 = 멀어지는 것 
3. 정수 +, - : O, 실수 연산 X 
4. 대입, 비교 가능

 

Various pointer


- pointer of pointer / void pointer / function pointer / null pointer


null pointer : 0이나 NULL을 대입하여 초기화한 pointer / 아무것도 가리키지 않는 pointer


pointer of pointer : 2중 pointer / 포인터 변수를 가리키는 포인터 / 참조 연산자(*)를 두 번 사용


void pointer : 대상이 되는 데이터의 타입을 명시하지 않은 포인터 / 변수, 함수, 포인터 등 어떠한 값도 가리킬 수 있지만, 포인터 연산이나 메모리 참조와 같은 작업은 할 수 없습니다 = 주소값을 저장하는 것 이외에는 아무것도 할 수 없는 포인터 / 사용할 때마다 명시적 타입 변환을 하고 난 뒤에 사용


function pointer : 함수의 시작 주소를 가리키는 포인터 상수 / 함수 포인터의 포인터 타입은 함수의 반환값과 매개변수에 의해 결정 = 함수의 원형을 알아야만 해당 함수에 맞는 함수 포인터를 만들 수 있습니다.


*프로그램에서 정의된 함수는 프로그램이 실행될 때 모두 메인 메모리로 올라감 ->  함수의 이름은 메모리에 올라간 함수의 시작 주소를 가리키는 포인터 상수(constant pointer)가 됨 
원형 - void func (int, int); -> 함수 포인터 - void (*ptr_func) (int, int);


**함수 포인터 사용시 연산자의 우선순위 때문에 반드시 *ptr_func 부분을 괄호(())로 둘러싸기

Argument transfer
- argument = 함수를 호출시, 함수에 필요한 데이터를 전달할 때 사용


- 종류: call by value, call by reference


call by value : 인수로 전달되는 변수가 가지고 있는 값을 함수 내의 매개변수에 복사하는 방식 / 이렇게 복사된 값으로 초기화된 매개변수는 인수로 전달된 변수와는 완전히 별개의 변수 / 함수 내에서의 매개변수 조작은 인수로 전달되는 변수에 아무런 영향을 미치지 않습니다.


call by reference : 인수로 변수의 값을 전달하는 것이 아닌, 해당 변수의 주소값을 전달 / 함수의 매개변수에 인수로 전달된 변수의 원래 주소값을 저장 / 인수로 전달된 변수의 값을 함수 내에서 변경할 수 있게 됩니다.

 

 


포인터 배열(Pointer Array & Array Pointer)

- Pointer Array : 배열 요소로 포인터 변수를 가지는 배열 = 포인터 변수를 저장할 수 있는 배열


- Array Pointer : 배열을 가리킬 수 있는 포인터 / 2차원 이상의 배열에서만 의미 / 포인터를 배열처럼 사용하기 위해서 배열 포인터를 정의하여 사용


- 구분 : 괄호의 유무 

2차원 배열의 배열 이름으로 포인터 연산을 하면 배열의 행 단위로 이동 = (arr+1)은  arr[1]과 같은 곳을 가리킴 / 포인터 연산 시 증가하는 값이 행의 길이(= 부분 배열의 크기 = sizeof(arr[0]) / sizeof(타입))에 따라 차이 / 

 

Pointer와 Array의 관계
- C언어에서는 배열의 이름을 포인터처럼 사용할 수 있을 뿐만 아니라, 포인터를 배열의 이름처럼 사용


- 포인터 상수(constant pointer) = 포인터 변수가 가리키고 있는 주소 값을 변경할 수 없는 포인터 = Array


- 상수 포인터(pointer to constant) = 상수를 가르키는 포인터


- 배열의 크기를 계산할 때에는 배열의 이름과 포인터 사이에 차이가 발생
배열의 이름을 이용한 크기 계산 -> 배열의 크기가 int형 배열 요소 3개의 크기인 12바이트로 제대로 출력
포인터를 이용한 크기 계산 ->  배열의 크기가 아닌 포인터 변수 자체의 크기가 출력되는 차이


*배열에 관계된 연산을 할 때는 언제나 배열의 크기를 넘어서는 접근을 하지 않도록 주의 -> 포인터 연산을 이용하여 계산하다가 배열의 크기를 넘어서는 접근을 하는 경우, C 컴파일러는 어떠한 오류도 발생X = 언제나 배열의 크기에도 주의

 

 

*main함수
- 원형 : void(또는 int) main(int argc, char *argv[]); 
- 프로그램이 실행되면 제일 먼저 자동으로 호출되는 함수
첫 번째 인수 = int형 변수 argc / main() 함수에 인수로 전달되는 문자열의 개수를 명시
두 번째 인수 = char형 포인터 배열 argv = main() 함수에 인수로 전달된 각각의 문자열이 저장된 배열

'Basic Programming Language > C' 카테고리의 다른 글

C언어 - 제어문, 함수  (0) 2024.04.05
C언어 - 연산자, 배열  (0) 2024.04.04
C언어 - 선행처리, 변수  (0) 2024.04.03
C언어 - Input/Output  (1) 2024.04.02