함수 포인터와 void 포인터 + 도전 프로그래밍3 3&4번문제

2023. 3. 19. 01:13언어/열혈C

함수 포인터란?

함수 또한 메모리에 바이너리 형태로 저장&호출이 되는 방식이다. 변수와 마찬가지로 메모리에 저장되므로 그 주소가 있고 그걸 함수 포인터라고 부른다. 함수 포인터를 저장하는 포인터 변수를 함수 포인터 변수라고 한다.

 

함수의 이름은 마치 우리가 배열때 했듯이 그 이름 자체로 주소 값을 의미한다(+상수 형태) 그럼 어떻게 선언하는가?

int Func(int num){...}에서 알 수 있는 건

반환형 / 함수 이름 / 매개변수 들이다.

우선 우리는 함수의 type(자료형이라 말하면 조금 이상한데...암튼 거기에 대응하는 개념인듯)을 먼저 생각해야한다. 단순하다. 그냥 반환형과 매개 변수의 선언형태를 기준으로 구분하기로 했다.

위에 Func함수의 포인터 형의 경우 반환형이 int, 매개변수가 int형 하나로 선언된 포인터 형이라고 할 수 있다.

 

 

함수 포인터 선언은

(함수의 반환형) (*fptr) (매개변수 자료형&개수) 로 선언한다. (*fptr)로 쓰는건 뭔가 배열이랑 비슷한 느낌이 난다. 배열 포인터를 선언 할 때도 (자료형) (*ptr)[n] 이런식으로 했었는데 이번에도 함수 포인터는 (반환형) (*fptr) (자료형&개수)로 나타난다.

ex) double SSM(int num1, char ch1){...}이라는 함수는

doulbe (*fptr) (int, char); 로 선언됨

이후 ftpr=SSM; 이라고 하면 되겠죠?

또한 함수의 매개변수로서도 선언 가능한 게 신기해서 예시 들고옴

int WIF(int num1, int num2, int (*fptr)(int n1, int n2)){...}

이런식으로 매개변수에 함수를 그냥 넣는 것도 가능하더라. 그럼 나중에 반환형이 int고 int를 2개 매개변수로 요하는 함수를 만들면 저기에 그냥 함수 이름 갖다 넣으면 되는 거임 ㅇㅇ.

 

 

void형 포인터란 어떤 변수의 주소도 다 담을 수 있다고함. int char 등등은 물론이고 함수도 가능 ㅇㅇ.

대신 연산이나 값의 변경/참조도 불가능함. only 주소를 저장하기 위함인듯?

"일단 주소 값에만 의미를 두고, 포인터의 형은 나중에 결정한다." - 열혈C중에서

나중에 메모리의 동적 할당에서 다시 나온다고 한다.

 

 

마지막으로 main 함수의 원래 형태이다. 

int main(int argc, char * argv[ ]){...}

이게 원래 형태라고 한다. 참고로 그냥 실행하면 안되고 cmd열어서 실행해야함.

argc는 입력받은 문자열의 개수를 세주고, argv는 그 문자열들의 주소값이 반환되어(이미 포인터 1차) 저장된 배열이 저장된 주소(포인터 2차)를 포인터로 가져오는 거라고 한다. 그래서 *argv[ ] (혹은 **argv)라고 표현되는 거다.

cmd 창에 (소스코드 파일 이름) (문자열들...) 이런식으로 입력하나보다.

ex) ArgcArgc I like you 라고 실행하면 (ArgcArgv가 실행파일 이름) 프로그램은 띄어쓰기를 단위로 문자열을 인식해 ArgcArgc, I, like, you 이렇게 배정됨. 참고로 "~~"이렇게 쌍따옴표를 이용하면 안에 있는 문자열들은 띄어쓰기 관계 없이 그대로 하나의 문자열로 취급된다고 한다.

 

//

도전 프로그래밍 문제에서 난수라는 개념 등장. stdlib.h에 저장되있는 함수라고 함. rand함수는 의사난수(pseudo-random number)를 정수형으로 반환. 

 

0~99까지 난수를 만들어내는 문제

#include<stdio.h>
#include<stdlib.h>

int main() {
	int i;
	printf("난수 범위 0~99 \n");
	for (i = 0; i < 5; i++) {
		printf("%d \n", rand() % 100);
	}

	return 0;
}

답지가 없어서 애매한데 맞겠지?

근데 계속 실행해도 같은 값이 나옴. 그래서 psuedo(의사)라는 말이 붙는다고 한다. 값이 예측이 되서. 컴파일이나 디버깅을 다시 해도 그러더라. 그래서 그 대안?을 바로 다음 문제인 4번에서 다룸.

 

srand함수. 매개변수로 양의 정수 하나를 입력 받으면 그에따라 rand함수가 반환하는 난수가 달라짐.

+time함수. time.h에 저장되어 있는 함수로 1970년 1월 1일 이후의 시간적 차를 초단위로 계산해서 반환해 준다고 한다. 우리는 단순히 시간정보를 반환받으므로 time(NULL) 이렇게 쓴다고 한다. 다른 목적일 때는 다른 인자를 넣는듯?

그래서 srand((int)time(NULL))이라고 함수를 사용하면, 매초마다 다른 값이 시드값으로 들어가고, 매번 다른 rand()를 뱉어낸다고함

 

무작위 주사위 값을 출력하는 문제

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

int main() {
	srand((int)time(NULL));
	printf("주사위 1의 결과 : %d\n", rand() % 6 + 1);
	printf("주사위 2의 결과 : %d\n", rand() % 6 + 1);

	return 0;
}

'언어 > 열혈C' 카테고리의 다른 글

구조체와 사용자 정의 자료형1  (0) 2023.07.21
문자와 문자열  (0) 2023.07.19
다차원 배열과 포인터  (0) 2023.03.11
더블 포인터  (0) 2023.03.09
다차원 배열  (0) 2023.03.09