공부했던 자료 정리하는 용도입니다.
재배포, 수정하지 마세요.
포인터
- 포인터
- 포인터 변수
- 포인터 변수의 선언
* 포인터 변수의 크기 - 포인터 형(type)
- 포인터 변수와 관련된 연산자
1. & 연산자
2. * 연산자 - null 포인터
- 포인터 대상의 const 선언
* 상수를 가리키는 포인터인 경우
* 포인터 자체가 상수인 경우
* 포인터가 상수이면서 상수를 가리키는 경우
- 포인터와 배열
- 포인터 연산
- 문자열의 선언방식
- 포인터 배열
* 문자열 배열
- 포인터와 함수
- 함수의 호출 방식
* Call-by-value
* Call-by-reference - 함수의 인자로 배열 전달
* 인자로 배열 전달 시 배열의 크기
- 함수의 호출 방식
- 이중 포인터(더블 포인터)
- 이중 포인터 선언과 사용
- 포인터 변수 대상의 Call-by-reference
- 포인터 배열과 포인터 배열의 포인터 type
- 다중 포인터 변수
- 다차원 배열과 포인터
- 2차원 배열의 이름과, 2차원 배열의 첫 번째 행
- 2차원 배열의 증감 연산
- 2차원 배열의 포인터
- 함수 인자로 2차원 배열 전달
- 다차원 배열에서 arr[i]와 *(arr + i)
- 배열 포인터와 포인터 배열
- main 함수의 인자
* 인자의 형성 과정
* char * argv[ ]
- 함수 포인터
- 함수 포인터 변수 선언
- void 포인터
포인터와 배열
배열도 포인터이다. 그러나 값을 바꿀 수 없는 '상수 형태의 포인터'이다.
포인터 연산
arr[i] == *(arr + i);
``type``형 포인터를 대상으로 ``n``의 크기만큼 값을 변경시키면 @@n × sizeof(type)@@의 크기만큼 주소 값이 증가/감소한다.(``int``형일 경우 ``4``씩, ``double``형일 경우 ``8``..) 그래서 위와 같이 배열일 경우 @@arr[i] == *(arr + i)@@이 성립한다.
문자열의 선언방식
마지막에 null 문자가 삽입되는 문자열의 선언방식
- 변수 형태의 문자열 : 배열 이용
- 상수 형태의 문자열 : ``char``형 포인터 변수 이용
//마지막에 null 문자가 삽입되는 문자열의 선언방식
// 1. char형 배열 이용(변수 형태의 문자열, 문자열 변경 가능)
char str1[] = "String1";
// 2. char형 포인터 변수 이용(상수 형태의 문자열, 문자열 변경 불가)
char * str2 = "String2";
``str1``은 그 자체로 문자열 전체를 저장하는 배열이다. ``str2`` 처럼 선언하면 메모리 공간에 문자열 ``String``이 저장되고, 문자열의 첫 번째 문자 ``S``의 주소 값이 반환된다. 그리고 그 반환 값이 포인터 변수 ``str2``에 저장된다. ``str1``, ``str2`` 모두 문자열의 시작 주소 값을 가리키고 있다는 것에서는 동일하지만 ``str1``은 상수 형태의 포인터이기 때문에 가리키는 대상을 변경할 수 없는 반면, ``str2``는 가리키는 대상을 변경할 수 있다. 배열로 선언되는 문자열을 '변수 형태의 문자열'이라 하고 ``char``형 포인터 변수를 이용해서 선언한 문자열은 '상수 형태의 문자열'이라고 한다.
##"##로 묶여서 표현되는 문자열은 그 형태에 상관없이 메모리 공간에 저장된 후 그 주소 값이 반환된다. 그래서 ##printf## 함수는 문자열이 아닌 문자열의 주소 값을 전달받는 함수이다. (인자가 ##char *## 형)
포인터 배열
#include <stdio.h>
int main(void)
{
int num1 = 10, num2 = 20, num3 = 30;
int * arr[3] = {&num1, &num2, &num3};
printf("%d \n", *arr[0]);
printf("%d \n", *arr[1]);
printf("%d \n", *arr[2]);
return 0;
}
포인터 변수로 이뤄져 주소 값의 저장이 가능한 배열을 포인터 배열이라고 한다.
■ 문자열 배열
#include <stdio.h>
int main(void)
{
char * strArr[3] = {"Simple", "String", "Array"};
printf("%s \n", strArr[0]);
printf("%s \n", strArr[1]);
printf("%s \n", strArr[2]);
return 0;
}
문자열 배열은 문자열의 주소 값을 저장할 수 있는 배열로서 사실상 ``char *``형 포인터 배열이다. ``"``로 묶여서 표현되는 문자열은 메모리 공간에 저장된 후, 주소 값이 반환되므로 실제로는 ``strArr``에 각 문자열의 주소 값들이 들어있는 것이다.
포인터와 함수
함수의 호출 방식
함수의 호출 방식
- Call-by-value : 값을 전달하는 형태의 함수 호출
- Call-by-reference : 주소 값을 전달하는 형태의 함수 호출
■ Call-by-value
#include <stdio.h>
void Swap(int n1, int n2)
{
int temp = n1;
n1 = n2;
n2 = temp;
printf("n1 n2 : %d %d \n", n1, n2);
}
int main(void)
{
int num1 = 10;
int num2 = 20;
printf("num1 num2 : %d %d \n", num1, num2);
Swap(num1, num2);
printf("num1 num2 : %d %d \n", num1, num2);
return 0;
}
함수 호출 시 전달되는 인자의 값은 매개변수에 복사가 되는데 이런 방식을 Call-by-value라고 한다.
그래서 위의 예시의 경우 ``Swap``함수를 호출해서 ``main``함수의 ``num1``과 ``num2``값을 서로 바꾸려 했지만 바뀌지 않았다.
■ Call-by-reference
#include <stdio.h>
void Swap(int * n1, int * n2) // 매개변수의 주소값을 인자로 받음
{
int temp = *n1;
*n1 = *n2;
*n2 = temp;
}
int main(void)
{
int num1 = 10;
int num2 = 20;
printf("num1 num2 : %d %d \n", num1, num2);
Swap(&num1, &num2); // 매개변수가 포인터이므로 주소값 전달
printf("num1 num2 : %d %d \n", num1, num2);
return 0;
}
앞의 예시에서 함수로 실제 변수값을 바꾸고 싶다면 변수의 주소 값을 인자로 받아서 처리해야 된다.
이런 방식을 Call-by-reference라고 한다.
함수의 인자로 배열 전달
void ShowArayElem(int * param, int len) {...}
void AddArayElem(int * param, int len, int add) {...}
// 배열의 주소값이 인자로 전달될 때에는 주로 아래와 같이 선언된다.
void ShowArayElem(int param[], int len) {...}
void AddArayElem(int param[], int len, int add) {...}
함수의 매개변수로 배열을 선언할 수 없지만 배열의 주소 값을 전달하는 것은 가능하다. 일반적으로 배열의 주소 값이 인자로 전달될 때에는 배열인 것을 강조하기 위해 ``param[ ]``과 같은 표현을 더 많이 사용한다. (매개 변수일 때만 서로 변환 가능)
int arr[3] = {1, 2, 3};
int * ptr = arr; //int ptr[] = arr;로 대체 불가능
매개변수가 아닌 경우에는 대체할 수 없다.
■ 인자로 배열 전달 시 배열의 크기
#include <stdio.h>
void ShowArayElem(int * param, int len)
{
for(int i = 0 ; i < len ; i++)
printf("%d ", param[i]);
printf("\n");
}
int main(void)
{
int arr1[3] = {1, 2, 3};
int arr2[5] = {4, 5, 6, 7, 8};
ShowArayElem(arr1, sizeof(arr1) / sizeof(int));
ShowArayElem(arr2, sizeof(arr2) / sizeof(int));
return 0;
}
배열의 주소 값을 인자로 전달받는 매개변수는 포인터 변수이기 때문에 이를 대상으로 ``sizeof``연산을 할 경우 배열의 크기가 아닌 포인터 변수의 크기가 반환된다. 따라서 배열의 크기를 알 수 없기 때문에 배열의 크기나 길이 정보도 함께 인자로 전달해야 한다.
'기타 > C' 카테고리의 다른 글
[C] 다차원 배열과 포인터 (0) | 2020.05.19 |
---|---|
[C]이중 포인터(더블 포인터) (0) | 2020.05.12 |
[C] 포인터 (0) | 2020.05.05 |
[C] 배열 (1차원 배열, 다차원 배열, 가변 길이 배열) (1) | 2020.04.28 |
[C] 함수 (0) | 2020.04.27 |