1. 初识C语言
C语言是一种广泛使用的计算机编程语言,以其高效性和灵活性而闻名。它是一种过程式语言,主要用于系统软件开发、嵌入式系统、游戏开发等领域。学习C语言,首先要了解它的基本语法和数据结构。
实例1:第一个C语言程序
#include <stdio.h>
int main() {
printf("Hello, World!\n");
return 0;
}
这个简单的程序会输出“Hello, World!”到控制台。
2. 数据类型与变量
在C语言中,数据类型决定了变量的存储方式和大小。常见的有整型(int)、浮点型(float)、字符型(char)等。
实例2:声明和初始化变量
int a = 10;
float b = 3.14;
char c = 'A';
这里声明了三个变量,并分别初始化。
3. 控制语句
控制语句用于控制程序的流程,包括条件语句(if-else)、循环语句(for、while、do-while)等。
实例3:使用if-else语句
#include <stdio.h>
int main() {
int age = 18;
if (age >= 18) {
printf("你已经成年了!\n");
} else {
printf("你还没有成年。\n");
}
return 0;
}
这个程序会根据年龄判断是否成年。
4. 数组
数组是一组相同类型的元素的集合。在C语言中,可以通过下标访问数组元素。
实例4:声明和初始化数组
int numbers[5] = {1, 2, 3, 4, 5};
这里声明了一个包含5个整数的数组,并进行了初始化。
5. 函数
函数是C语言中用于组织代码的重要工具,它可以将一段代码封装起来,方便复用。
实例5:编写简单的函数
#include <stdio.h>
void printMessage() {
printf("这是一个函数!\n");
}
int main() {
printMessage();
return 0;
}
这个程序定义了一个函数printMessage,并在main函数中调用它。
6. 指针
指针是C语言中的一个重要概念,它用于存储变量的内存地址。
实例6:使用指针
#include <stdio.h>
int main() {
int a = 10;
int *ptr = &a;
printf("a的地址是:%p\n", (void *)ptr);
printf("ptr指向的值是:%d\n", *ptr);
return 0;
}
这个程序演示了如何使用指针获取变量的地址和值。
7. 结构体
结构体是一种用于组合不同类型数据的数据类型。
实例7:定义和初始化结构体
#include <stdio.h>
struct Person {
char name[50];
int age;
};
int main() {
struct Person p1;
strcpy(p1.name, "张三");
p1.age = 25;
printf("姓名:%s,年龄:%d\n", p1.name, p1.age);
return 0;
}
这个程序定义了一个Person结构体,并创建了一个结构体变量p1进行初始化。
8. 文件操作
C语言提供了丰富的文件操作函数,可以用于读写文件。
实例8:读取文件内容
#include <stdio.h>
int main() {
FILE *fp = fopen("example.txt", "r");
if (fp == NULL) {
printf("无法打开文件。\n");
return 1;
}
char ch;
while ((ch = fgetc(fp)) != EOF) {
putchar(ch);
}
fclose(fp);
return 0;
}
这个程序读取了名为example.txt的文件,并将其内容输出到控制台。
9. 动态内存分配
动态内存分配可以让我们在程序运行时根据需要分配内存。
实例9:动态分配内存
#include <stdio.h>
#include <stdlib.h>
int main() {
int *arr = (int *)malloc(5 * sizeof(int));
if (arr == NULL) {
printf("内存分配失败。\n");
return 1;
}
for (int i = 0; i < 5; i++) {
arr[i] = i + 1;
}
for (int i = 0; i < 5; i++) {
printf("%d ", arr[i]);
}
printf("\n");
free(arr);
return 0;
}
这个程序使用malloc函数动态分配了一个包含5个整数的数组,并进行了初始化和释放。
10. C语言中的字符串操作
C语言提供了丰富的字符串操作函数,如strlen、strcpy、strcmp等。
实例10:字符串操作
#include <stdio.h>
#include <string.h>
int main() {
char str1[100] = "Hello";
char str2[100] = "World";
printf("str1的长度:%d\n", strlen(str1));
strcpy(str1, str2);
printf("str1:%s\n", str1);
printf("str1和str2是否相等:%d\n", strcmp(str1, str2));
return 0;
}
这个程序演示了字符串的长度、复制和比较操作。
11. 预处理指令
预处理指令是C语言中的一个重要特性,它允许我们在编译前对代码进行修改。
实例11:宏定义
#include <stdio.h>
#define PI 3.14159
int main() {
printf("PI的值:%f\n", PI);
return 0;
}
这个程序使用宏定义定义了PI的值。
12. C语言中的错误处理
错误处理是编写健壮程序的关键。
实例12:使用返回值判断函数执行结果
#include <stdio.h>
int divide(int a, int b) {
if (b == 0) {
return -1;
}
return a / b;
}
int main() {
int result = divide(10, 2);
if (result == -1) {
printf("除数不能为0。\n");
} else {
printf("结果:%d\n", result);
}
return 0;
}
这个程序使用返回值来判断divide函数的执行结果。
13. C语言中的位操作
位操作是C语言中的一个强大特性,它允许我们直接操作计算机的位。
实例13:位与操作
#include <stdio.h>
int main() {
int a = 5; // 0101
int b = 3; // 0011
printf("a & b:%d\n", a & b); // 0001
return 0;
}
这个程序演示了位与操作。
14. C语言中的结构体数组和指针
结构体数组和指针在C语言中非常有用,它们可以用于处理更复杂的数据结构。
实例14:使用结构体指针
#include <stdio.h>
struct Person {
char name[50];
int age;
};
int main() {
struct Person p1;
strcpy(p1.name, "张三");
p1.age = 25;
struct Person *ptr = &p1;
printf("姓名:%s,年龄:%d\n", ptr->name, ptr->age);
return 0;
}
这个程序演示了如何使用结构体指针访问结构体成员。
15. C语言中的动态链接库
动态链接库是一种用于复用代码和资源的有效方式。
实例15:使用动态链接库
#include <stdio.h>
#include <dlfcn.h>
int main() {
void *handle = dlopen("libexample.so", RTLD_LAZY);
if (!handle) {
fprintf(stderr, "无法加载库:%s\n", dlerror());
return 1;
}
int (*add)(int, int);
*(void **)(&add) = dlsym(handle, "add");
if (!add) {
fprintf(stderr, "无法找到函数:%s\n", dlerror());
dlclose(handle);
return 1;
}
printf("add(2, 3):%d\n", add(2, 3));
dlclose(handle);
return 0;
}
这个程序演示了如何使用动态链接库。
16. C语言中的网络编程
C语言提供了丰富的网络编程库,如socket编程。
实例16:使用socket编程发送数据
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
int main() {
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
perror("创建socket失败");
return 1;
}
struct sockaddr_in server_addr;
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(8080);
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
if (connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
perror("连接服务器失败");
close(sockfd);
return 1;
}
char buffer[1024];
sprintf(buffer, "GET / HTTP/1.1\r\nHost: 127.0.0.1\r\n\r\n");
send(sockfd, buffer, strlen(buffer), 0);
int bytes_received;
char response[1024];
while ((bytes_received = recv(sockfd, response, sizeof(response), 0)) > 0) {
fwrite(response, 1, bytes_received, stdout);
}
close(sockfd);
return 0;
}
这个程序演示了如何使用socket编程发送HTTP请求。
17. C语言中的多线程编程
C语言提供了POSIX线程库(pthread),用于实现多线程编程。
实例17:使用pthread创建线程
#include <stdio.h>
#include <pthread.h>
void *threadFunction(void *arg) {
printf("线程ID:%ld\n", pthread_self());
return NULL;
}
int main() {
pthread_t tid;
if (pthread_create(&tid, NULL, threadFunction, NULL) != 0) {
perror("创建线程失败");
return 1;
}
pthread_join(tid, NULL);
return 0;
}
这个程序创建了一个线程并执行了threadFunction函数。
18. C语言中的多进程编程
C语言提供了POSIX进程库(unistd),用于实现多进程编程。
实例18:使用fork创建进程
#include <stdio.h>
#include <unistd.h>
int main() {
pid_t pid = fork();
if (pid == 0) {
// 子进程
printf("子进程ID:%d,父进程ID:%d\n", getpid(), getppid());
} else if (pid > 0) {
// 父进程
printf("父进程ID:%d,子进程ID:%d\n", getpid(), pid);
} else {
// 创建进程失败
perror("创建进程失败");
return 1;
}
return 0;
}
这个程序使用fork函数创建了一个子进程。
19. C语言中的信号处理
信号是C语言中用于处理异步事件的一种机制。
实例19:使用信号处理
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
void signalHandler(int signum) {
printf("捕获信号:%d\n", signum);
_exit(0);
}
int main() {
signal(SIGINT, signalHandler);
while (1) {
printf("等待信号...\n");
sleep(1);
}
return 0;
}
这个程序捕获了SIGINT信号,并在接收到该信号时退出。
20. C语言中的文件锁定
文件锁定是一种用于保护文件不被多个进程同时访问的机制。
实例20:使用文件锁定
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
int main() {
int fd = open("example.txt", O_RDWR | O_CREAT, 0666);
if (fd == -1) {
perror("打开文件失败");
return 1;
}
struct flock lock;
memset(&lock, 0, sizeof(lock));
lock.l_type = F_WRLCK;
fcntl(fd, F_SETLK, &lock);
printf("文件已锁定。\n");
sleep(5);
lock.l_type = F_UNLCK;
fcntl(fd, F_SETLK, &lock);
close(fd);
return 0;
}
这个程序演示了如何使用文件锁定。
21. C语言中的内存映射
内存映射是一种将文件内容映射到进程地址空间的技术。
实例21:使用内存映射
#include <stdio.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
int main() {
int fd = open("example.txt", O_RDONLY);
if (fd == -1) {
perror("打开文件失败");
return 1;
}
char *map = mmap(NULL, 1024, PROT_READ, MAP_PRIVATE, fd, 0);
if (map == MAP_FAILED) {
perror("内存映射失败");
close(fd);
return 1;
}
printf("文件内容:%s\n", map);
munmap(map, 1024);
close(fd);
return 0;
}
这个程序演示了如何使用内存映射读取文件内容。
22. C语言中的网络编程——TCP客户端
C语言提供了丰富的网络编程库,包括TCP客户端编程。
实例22:使用socket编程创建TCP客户端
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
int main() {
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
perror("创建socket失败");
return 1;
}
struct sockaddr_in server_addr;
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(8080);
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
if (connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
perror("连接服务器失败");
close(sockfd);
return 1;
}
char buffer[1024];
sprintf(buffer, "GET / HTTP/1.1\r\nHost: 127.0.0.1\r\n\r\n");
send(sockfd, buffer, strlen(buffer), 0);
int bytes_received;
char response[1024];
while ((bytes_received = recv(sockfd, response, sizeof(response), 0)) > 0) {
fwrite(response, 1, bytes_received, stdout);
}
close(sockfd);
return 0;
}
这个程序演示了如何使用socket编程创建一个TCP客户端。
23. C语言中的网络编程——TCP服务器
C语言提供了丰富的网络编程库,包括TCP服务器编程。
实例23:使用socket编程创建TCP服务器
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
int main() {
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
perror("创建socket失败");
return 1;
}
struct sockaddr_in server_addr, client_addr;
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(8080);
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
if (bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
perror("绑定socket失败");
close(sockfd);
return 1;
}
listen(sockfd, 5);
socklen_t client_addr_len = sizeof(client_addr);
int client_sockfd = accept(sockfd, (struct sockaddr *)&client_addr, &client_addr_len);
if (client_sockfd < 0) {
perror("接受连接失败");
close(sockfd);
return 1;
}
char buffer[1024];
while (1) {
int bytes_received = recv(client_sockfd, buffer, sizeof(buffer), 0);
if (bytes_received <= 0) {
break;
}
send(client_sockfd, buffer, bytes_received, 0);
}
close(client_sockfd);
close(sockfd);
return 0;
}
这个程序演示了如何使用socket编程创建一个TCP服务器。
24. C语言中的网络编程——UDP编程
C语言提供了丰富的网络编程库,包括UDP编程。
实例24:使用socket编程创建UDP客户端
”`c
#include
int main() {
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0) {
perror("创建socket失败");
return 1;
}
struct sockaddr_in server_addr;
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(8080);
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
char buffer[1024];
sprintf(buffer, "Hello, UDP Server!");
sendto(sockfd, buffer, strlen(buffer), 0, (struct sockaddr *)&server_addr, sizeof(server_addr));
int bytes_received;
char response[1024];
struct sockaddr_in client_addr;
socklen_t client_addr_len = sizeof(client_addr);
while ((bytes_received = recvfrom(sockfd, response, sizeof(response), 0, (struct sockaddr *)&client
