반응형
함수 포인터란?
  • 함수의 이름은 그 함수가 저장된 메모리의 주소이다 (함수 포인터)
  • 함수의 주소값을 함수 포인터 변수를 선언해서 저장할 수 있다.
  • 함수 포인터에 함수의 주소를 담아서 함수처럼 사용이 가능하다

 

 

 

함수 포인터 변수 선언

함수 포인터 변수는 아래와 같이 선언할 수 있습니다.

반환형 (*변수명) (매개변수 데이터타입, ...);

int (*fptr) (int, int);	// 반환형 (*변수명) (매개변수 데이터타입, ...);

 

아래와 같이 함수 포인터 변수를 선언하고

그 변수에 함수를 할당받고 함수처럼 사용하면

함수와 같이 동일하게 쓰입니다.

이렇게 함수 포인터 변수에 저장된 값을 통해서도

함수호출이 가능합니다!

int Add(int num1, num2){...}
int (*fptr) (int, int);

fptr = Add;
fptr(1, 2);	// Add(1, 2)와 동일한 결과를 보임

 

 

 

 

 

함수 포인터 주의사항

매개변수가 다르면 참조 불가능

반환형이나 매개변수가 다르면 다른타입이기에 함수 포인터 변수에

그 함수를 할당할 수 없다

 

함수 이름은 같지만 매개변수랑 반환형이 다르면 함수 포인터형이 다른것이다.

 

void 포인터

어떠한 주소 값도 저장이 가능한 void형 포인터

형 정보가 존재하지 않는 포인터 변수이기에 어떠한 주소 값도 저장이 가능하다.

형 정보가 존재하지 않기 때문에 메모리 접근을 위한 *연산은 불가능하다.

 

함수의 형태든 int형이든 다 저장이 가능하다.

주소 값만을 저장하기에 값 할당, 주소의 값을 가져오는

포인터 연산이 안된다.

 

 

 

void 포인터 주의사항

void 포인터 또한  int포인터로 형변환이 가능하다

하지만 void포인터에 함수형 또한 담기는데 함수주소를 담을때

int포인터로 강제 형변환을 하면 컴파일 에러는 없지만,

함수의 기능이 정수형으로 사용되는 오작동을 하게 된다.

 

반응형

 

반응형

'C' 카테고리의 다른 글

표준 입출력 버퍼  (0) 2023.05.22
문자와 문자열 함수  (0) 2023.05.22
다차원 배열과 포인터의 관계  (0) 2023.05.18
다중포인터  (0) 2023.05.18
다차원 배열  (0) 2023.05.17
반응형
2차원 배열이름의 포인터 형

int형과 int* 1차원배열은 이런식으로 포인터 형을 취할 수 있다.

int arr[10];	// int형 포인터 (int*)
int* parr[20];	// int형 이중 포인터 (int**)

int arr1[3][4];

 

 

 

 

2차원 배열 선언

2차원 배열을 포인터형을 취할 때는 약간 다르다.

아래의 코드처럼 데이터타입(*변수명)[행의 길이]; 로 선언이 됩니다.

int (*ptr)[4];

 

아래의 코드에서 포인터형에 +1을 할 경우 데이터타입 * 2차원 배열의 행길이가 증가하는 포인터 변수가 된다.

arr1+1  => char형크기 * 4

arr2+1 => int형크기 * 6

+ 1을 하면 다음 열의 첫번째 행의 주소값이 된다.

char (*arr1)[4];
int (*arr2)[6];

 

 

2차원배열이면서 자료형이 같고 행의 길이가 같으면 포인터 형이 같은것이다.

 

 

 

2차원 배열 주의사항
  • 배열 포인터와 포인터 배열은 다르다!
int * arrA[4];	// 해당 값에 주소가 들어가 있다.
int (*whoB)[4];	// 해당 값에 int형이 들어가 있다.

 

  • 인자로 2차원배열 전달

2차원배열을 매개변수로 넘길때 행의 길이를 넘겨야 합니다.

2차원배열을 매개변수로 넘길때 SimpleFunc1, SimpleFunc2처럼 매개변수를 넘기면 됩니다.

두 함수 모두 동일한 선언입니다.  

int arr1[2][7];
double arr2[10][5];
SimpleFunc1(arr1, arr2);
SimpleFunc2(arr1, arr2);

void SimpleFunc1(int (*parr1)[7], double (*parr2)[5]) {...}
void SimpleFunc2(int  parr1[][7], double parr2[][5]) {...}

 

  • 배열의 세로길이 계산방식

2차원 배열의 행의 길이는 결정되어 있다.

세로 길이 정보는 결정되어 있지 않기에

sizeof(배열) / sizeof(배열[0]) 으로 배열의 세로길이를 구할 수 있다.

 

 

  • 2차원 배열과 포인터 표현 방식

아래의 코드는 모두 동일한 표현 방식입니다.

arr[2][1] = 4;
(*(arr+2))[1] = 4;
*(arr[2] +1) = 4;
*(*(arr+2)+1) = 4;

 

반응형

 

반응형

'C' 카테고리의 다른 글

문자와 문자열 함수  (0) 2023.05.22
함수 포인터  (0) 2023.05.19
다중포인터  (0) 2023.05.18
다차원 배열  (0) 2023.05.17
홀수 짝수 구분  (0) 2023.05.17
반응형
이중 포인터 변수

포인터 변수의 주소 값을 저장하는 것이 이중 포인터 변수(더블 포인터 변수)이다.

 

 

아래의 코드는 이중포인터 변수의 예시이다.

이중포인터 dptr이 ptr의 주소 값을 저장합니다.

*dptr은 ptr의 주소 값이 나오며 한번더 포인터연산자를 써서

**dptr을 하게 되면 ptr의 주소값에 있는 num의 값에 접근하게 됩니다.

 

*dptr은 double포인터인 ptr1의 주소값을 가지고 있기에 double포인터 ptr2에 할당이 가능합니다.

ptr2 또한 num의 주소값을 참조하게 되어서 *ptr2의 값을 변경하면 num의 값이 변경되게 됩니다.

double num = 3.14; 	// 100번지
double *ptr = # 	// 200번지
double **dptr = &ptr;	// 300번지
double* ptr2;	// 400번지

printf("%9p %9p \n", ptr, *dptr);	// 100번지 100번지
printF("%9g%9g\n", num, **dptr);	// 3.14 3.14

ptr2 = *dptr;
*ptr2 = 10.99;
printf("%9g %9g \n", num, **dptr);	// 10.99 10.99

 

 

 

포인터 배열과 포인터 배열의 포인터 형

int arr1[5]; 에서 arr1의 포인터형은 int* 이렇게 표기합니다

따라서 int* arr1[10]; 에서 arr의 포인터 형은 int** 입니다.

int arr1[5];
int* ptr1 = arr1;	// 자료형(타입)이 같아서 할당이 된다.

int* arr2[10];
int** ptr2 = arr2;	// 자료형(타입)이 같아서 할당이 된다.

 

 

삼중 포인터

삼중 포인터는 아래의 코드처럼 int*** tptr; 이렇게 선언이 가능하며

이중 포인터 변수의 주소 값을 담는 용도로 선언됩니다.

int num = 10;
int* ptr = #
int** dptr = &ptr;
int*** tptr = &dptr;

printf("%d %d \n", **dptr, ***tptr);	// 100 100 출력

 

 

포인터의 필요성
  • scanf함수와 같이 외부에 선언된 변수의 접근을 허용하기 위해서
  • 메모리의 동적 할등
  • 자료구조

 

 

다중 포인터 이해(정리)

처음 다중 포인터를 접한다면 정말 너무 당황하게 됩니다.

주소에 주소를 담고 거기에 또 주소를 담는다는 이론은 쉽게 이해할 수도 있지만

실제로 쓸려고 하면 막막하게 됩니다. 물론 이해하기도 벅찹니다.

 

저는 그래서 다중 포인터를 박싱과 언박싱으로 예시를 들겠습니다.

int** dtpr은 int형 이중포인터인데 자료형과 같이 *연산자가 같이 쓰일경우는

선언할때입니다. 선언할때 *의 갯수가 박싱의 개념이라고 생각합니다.

int**형 같은 경우는 내용물을 작은박스에 그 후 작은박스를 큰박스에 담는 느낌으로 말입니다.

 

선언후에 int형 이중 포인터 변수에 *연산자를 붙이면 이중포인터에 들어와 있는 값을

뜻하는데 그때의 *는 언박싱의 개념으로 말입니다. 

int** dtpr은 **dtpr처럼 *연산자가 두개가 있으면 박스를 두번 열어서 그 안의 내용물을 꺼낸다라고 

생각하면 이중포인터가 나름 친근하게 다가올 수 있습니다.

 

N중 포인터 또한 이런 방식으로 생각하면 개념에 조금 더 쉽게 다가갈 수 있을것입니다!

 

반응형

 

 

반응형

'C' 카테고리의 다른 글

함수 포인터  (0) 2023.05.19
다차원 배열과 포인터의 관계  (0) 2023.05.18
다차원 배열  (0) 2023.05.17
홀수 짝수 구분  (0) 2023.05.17
이진수 출력  (0) 2023.05.17
반응형
2차원 배열이란?

1차원 배열이 한방향으로 길이가 있는 형태라면

2차원 배열은 가로, 세로 길이가 있는 배열이라고 생각하면 됩니다!

int arr[3][3];	// 가로, 세로 길이가 각각 3인 2차원 int형 배열

 

 

3차원 배열이란?

3차원 배열은 가로, 세로, 높이의 길이가 있는 배열이라 생각하면 됩니다.

int arr[3][3][3];	// 가로, 세로, 길이가 각각 3인 3차원 int형 배열

 

 

N차원 배열

물론 메모리 구조상으로는 N차원배열은 전부 일렬로 연속되어 있고,

N차원 배열은 포인터로도 취급이 가능하다.

 

 

 

2차원 배열선언

2차원 배열의 선언 방식은 아래의 코드와 같습니다.

type arr[세로 길이][가로 길이];

 

아래의 표는 해당 2차원 배열의 요소를 표로 표현한 것입니다.

int arr[3][4];
                                 열
1열 2열 3열 4열
1행 [0][0] [0][1] [0][2] [0][3]
2행 [1][0] [1][1] [1][2] [1][3]
3행 [2][0] [2][1] [2][2] [2][3]

 

2차원 배열의 메모리상 할당

출력결과를 보면 알 수 있듯이 N차원배열의 메모리 공간은 전부 일렬로 연속되어있다.

int arr[2][3];
int i, j;
for(i=0; i<2; i++)
	for(j=0; j<3; j++)
    	printf("%p \n", &arr[i][j]);
return 0;

/* 출력결과
00000020E0F2F5A8
00000020E0F2F5AC
00000020E0F2F5B0
00000020E0F2F5B4
00000020E0F2F5B8
00000020E0F2F5BC
*/

 

 

 

2 차원배열 선언과 초기화

아래의 코드예제를 통해서 2차원배열 선언과 초기화에 대해서 설명드리겠습니다!

arr1배열처럼 모든 요소를 다 입력해서 초기화를 할 수 있습니다.

 

arr2배열은 요소 중간이 비어있지만 이 요소들은 전부 0으로 초기화됩니다.

 

arr3배열은 2차원 배열이지만 1차원 배열처럼 일렬로 초기화했지만 2차원 배열은 사실

1차원 배열로도 표현이 가능합니다. 그리고 초기화하지 않은 인덱스는 0으로 초기화됩니다.

 

arr4배열은 행열의 길이 두개 다 비워두어서 컴파일 에러가 발생합니다.

 

2차원배열의 길이 하나만 생략된다면 나머지차원의 길이는 계산이 가능합니다.

그래서 2차원 배열의 선언과 초기화에서는 세로길이만 생략이 가능하도록 약속되어 있습니다.

arr5, arr6배열처럼 열의 길이가 생략되어도 열의 길이는 자동으로 계산되어져서 컴파일이 성공합니다.

int arr1[3][3] = 
{
    {1, 2, 3,},	// 1 2 3
    {4, 5, 6,},	// 4 5 6
    {7, 8, 9}	// 7 8 9
};

int arr2[3][3]	=
{
    {1},	    // 1 0 0
    {4, 5},	    // 4 5 0
    {7, 8, 9}	    // 7 8 9
};

int arr3[3][3] =
{
    1, 2, 3,	// 1 2 3
    4, 5, 6,	// 4 5 6
    7		// 7 0 0
}

int arr4[][] = {1, 2, 3, 4};	// 컴파일 에러

int arr5[][4] = {1, 2, 3, 4, 5, 6, 7, 8};	// 컴파일 성공
int arr6[][2] = {1, 2, 3, 4, 5, 6, 7, 8};	// 컴파일 성공

 

반응형

 

반응형

'C' 카테고리의 다른 글

다차원 배열과 포인터의 관계  (0) 2023.05.18
다중포인터  (0) 2023.05.18
홀수 짝수 구분  (0) 2023.05.17
이진수 출력  (0) 2023.05.17
홀수를 먼저 짝수를 나중에 출력하는 함수  (0) 2023.05.17
반응형
void Practice()
{
	int arr[10] = { 0 };
	int arrLen = sizeof(arr) / sizeof(int);
	int odd[10] = { 0 };
	int even[10] = { 0 };
	int evenCount = 0;
	int oddCount = 0;
	for (int i = 0; i < arrLen; i++)
	{
		scanf("%d", &arr[i]);
		if (arr[i] % 2 == 0)
			even[evenCount++] = arr[i];
		else
			odd[oddCount++] = arr[i];
	}
	Odd(odd, oddCount);
	printf("\n");
	Even(even, evenCount);

}
void Odd(int* odd, int oddLen)
{
	printf("홀수 출력 : ");
	for (int i = 0; i < oddLen; i++)
	{
		printf("%d ", odd[i]);
	}
}
void Even(int* even, int evenLen)
{
	printf("짝수 출력 : ");
	for (int i = 0; i < evenLen; i++)
	{
		printf("%d ", even[i]);
	}
}

 

반응형

 

반응형

'C' 카테고리의 다른 글

다중포인터  (0) 2023.05.18
다차원 배열  (0) 2023.05.17
이진수 출력  (0) 2023.05.17
홀수를 먼저 짝수를 나중에 출력하는 함수  (0) 2023.05.17
회문  (0) 2023.05.17

+ Recent posts