출처 : https://swexpertacademy.com/main/learn/course/lectureVideoPlayer.do
1. 포인터와 함수 매개변수
(1) 함수의 매개 변수
- 함수에 전달한 값이 있는 경우 인자를 전달
- 함수 측에서는 매개변수를 통해 전달받음
(2) 함수 인수 전달방법
1) call by value
- 값에 의한 호출
- 인자의 값이 매개변수로 복사
- 함수호출 측의 인자 자체에는 영향 없음
- 즉, 함수 내에서 매개변수가 변화해도 그 함수 내에서만 영향
2) call by reference
- 참조에 의한 호출
- 호출된 함수 측에서 포인터 매개변수로 받아 호출한 함수 측의 주소를 참조하도록 구성
- 인자 주소가 매개변수에 복사, 호출된 함수에서 주소를 이용하여 인수에 접근
- 매개변수 변화가 인자에 영향
(3) 함수 인수 전달방법 예제
1) call by value
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
#include <stdio.h>
void swap(int a, int b);
int main(void)
{
int a,b;
a = 5;
b = 10;
swap(a,b);
printf("main() : a = %d\tb= %d\n",a ,b);
return 0;
}
void swap(int a, int b)
{
int temp;
temp = a;
a = b;
b = temp;
printf("swap() : a = %d\tb = %d\n", a, b);
}
|
|
- 인자로 main 함수의 지역 변수(a,b) 전달
- swap 함수 수행 후, main 함수에서 a,b 내용 확인 시 값이 처음 상태로 유지
- 결과 :
swap() : a = 10 b = 5
main() : a = 5 b = 10
|
2) call by reference
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
#include <stdio.h>
void swap(int *a, int *b);
int main(void)
{
int a,b;
a = 5;
b = 10;
swap(&a,&b); // 인자를 주소로 전달
printf("main() : a = %d\tb= %d\n",a ,b);
return 0;
}
void swap(int* a, int* b)
{
int temp;
temp = *a;
*a = *b;
*b = temp;
printf("swap() : a = %d\tb = %d\n", *a, *b);
}
|
|
- 보통, 함수 처리 결과를 2개 이상 반환하는 경우의 프로그램일 때 사용
- 결과 :
swap() : a = 10 b = 5
main() : a = 10 b = 5
|
2. main 함수의 매개변수 전달
(1) 명령어의 실행
- 명령어 창에서 직접 명령어를 입력해서 실행하는 경우, 명령어 뒤에 인자를 붙여 사용
- ex) ftp ftp.kernel.org
(2) main 함수의 원형
1
|
int main(int argc, char *argv[])
|
- 프로그램 실행 시 인자를 전달받기 위해 main 함수의 원형에 대한 이해가 필요
- argc : 인자의 개수 전달 / *argv : 인자의 목록 전달 (char* 배열이나 2중 포인터로 받아야 함)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
#include<stdio.h>
#include<string.h>
int main(int argc, char* argv[])
{
char* path = "/tmp";
char filename[1024];
if(argc!=2){
printf("Usage : %s filename\n", argv[0]);
return 0;
}
strcpy(filename, path);
strcat(filename, argv[1]);
printf("filename : %s\n", filename);
return 0;
}
|
|
- 흠.. 대충 개념만 알자
|
3. 함수 포인터
(1) 함수 포인터란?
- 포인터는 함수 시작 번지를 넣어 사용 가능
- 함수의 시작 주소를 포인터 변수에 대입
(2) 함수 포인터의 목적
- 다양한 함수들이 서로 다른 환경에서 호출되는 경우 사용 (ex. 컴파일러, 어셈블러, 인터프리터 등의 소프트웨어 작성 시)
- 동적으로 함수를 불러다 사용하고 필요없는 경우 삭제하는 동적 라이브러리 함수를 이용하는 경우
(3) 함수 포인터 선언
리턴타입 (*함수포인터변수명)(매개변수목록);
|
int(*fun)(int num); // int(*fun)(int); 도 가능. 즉, 매개변수 명은 생략
|
- fun 변수에 시작 주소를 대입
- int 값을 반환하고 매개변수로 int 형의 num 하나만 선언
- int *fun() ---> int형 포인터(주소)를 반환하는 fun 함수 호출로 해석
|
(4) 함수의 시작 주소 확인
- "배열 이름 = 배열 시작 주소"와 마찬가지로 함수 이름은 함수의 시작 번지를 통해 알 수 있음
(5) 함수 포인터 예제
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
#include <stdio.h>
int add(int x, int y);
int main(void)
{
int (*calc)(int x, int y); // 함수 포인터 선언
int x,y,z;
x = 10;
y = 20;
calc=add; // add함수의 시작 주소를 대입
z = calc(x,y); // 함수 포인터를 이용한 함수 간접 호출
printf("add = %d\n", z);
return 0;
}
int add(int x, int y)
{
return x+y;
}
|
(6) 함수 포인터 배열
- 배열 원소 각각이 함수 포인터 변수
- 원형이 동일한 함수의 주소들이 모여있는 구조
1) 함수 포인터 배열 선언
리턴타입 (*함수포인터배열명[크기])(매개변수목록);
|
- 함수 포인터 선언과 다른 점 : ① 크기가 있음 ② 첨자를 이용해 함수 포인터 원소에 접근 가능
2) 함수 포인터 배열 예제
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
|
#include <stdio.h>
int add(int a, int b);
int subtract(int a, int b);
int multiply(int a, int b);
int divide(int a, int b);
int main(void)
{
int (*fptr[4])(int a, int b);
int a, b, result, op;
fptr[0] = add;
fptr[1] = subtract;
fptr[2] = multiply;
fptr[3] = divide;
do{
printf("두 개의 수를 입력\n");
scanf("%d %d",&a,&b);
printf("1. 더하기 2. 빼기 3. 곱하기 4. 나누기 5. 종료\n");
printf("선택하십시오[0-5]\n");
scanf("%d,&op");
if(op == 5)
break;
result = (*fptr[op-1])(a,b);
}while(1);
return 0;
}
int add(int a, int b)
{
return a+b;
}
int subtract(int a, int b)
{
return a-b;
}
int multiply(int a, int b)
{
return a*b;
}
int divide(int a, int b)
{
return a/b;
}
|
4. void 포인터
(1) void형이란?
- 값이 없을 때 이용하는 자료형
- 반환 값이 없는 함수의 리턴 타입
(2) void*형
- 주소를 저장하는 자료형
- 어떤 유형의 주소도 저장 가능
- void형은 크기가 없어 void* 변수가 가리키는 메모리를 얼마나 참조해야 하는지 확인 불가
(포인터가 가리키는 내용 참조 시 원래 자료형으로 형변환)
- ex) printf("num = %d\n", *(int*)p); --> (int*)의 형변환을 해줌
- 즉, void 포인터는 아직 값이 들어갈 때 자료형이 어떤 것인지 알 수 없을 경우 사용. 그렇기 때문에 함수 내에서 형변환을 이용하여 자료형에 따른 연산을 각각 설정
(3) void* 예제
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
#include <stdio.h>
#include <string.h>
void swap(char* type, void* a, void* b)
int main(void)
{
int a,b;
a = 5;
b = 10;
swap("int", &a, &b);
printf("main() : a = %d\t b= %d\n", a, b);
c = 'a';
d = 'b';
swap("char", &c, &d);
printf("main() : c = %c\td = %c\n", c, d);
}
void swap(char*type, void*a, void*b)
{
int temp;
if(!strcmp(type,"int")){
temp = *(int*)a;
*(int*)a = *(int*)b;
*(int*)b = temp;
} else if(!strcmp(type,"char")){
temp = *(char*)a;
*(char*)a = *(char*)b;
*(char*)b = temp;
}
}
|
5. 라이브러리 함수
(1) 라이브러리란?
- C프로그램을 쉽게 개발하기 위해 미리 만들어놓은 함수들의 모음
- 개발환경 구축 할 때, C컴파일러와 라이브러리가 설치되어 바로 사용 가능
(2) 표준입출력 함수의 이해
#include <stdio.h>
|
- 우리가 항상 사용하던 stdio도 라이브러리의 일종
(3) 표준입출력 함수 예제
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
#include <stdio.h>
int main(void)
{
char buffer[80];
char string[1024];
printf("문자열을 입력하시오.\n");
gets(buffer); // 라이브러리 사용, 입력
sprintf(string,"입력된 문자열은 %s 입니다",buffer); // 라이브러리 사용, 추가
puts(string); // 라이브러리 사용, 출력
return 0;
}
|
(4) 문자 처리 함수
- 문자의 특성 구분이 필요한 경우 사용하는 라이브러리는 아래와 같다.
#include <ctype.h>
|
int isalnum(int ch) | 인자가 영문자나 숫자인 경우 참(0이 아닌 값) 반환, 그렇지 않은 경우 거짓(0) 반환 |
int isalpha(int ch) | ch로 전달된 인자가 영문자인 경우 참 반환, 그 외엔 거짓 반환 |
int isdigit(int ch) | ch에 전달된 인자가 숫자(0~9)인 경우 참 반환, 그 외에 거짓 반환 |
int iscntrl(int ch) | ch에 전달된 인자가 0~0x1f 사이에 있거나 0x7f(DEL)와 같은 제어문자인 경우 참 반환, 그 외에 거짓 반환 |
int isspace(int ch) | ch에 전달된 인자가 공백문자이면 참 반환, 그 외에는 거짓 반환 |
int ispunct(int ch) |
인자 ch가 공백문자를 제외한 구두점 문자인 경우 참 반환, 그 외에는 거짓 반환 구두점 문자 : 영문자, 숫자, 공백문자를 제외한 출력 가능한 문자, 즉 특수문자 |
int tolwer(int ch), int toupper(int ch) |
함수 tolower는 ch가 영문자인 경우 소문자로 반환, 그 외에는 그대로 반환 toupper는 대문자 반환 |
(5) 문자열 처리 함수
- C에는 문자열 자료형이 제공되지 않음
#include <string.h>
|
'C언어' 카테고리의 다른 글
C언어_printf()함수_형식지정자, 제어문자 리스트 (0) | 2019.11.13 |
---|---|
C언어_스터디_4_구조체/공용체 (0) | 2019.11.12 |
C언어_스터디_2_포인터란? (0) | 2019.11.09 |
C언어_스터디_1_변수의 유효범위 (0) | 2019.11.08 |
C언어_배열 출력 (0) | 2019.03.22 |