C 언어 학습: 고급 주제
C 언어의 기본을 익힌 후에는 고급 주제를 통해 더욱 깊이 있는 프로그래밍 기술을 습득할 수 있습니다. 이번 글에서는 전처리기 지시자, 라이브러리와 모듈화, 네트워킹 기초(소켓 프로그래밍), 다중 스레딩(pthread)에 대해 알아보겠습니다.
1. 전처리기 지시자 (#define, #include, #if 등)
전처리기 지시자는 컴파일러가 소스 코드를 컴파일하기 전에 처리해야 할 명령을 지정합니다. 주요 전처리기 지시자는 다음과 같습니다:
- #define : 매크로를 정의합니다.
[c]#define PI 3.14159
- #include : 다른 파일을 포함합니다.
[c]#include <stdio.h>#include "myheader.h"
- #if, #elif, #else, #endif : 조건부 컴파일을 수행합니다.
[c]
#define DEBUG
#if defined(DEBUG)
#define LOG(msg) printf("DEBUG: %s\n", msg)
#else
#define LOG(msg)
#endif
예제
#define PI 3.14159
#define SQUARE(x) ((x) * (x))
int main() {
printf("PI: %f\n", PI);
printf("SQUARE(5): %d\n", SQUARE(5));
return 0;
}
위의 예제에서 #define을 사용하여 매크로 PI와 SQUARE를 정의하였고, 이를 통해 상수와 함수를 대체할 수 있습니다.
2. 라이브러리와 모듈화
라이브러리와 모듈화를 통해 코드를 재사용 가능하고, 유지보수가 용이하게 만들 수 있습니다. C 언어에서는 헤더 파일과 소스 파일을 분리하여 모듈화를 구현합니다.
1. 헤더 파일 (mylib.h)
#define MYLIB_H
void sayHello();
int add(int a, int b);
#endif
2. 소스 파일 (mylib.c)
#include "mylib.h"
void sayHello() {
printf("Hello, World!\n");
}
int add(int a, int b) {
return a + b;
}
3. 메인 파일 (main.c)
#include "mylib.h"
int main() {
sayHello();
printf("3 + 4 = %d\n", add(3, 4));
return 0;
}
4. 컴파일 명령
[sh]
gcc -o main main.c mylib.c
위의 예제에서 mylib.h는 함수 선언을 포함하고 있으며, mylib.c는 함수 정의를 포함하고 있습니다. main.c에서 이 헤더 파일을 포함하여 함수를 호출할 수 있습니다.
3. 네트워킹 기초 (소켓 프로그래밍)
소켓 프로그래밍은 네트워크 상에서 통신을 수행하는 방법입니다. C 언어에서는 socket API를 사용하여 소켓을 생성하고, 서버와 클라이언트 간의 통신을 처리합니다.
1. 서버 예제
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
int main() {
int server_fd, new_socket;
struct sockaddr_in address;
int opt = 1;
int addrlen = sizeof(address);
char buffer[1024] = {0};
char *hello = "Hello from server";
// 소켓 파일 디스크립터 생성
server_fd = socket(AF_INET, SOCK_STREAM, 0);
if (server_fd == 0) {
perror("socket failed");
exit(EXIT_FAILURE);
}
// 소켓 설정
setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt));
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(8080);
// 소켓 바인딩
bind(server_fd, (struct sockaddr *)&address, sizeof(address));
// 소켓 리스닝
listen(server_fd, 3);
// 클라이언트 연결 수락
new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen);
read(new_socket, buffer, 1024);
printf("%s\n", buffer);
send(new_socket, hello, strlen(hello), 0);
printf("Hello message sent\n");
return 0;
}
2. 클라이언트 예제
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
int main() {
int sock = 0, valread;
struct sockaddr_in serv_addr;
char *hello = "Hello from client";
char buffer[1024] = {0};
// 소켓 파일 디스크립터 생성
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
printf("\n Socket creation error \n");
return -1;
}
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(8080);
// 서버 주소 설정
inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr);
// 서버에 연결
connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
send(sock, hello, strlen(hello), 0);
printf("Hello message sent\n");
valread = read(sock, buffer, 1024);
printf("%s\n", buffer);
return 0;
}
위의 예제에서 서버는 클라이언트의 연결을 기다리고, 클라이언트는 서버에 연결하여 메시지를 주고받습니다.
4. 다중 스레딩 (pthread)
다중 스레딩은 여러 스레드를 사용하여 동시에 여러 작업을 수행하는 방법입니다. C 언어에서는 pthread 라이브러리를 사용하여 다중 스레딩을 구현할 수 있습니다.
스레드 생성 예제
#include <stdlib.h>
#include <pthread.h>
void* print_message(void* ptr) {
char *message;
message = (char *) ptr;
printf("%s \n", message);
return NULL;
}
int main() {
pthread_t thread1, thread2;
const char *message1 = "Thread 1";
const char *message2 = "Thread 2";
// 스레드 생성
pthread_create(&thread1, NULL, print_message, (void*) message1);
pthread_create(&thread2, NULL, print_message, (void*) message2);
// 스레드 종료 대기
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
return 0;
}
위의 예제에서 두 개의 스레드를 생성하여 각각의 메시지를 출력합니다. pthread_create 함수는 새로운 스레드를 생성하고, pthread_join 함수는 스레드가 종료될 때까지 대기합니다.
이번 글에서는 C 언어의 고급 주제에 대해 알아보았습니다. 이러한 고급 기능을 통해 보다 복잡하고 효율적인 프로그램을 작성할 수 있습니다. C 언어 학습에 많은 도움이 되길 바랍니다. Happy Coding!
'프로그래밍 > C' 카테고리의 다른 글
[C] 12. C언어의 "프로젝트 및 실습(기타)" (0) | 2024.06.14 |
---|---|
[C] 10. C언어의 "메모리 관리(기타)" (1) | 2024.06.14 |
[C] 9. C언어의 "파일 입출력(기타)" (2) | 2024.06.13 |
[C] 8. C언어의 "구조체" (0) | 2024.06.13 |
[C] 7. C언어의 "포인터" (0) | 2024.06.13 |