引言
C语言是一种广泛使用的高级编程语言,以其灵活性和高效性在软件开发领域占据重要地位。对于初学者来说,C语言的学习往往从基础的语法和概念开始,但随着技能的提升,深入理解编程思想以及实际应用变得尤为重要。本文将带领你从C语言的入门知识出发,通过50个经典实例,一步步深入理解C语言编程,最终能够将所学知识应用到实际项目中。
第一章:C语言基础入门
1.1 C语言简介
C语言由Dennis Ritchie于1972年发明,最初是为了编写操作系统Unix而设计的。它具有结构化、高效、可移植等特点,至今仍是计算机科学教育中不可或缺的一部分。
1.2 基本语法
- 变量和数据类型
- 运算符和表达式
- 控制结构(if-else,for,while)
1.3 编程实例1:Hello World
#include <stdio.h>
int main() {
printf("Hello, World!\n");
return 0;
}
第二章:C语言进阶知识
2.1 函数和模块化编程
- 函数的定义和调用
- 参数传递和局部变量
- 编程实例2:计算两个数的和
2.2 数组和字符串
- 一维数组和多维数组
- 字符串操作
- 编程实例3:字符串排序
2.3 指针和内存管理
- 指针的基本概念
- 动态内存分配
- 编程实例4:复制一个字符串
第三章:C语言高级应用
3.1 结构体和联合体
- 结构体的定义和使用
- 联合体的概念
- 编程实例5:定义一个学生结构体
3.2 位操作
- 位运算符
- 位字段
- 编程实例6:计算整数的奇偶性
3.3 文件操作
- 文件的打开、读取和关闭
- 文件读写操作
- 编程实例7:读取文本文件内容
第四章:50个经典实例深度解析
4.1 实例1:实现冒泡排序算法
void bubbleSort(int arr[], int n) {
int i, j, temp;
for (i = 0; i < n-1; i++) {
for (j = 0; j < n-i-1; j++) {
if (arr[j] > arr[j+1]) {
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}
4.2 实例2:实现递归函数计算阶乘
unsigned long factorial(unsigned int n) {
if (n <= 1)
return 1;
else
return n * factorial(n - 1);
}
4.3 实例3:使用结构体实现学生管理系统
#include <stdio.h>
#define MAX_STUDENTS 100
typedef struct {
int id;
char name[50];
float score;
} Student;
void addStudent(Student students[], int *studentCount, Student newStudent) {
students[*studentCount] = newStudent;
(*studentCount)++;
}
void printStudents(Student students[], int studentCount) {
for (int i = 0; i < studentCount; i++) {
printf("ID: %d, Name: %s, Score: %.2f\n", students[i].id, students[i].name, students[i].score);
}
}
int main() {
Student students[MAX_STUDENTS];
int studentCount = 0;
// 添加学生信息
addStudent(students, &studentCount, (Student){1, "Alice", 92.5});
addStudent(students, &studentCount, (Student){2, "Bob", 85.0});
addStudent(students, &studentCount, (Student){3, "Charlie", 78.0});
// 打印学生信息
printStudents(students, studentCount);
return 0;
}
4.4 实例4:实现一个简单的命令行计算器
#include <stdio.h>
#include <stdlib.h>
double add(double a, double b) {
return a + b;
}
double subtract(double a, double b) {
return a - b;
}
double multiply(double a, double b) {
return a * b;
}
double divide(double a, double b) {
if (b != 0)
return a / b;
else
return 0;
}
int main() {
char operator;
double num1, num2;
printf("Enter an operator (+, -, *, /): ");
scanf(" %c", &operator);
printf("Enter two operands: ");
scanf("%lf %lf", &num1, &num2);
switch (operator) {
case '+':
printf("%.1lf\n", add(num1, num2));
break;
case '-':
printf("%.1lf\n", subtract(num1, num2));
break;
case '*':
printf("%.1lf\n", multiply(num1, num2));
break;
case '/':
printf("%.1lf\n", divide(num1, num2));
break;
default:
printf("Error! operator is not correct\n");
}
return 0;
}
4.5 实例5:实现一个简单的文本编辑器
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFFER_SIZE 1024
void appendToFile(FILE *file, const char *text) {
fprintf(file, "%s", text);
}
void readFile(const char *filename) {
FILE *file = fopen(filename, "r");
if (file == NULL) {
printf("Error opening file\n");
return;
}
char buffer[BUFFER_SIZE];
while (fgets(buffer, BUFFER_SIZE, file)) {
printf("%s", buffer);
}
fclose(file);
}
int main() {
char filename[50];
char text[256];
printf("Enter the filename: ");
scanf("%s", filename);
printf("Enter the text to append: ");
fgets(text, 256, stdin);
text[strcspn(text, "\n")] = 0; // Remove newline character
appendToFile fopen(filename, "a"), text;
readFile(filename);
return 0;
}
4.6 实例6:实现一个简单的Web服务器
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#define PORT 8080
void handleClient(int clientSocket) {
char request[1024];
char response[2048];
if (fgets(request, sizeof(request), stdin) != NULL) {
if (strncmp(request, "GET / HTTP/1.1", 18) == 0) {
strcpy(response, "HTTP/1.1 200 OK\r\n");
strcpy(response + 20, "Content-Type: text/html\r\n\r\n");
strcpy(response + 36, "<html><head><title>Hello World</title></head>");
strcpy(response + 66, "<body>Hello, World!</body></html>\r\n");
send(clientSocket, response, strlen(response), 0);
}
}
close(clientSocket);
}
int main() {
int serverSocket, clientSocket;
struct sockaddr_in serverAddr, clientAddr;
socklen_t clientAddrSize = sizeof(clientAddr);
serverSocket = socket(AF_INET, SOCK_STREAM, 0);
if (serverSocket < 0) {
printf("Error creating socket\n");
return 1;
}
memset(&serverAddr, 0, sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = INADDR_ANY;
serverAddr.sin_port = htons(PORT);
if (bind(serverSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0) {
printf("Error binding to port %d\n", PORT);
return 1;
}
if (listen(serverSocket, 5) < 0) {
printf("Error listening on port %d\n", PORT);
return 1;
}
while (1) {
clientSocket = accept(serverSocket, (struct sockaddr *)&clientAddr, &clientAddrSize);
if (clientSocket < 0) {
printf("Error accepting connection\n");
continue;
}
handleClient(clientSocket);
}
close(serverSocket);
return 0;
}
4.7 实例7:实现一个简单的TCP客户端
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define PORT 8080
int main() {
int socketId;
struct sockaddr_in serverAddr;
char buffer[1024];
socketId = socket(AF_INET, SOCK_STREAM, 0);
if (socketId < 0) {
printf("Error creating socket\n");
return 1;
}
memset(&serverAddr, 0, sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(PORT);
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
if (connect(socketId, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0) {
printf("Error connecting to server\n");
return 1;
}
printf("Enter message to send: ");
fgets(buffer, sizeof(buffer), stdin);
buffer[strcspn(buffer, "\n")] = 0; // Remove newline character
send(socketId, buffer, strlen(buffer), 0);
if (recv(socketId, buffer, sizeof(buffer), 0) < 0) {
printf("Error receiving response from server\n");
return 1;
}
printf("Response from server: %s\n", buffer);
close(socketId);
return 0;
}
4.8 实例8:实现一个简单的UDP客户端
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define PORT 8080
int main() {
int socketId;
struct sockaddr_in serverAddr;
char buffer[1024];
socketId = socket(AF_INET, SOCK_DGRAM, 0);
if (socketId < 0) {
printf("Error creating socket\n");
return 1;
}
memset(&serverAddr, 0, sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(PORT);
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
printf("Enter message to send: ");
fgets(buffer, sizeof(buffer), stdin);
buffer[strcspn(buffer, "\n")] = 0; // Remove newline character
sendto(socketId, buffer, strlen(buffer), 0, (struct sockaddr *)&serverAddr, sizeof(serverAddr));
if (recvfrom(socketId, buffer, sizeof(buffer), 0, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0) {
printf("Error receiving response from server\n");
return 1;
}
printf("Response from server: %s\n", buffer);
close(socketId);
return 0;
}
4.9 实例9:实现一个简单的UDP服务器
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define PORT 8080
int main() {
int socketId;
struct sockaddr_in serverAddr, clientAddr;
socklen_t clientAddrSize = sizeof(clientAddr);
char buffer[1024];
socketId = socket(AF_INET, SOCK_DGRAM, 0);
if (socketId < 0) {
printf("Error creating socket\n");
return 1;
}
memset(&serverAddr, 0, sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(PORT);
serverAddr.sin_addr.s_addr = INADDR_ANY;
if (bind(socketId, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0) {
printf("Error binding to port %d\n", PORT);
return 1;
}
while (1) {
if (recvfrom(socketId, buffer, sizeof(buffer), 0, (struct sockaddr *)&clientAddr, &clientAddrSize) < 0) {
printf("Error receiving data\n");
continue;
}
printf("Received message from client: %s\n", buffer);
strcpy(buffer, "Hello, client!");
sendto(socketId, buffer, strlen(buffer), 0, (struct sockaddr *)&clientAddr, clientAddrSize);
}
close(socketId);
return 0;
}
4.10 实例10:实现一个简单的线程池
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#define THREAD_COUNT 4
typedef struct {
int id;
char *task;
} ThreadPoolTask;
typedef struct {
pthread_t threads[THREAD_COUNT];
int next;
} ThreadPool;
void *threadFunction(void *arg) {
ThreadPoolTask *task = (ThreadPoolTask *)arg;
printf("Thread %d running task: %s\n", task->id, task->task);
free(task);
return NULL;
}
ThreadPool pool;
void threadPoolInit() {
pool.next = 0;
for (int i = 0; i < THREAD_COUNT; i++) {
pthread_create(&pool.threads[i], NULL, threadFunction, (void *)&(pool.next));
}
}
void threadPoolAddTask(const char *task) {
ThreadPoolTask *newTask = malloc(sizeof(ThreadPoolTask));
newTask->id = pool.next;
newTask->task = strdup(task);
pthread_create(&pool.threads[pool.next % THREAD_COUNT], NULL, threadFunction, newTask);
pool.next++;
}
int main() {
threadPoolInit();
threadPoolAddTask("Task 1");
threadPoolAddTask("Task 2");
threadPoolAddTask("Task 3");
threadPoolAddTask("Task 4");
sleep(10);
return 0;
}
4.11 实例11:实现一个简单的互斥锁
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
pthread_mutex_t lock;
void threadFunction(void *arg) {
pthread_mutex_lock(&lock);
printf("Thread %d acquired lock\n", (int)arg);
sleep(1);
pthread_mutex_unlock(&lock);
}
int main() {
pthread_mutex_init(&lock, NULL);
pthread_t threads[5];
for (int i = 0; i < 5; i++) {
pthread_create(&threads[i], NULL, threadFunction, (void *)(intptr_t)i);
}
for (int i = 0; i < 5; i++) {
pthread_join(threads[i], NULL);
}
pthread_mutex_destroy(&lock);
return 0;
}
4.12 实例13:实现一个简单的条件变量
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
pthread_mutex_t lock;
pthread_cond_t cond;
void producerFunction(void *arg) {
pthread_mutex_lock(&lock);
printf("Producing item\n");
sleep(1);
pthread_cond_signal(&cond);
pthread_mutex_unlock(&lock);
}
void consumerFunction(void *arg) {
pthread_mutex_lock(&lock);
pthread_cond_wait(&cond, &lock);
printf("Consuming item\n");
pthread_mutex_unlock(&lock);
}
int main() {
pthread_mutex_init(&lock, NULL);
pthread_cond_init(&cond, NULL);
pthread_t producerThread, consumerThread;
pthread_create(&producerThread, NULL, producerFunction, NULL);
pthread_create(&consumerThread, NULL, consumerFunction, NULL);
pthread_join(producerThread, NULL);
pthread_join(consumerThread, NULL);
pthread_mutex_destroy(&lock);
pthread_cond_destroy(&cond);
return 0;
}
4.13 实例14:实现一个简单的线程同步队列
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define QUEUE_SIZE 10
typedef struct {
int items[QUEUE_SIZE];
int head;
int tail;
int count;
} Queue;
Queue queue;
pthread_mutex_t lock;
pthread_cond_t notFull;
pthread_cond_t notEmpty;
void enqueue(int item) {
pthread_mutex_lock(&lock);
while (queue.count == QUEUE_SIZE) {
pthread_cond_wait(¬Full, &lock);
}
queue.items[queue.tail] = item;
queue.tail = (queue.tail + 1) % QUEUE_SIZE;
queue.count++;
pthread_cond_signal(¬Empty);
pthread_mutex_unlock(&lock);
}
int dequeue() {
pthread_mutex_lock(&lock);
while (queue.count == 0) {
pthread_cond_wait(¬Empty, &lock);
}
int item = queue.items[queue.head];
queue.head = (queue.head + 1) % QUEUE_SIZE;
queue.count--;
pthread_cond_signal(¬Full);
pthread_mutex_unlock(&lock);
return item;
}
int main() {
pthread_mutex_init(&lock, NULL);
pthread_cond_init(¬Full, NULL);
pthread_cond_init(¬Empty, NULL);
for (int i = 0; i < 10; i++) {
enqueue(i);
}
for (int i = 0; i < 10; i++) {
printf("Dequeued item: %d\n", dequeue());
}
pthread_mutex_destroy(&lock);
pthread_cond_destroy(¬Full);
pthread_cond_destroy(¬Empty);
return 0;
}
4.14 实例15:实现一个简单的网络爬虫
”`c
#include
#define MAX_URL_LENGTH 1024
void fetchWebpage(const char *url) {
int socketId;
struct sockaddr_in serverAddr;
char request[1024];
char response[4096];
socketId = socket(AF_INET, SOCK_STREAM, 0);
if (socketId < 0)
