일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- shell_script
- PHP #핵심정리
- MySQL #핵심정리
- C언어 #부록
- C언어 # 핵심 정리
- C언어 # 부록
- C언어 #핵심정리
- C++ 언어 # 핵심정리
- Hacking #Baic
- C++ 언어 #핵심정리
- Bandit
- C++ 언어 # 핵심 정리
- HTML #핵심정리
- Today
- Total
cCcode
C Language [핵심정리] - 39 본문
1. 함수에서 구조체 매개변수 사용하기
함수에 전달해야 할 매개변수의 개수가 많아진다면, 그 매개변수들을 하나의 단위로 묶어서 구조체를 사용할 수 있습니다. 그럼 매번 그 많은 매개변수들을 전달해야 할 필요가 없어지죠.
함수를 호출할 때 구조체 변수를 넣어주면 구조체 변수의 모든 멤버들이 매개변수로 복사됩니다. 단, 구조체 크기가 커지면 커질수록 그만큼 큰 공간이 필요하기에 효율적이라 말하긴 어렵겠네요. 보통 매개변수로 구조체를 전달할 때는 포인터를 사용해야 함수 외부에서도 수정한 구조체를 사용할 수 있습니다. 그 단편적인 예로는 다음코드를 보시죠.
분명히 함수에서 값을 수정했는데도 처음에 수정한 값으로 결과가 나왔습니다. 그 이유는 구조체의 멤버들이 포인터가 아니므로 함수 외부에 값을 전달할 수 없기 때문입니다. 만약 함수 외부 값을 전달하고 싶다면 구조체 변수를 포인터로 선언하거나 일반 구조체 변수로 선언뒤 함수에서 전달값을 포인터로 바꾸고, 매개변수로 &(주소연산자)를 통해 주소를 전달해주면 됩니다. 둘이 비슷해보이는 방법이지만, 멤버에 접근하는 방법이 . 과 -> 로 나누어진다는 점에서 (물론 오직 main 함수 내부에서만 해당하지만) 다르다고 볼수도 있습니다.
1) 구조체 포인터 변수 사용하기
구조체 변수를 포인터로 만들기 위해선 변수명 앞에 *(Asterisk)를 사용하고 동적 메모리 할당을 통해 공간을 부여 합니다. 당연히 그에 맞춰 . 도 ->(화살표 연산자)로 수정하고 모두 사용한 후 free 함수로 동적할당을 해제해줘야겠죠?
2) 함수에서의 전달값과 매개변수 바꾸기
함수를 호출할 때 주소를 매개변수로 사용한다면 (= 매개변수를 구조체 포인터로 사용하면)구조체 멤버의 값이 복사되지 않고, 메모리 주소만 전달되기 때문에 외부의 값을 수정할 수 있는것이죠.
우리는 배열 매개변수에 사용하던 복합 리터럴을 구조체 매개변수에서도 사용할 수 있습니다.
우리가 구조체를 만들 때 멤버들을 순서대로 나열하기 때문에 굳이 멤버 명을 쓰지 않고 바로 값을 할당할 수 있습니다.
이외에도 위 중 두 번째 방법(매개변수로 구조체 변수의 주소를 주는 경우) 또한 복합리터럴이 사용가능합니다.
가장 앞에 &(주소 연산자)만 사용하면 되요. 간단하죠?
이처럼 복합리터럴을 사용하는 경우 중괄호({})를 사용해 값을 지정해주기 때문에 문자열의 경우에도 strcpy 같은 문자열 함수의 사용 없이 간단히 =(대입 연산자)로 값을 할당할 수 있습니다.
여러분들이 그전에 배웠던 구조체 별칭으로 코드를 간결하게 만들 수 있습니다. 다만 구조체 포인터 별칭의 경우에는 이미 포인터 자체를 포함한 상태에서 선언되기 때문에 헷갈리실 수 도 있으니 주의해서 사용해주세요. 여기서 잘못 사용하면 오류도 안뜨고 워닝도 안뜨는데 비정상적으로 프로그램이 종료되는 끔찍한 상황을 보실수 있을겁니다.
+ 이외에도 구조체 뿐만 아니라 공용체와 열거형 또한 매개변수로 전달할 수 있습니다. 그것까지 설명한다면 글이 너무 길어지기 때문에 설명은 여기서 마치도록 하겠습니다.
2. 함수에서 가변인자 사용하기
C언어에서 함수 중 scanf 나 printf 처럼 매개변수의 개수가 정해지지 않은 함수들이 존재합니다. 이렇게 사용할 때마다 전달되는 인수(argument)의 개수가 변하는 걸 가변 인수(variable argument)라고 합니다.
함수를 호출한 결과 한 개 이상의 값을 전달했으나 실제로 사용된 것 첫번째 매개변수 뿐입니다. 그럼 나머지 매개변수는 어디 들어가는지 궁금하실 수 있는데, 나머지 매개변수들은 ... ← 이 부분에 들어갑니다. 그럼 이제 ... 부분에 들어가는 매개 변수들을 사용해보겠습니다.
그전에 가변인자를 처리해주는 매크로를 알고 있어야 합니다. (+ <stdarg.h>파일에 정의되어있습니다.)
사용하는 매크로 명 자체가 긴 탓에 어렵게 느껴질 수도 있지만 그렇게 어렵지는 않습니다. 차근차근 설명할테니 이해하셨으면 좋겠네요. 일단 va_list 매크로는 일종의 가변인자를 저장하는 변수(배열)를 생성하고 va_start 는 시작하는 부분 즉, 매개변수가 끝나는 부분을 시작점으로 잡는 매크로라고 이해하시면 될거 같습니다. 왜냐하면 우리는 가변인자(매개변수 X)를 사용할 것이기 때문에 매개변수 이후에 나오는 ... 부분을 사용하려면 시작점을 가장 마지막 매개변수로 지정해줘야 하기 때문입니다. va_arg는 가변 인자 목록(가변 인자의 배열)에서 지정한 자료형의 크기만큼 값을 가져올 때 사용합니다. 그리고 가변인자의 사용이 끝난 후에는 va_end 를 사용해 가변인자 목록 포인터를 NULL로 초기화하며, 가변인자의 사용을 끝마칩니다. (일종의 free 함수로 봐도 무방할 듯 합니다.) 위 코드의 흐름을 그림으로 표시하자면 다음과 같습니다.
'C Language Basic' 카테고리의 다른 글
C Language [핵심정리] - 41 (0) | 2021.07.22 |
---|---|
C Language [핵심정리] - 40 (0) | 2021.07.20 |
C Language [핵심정리] - 38 (0) | 2021.07.16 |
C Language [핵심정리] - 37 (0) | 2021.07.11 |
C Language [핵심정리] - 36 (0) | 2021.07.09 |