当前位置: 首页 > news >正文

C语言基础教程--从入门到精通

C语言基础教程–从入门到精通(总体概括)

接下来会对每一个章节进行详细的总结与整理,希望对大家有用!大家一起学习!

目录

  • C语言基础教程--从入门到精通(总体概括)
    • **`接下来会对每一个章节进行详细的总结与整理,希望对大家有用!大家一起学习!`**
  • 第一章:C 语言概述与环境搭建
    • 1.1 C 语言简介
    • 1.2 开发环境搭建
    • 1.3 第一个 C 程序
  • 第二章:基本语法与数据类型
    • 2.1 变量与常量`int age = 25; // 整型变量
    • 2.2 基本数据类型
    • 2.3 输入输出
  • 第三章:运算符与表达式
    • 3.1 算术运算符
    • 3.2 关系运算符
    • 3.3 逻辑运算符
  • 第四章:控制结构
    • 4.1 条件语句
    • 4.2 循环结构
  • 第五章:函数
    • 5.1 函数定义与调用
    • 5.2 递归函数
  • 第六章:数组与字符串
    • 6.1 一维数组
    • 6.2 多维数组
    • 6.3 字符串处理
  • 第七章:指针
    • 7.1 指针基础
    • 7.2 指针与数组
    • 7.3 指针与函数
  • 第八章:结构体与联合体
    • 8.1 结构体定义与使用
    • 8.2 联合体
  • 第九章:文件操作
    • 9.1 文件读写基础
    • 9.2 二进制文件操作
  • 第十章:动态内存管理
    • 10.1 malloc 和 free
    • 10.2 calloc 和 realloc
  • 第十一章:高级主题
    • 11.1 函数指针
    • 11.2 多文件编程
  • 第十二章:最佳实践与调试
    • 12.1 代码规范
    • 12.2 调试技巧
    • 12.3 常见错误

第一章:C 语言概述与环境搭建

1.1 C 语言简介

C 语言由 Dennis Ritchie 于 1972 年在贝尔实验室开发,是一种高效灵活的通用编程语言。它结合了低级语言的高效性和高级语言的可读性,被称为"系统编程语言"的基石。

主要特点:

1.结构化编程
2.内存直接访问
3.高效执行速度
4.丰富的运算符
5.可移植性强

1.2 开发环境搭建

Windows 环境:

1.安装 MinGW(GCC for Windows)
2.安装代码编辑器(VS Code、Dev-C++)
3.配置环境变量

Linux/macOS 环境:

# 安装 GCC
sudo apt-get install gcc   # Ubuntu/Debian
brew install gcc           # macOS# 验证安装
gcc --version

1.3 第一个 C 程序

#include <stdio.h>  // 标准输入输出头文件int main() {         // 程序入口函数printf("Hello, World!\n");  // 输出语句return 0;        // 程序正常结束
}

编译与运行:

gcc hello.c -o hello  # 编译
./hello               # 运行 (Linux/macOS)
hello.exe             # 运行 (Windows)

第二章:基本语法与数据类型

2.1 变量与常量`int age = 25; // 整型变量

float salary = 8500.50; // 浮点型变量
const double PI = 3.14159; // 常量
char grade = ‘A’; // 字符变量`

2.2 基本数据类型

类型大小 (字节)范围格式说明符
char1-128 到 127%c
int4-2^31 到 2^31-1%d
float43.4E-38 到 3.4E+38%f
double81.7E-308 到 1.7E+308%lf
void无值

2.3 输入输出

#include <stdio.h>int main() {int num;printf("请输入一个整数: ");scanf("%d", &num);  // 读取输入printf("你输入的是: %d\n", num);printf("浮点数: %.2f\n", 3.14159); // 保留两位小数return 0;
}

第三章:运算符与表达式

3.1 算术运算符

int a = 10, b = 3;
int sum = a + b;      // 13
int diff = a - b;     // 7
int product = a * b;  // 30
int quotient = a / b; // 3 (整数除法)
int remainder = a % b; // 1

3.2 关系运算符

int x = 5, y = 10;
printf("%d\n", x == y); // 0 (false)
printf("%d\n", x != y); // 1 (true)
printf("%d\n", x > y);  // 0
printf("%d\n", x < y);  // 1

3.3 逻辑运算符

int age = 25;
int hasLicense = 1; // trueif (age >= 18 && hasLicense) {printf("可以开车\n");
}if (age < 18 || !hasLicense) {printf("不能开车\n");
}

第四章:控制结构

4.1 条件语句

// if-else
int score = 85;
if (score >= 90) {printf("优秀\n");
} else if (score >= 60) {printf("及格\n");
} else {printf("不及格\n");
}// switch-case
char grade = 'B';
switch(grade) {case 'A': printf("优秀\n");break;case 'B': printf("良好\n");break;default:printf("其他\n");
}

4.2 循环结构

// for 循环
for(int i = 0; i < 5; i++) {printf("%d ", i); // 0 1 2 3 4
}// while 循环
int count = 5;
while(count > 0) {printf("%d ", count--); // 5 4 3 2 1
}// do-while 循环
int num;
do {printf("请输入正数: ");scanf("%d", &num);
} while(num <= 0);

第五章:函数

5.1 函数定义与调用

#include <stdio.h>// 函数声明
int add(int a, int b);int main() {int result = add(5, 3);printf("5 + 3 = %d\n", result);return 0;
}// 函数定义
int add(int a, int b) {return a + b;
}

5.2 递归函数

// 计算阶乘
int factorial(int n) {if (n == 0 || n == 1)return 1;elsereturn n * factorial(n - 1);
}int main() {printf("5! = %d\n", factorial(5)); // 120return 0;
}

第六章:数组与字符串

6.1 一维数组

// 声明与初始化
int numbers[5] = {1, 2, 3, 4, 5};// 访问元素
printf("第一个元素: %d\n", numbers[0]); // 1// 遍历数组
for(int i = 0; i < 5; i++) {printf("%d ", numbers[i]);
}

6.2 多维数组

// 二维数组(矩阵)
int matrix[2][3] = {{1, 2, 3},{4, 5, 6}
};// 访问元素
printf("第二行第一列: %d\n", matrix[1][0]); // 4

6.3 字符串处理

注意:这段代码在运行时可能会报错,主要原因是缓冲区溢出问题。

#include <string.h>char str1[20] = "Hello";
char str2[] = "World";// 字符串连接
strcat(str1, " ");
strcat(str1, str2); // "Hello World"// 字符串长度
int len = strlen(str1); // 11// 字符串比较
if(strcmp(str1, "Hello World") == 0) {printf("字符串相等\n");
}

错误原因分析:

1.内存计算错误:

初始str1内容:“Hello”(5字符) + ‘\0’ = 6字节
添加空格后:"Hello "(6字符) + ‘\0’ = 7字节
添加"World"后:“Hello World”(11字符) + ‘\0’ = 12字节
虽然12 < 20,但问题出在strcat的工作机制

2.strcat函数的工作方式:

strcat会从目标字符串的结束符’\0’处开始追加新内容
第一次strcat(str1, " “)后:str1变为"Hello \0”
第二次strcat(str1, str2)时:
从’ ‘后的’\0’开始覆盖
追加"World"(5字符)和结束符’\0’
最终得到"Hello World\0"(12字节)

缓冲区溢出风险:

虽然本例最终长度12 < 20,但如果初始数组更小(如char str1[12]),会溢出
实际开发中这种写法有隐患

解决方案
方法1:确保足够缓冲区 + 安全初始化

#include <stdio.h>
#include <string.h>int main() {// 增大缓冲区并初始化为全零char str1[20] = {0};char str2[] = "World";// 安全拷贝初始值strcpy(str1, "Hello");strcat(str1, " ");strcat(str1, str2);printf("连接结果: %s\n", str1); // Hello Worldprintf("长度: %zu\n", strlen(str1)); // 11if(strcmp(str1, "Hello World") == 0) {printf("字符串相等\n");}return 0;
}

方法2:使用更安全的 snprintf (推荐)

#include <stdio.h>
#include <string.h>int main() {char str1[20];const char* str2 = "World";// 安全格式化拼接snprintf(str1, sizeof(str1), "%s %s", "Hello", str2);printf("结果: %s\n", str1);return 0;
}

方法3:手动控制拼接过程

#include <stdio.h>
#include <string.h>int main() {char str1[20] = "Hello";char str2[] = "World";// 计算剩余空间size_t remain = sizeof(str1) - strlen(str1) - 1; // 安全追加strncat(str1, " ", remain);remain -= 1;  // 更新剩余空间strncat(str1, str2, remain);printf("%s\n", str1);return 0;
}

为什么原始代码可能崩溃:

如果编译器在内存中布局时,str1后面紧跟着受保护的内存区域,即使12<20,连续两次strcat操作可能触发内存保护机制(如Stack Canary)。使用安全函数可避免这类问题。

第七章:指针

7.1 指针基础

int num = 10;
int *ptr = &num; // ptr指向num的地址printf("num的值: %d\n", num);     // 10
printf("num的地址: %p\n", &num);  // 内存地址
printf("ptr的值: %p\n", ptr);     // 与&num相同
printf("ptr指向的值: %d\n", *ptr); // 10

7.2 指针与数组

int arr[3] = {10, 20, 30};
int *ptr = arr; // 指向数组首元素printf("第一个元素: %d\n", *ptr);      // 10
printf("第二个元素: %d\n", *(ptr+1));  // 20

7.3 指针与函数

// 通过指针交换两个变量的值
void swap(int *a, int *b) {int temp = *a;*a = *b;*b = temp;
}int main() {int x = 5, y = 10;swap(&x, &y);printf("x=%d, y=%d", x, y); // x=10, y=5return 0;
}

第八章:结构体与联合体

8.1 结构体定义与使用

// 定义结构体
struct Student {char name[50];int age;float gpa;
};int main() {// 声明结构体变量struct Student stu1;// 访问成员strcpy(stu1.name, "张三");stu1.age = 20;stu1.gpa = 3.8;// 结构体指针struct Student *ptr = &stu1;printf("姓名: %s\n", ptr->name); // 张三return 0;
}

8.2 联合体

union Data {int i;float f;char str[20];
};int main() {union Data data;data.i = 10;printf("整数: %d\n", data.i);data.f = 3.14;printf("浮点数: %.2f\n", data.f); // 覆盖之前的值return 0;
}

第九章:文件操作

9.1 文件读写基础

#include <stdio.h>int main() {FILE *file;// 写入文件file = fopen("test.txt", "w");if(file != NULL) {fprintf(file, "Hello, File!\n");fclose(file);}// 读取文件char buffer[100];file = fopen("test.txt", "r");if(file != NULL) {while(fgets(buffer, 100, file) != NULL) {printf("%s", buffer);}fclose(file);}return 0;
}

9.2 二进制文件操作

struct Product {int id;char name[50];float price;
};int main() {// 写入二进制数据struct Product p1 = {1, "Laptop", 999.99};FILE *file = fopen("products.dat", "wb");fwrite(&p1, sizeof(struct Product), 1, file);fclose(file);// 读取二进制数据struct Product p2;file = fopen("products.dat", "rb");fread(&p2, sizeof(struct Product), 1, file);printf("产品: %s, 价格: %.2f\n", p2.name, p2.price);fclose(file);return 0;
}

第十章:动态内存管理

10.1 malloc 和 free

#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 * 10;}// 释放内存free(arr);return 0;
}

10.2 calloc 和 realloc

int main() {// 分配并初始化内存int *arr = (int*)calloc(5, sizeof(int));// 重新分配内存arr = (int*)realloc(arr, 10 * sizeof(int));// 使用更大的数组for(int i = 5; i < 10; i++) {arr[i] = i * 10;}// 释放内存free(arr);return 0;
}

第十一章:高级主题

11.1 函数指针

#include <stdio.h>// 加法函数
int add(int a, int b) {return a + b;
}// 减法函数
int subtract(int a, int b) {return a - b;
}int main() {// 声明函数指针int (*operation)(int, int);// 指向加法函数operation = add;printf("5 + 3 = %d\n", operation(5, 3));// 指向减法函数operation = subtract;printf("5 - 3 = %d\n", operation(5, 3));return 0;
}

11.2 多文件编程

main.c:

#include <stdio.h>
#include "math_operations.h"int main() {printf("5 + 3 = %d\n", add(5, 3));printf("5 - 3 = %d\n", subtract(5, 3));return 0;
}

math_operations.h:

#ifndef MATH_OPERATIONS_H
#define MATH_OPERATIONS_Hint add(int a, int b);
int subtract(int a, int b);#endif

math_operations.c:

#include "math_operations.h"int add(int a, int b) {return a + b;
}int subtract(int a, int b) {return a - b;
}

编译命令:

gcc main.c math_operations.c -o program

第十二章:最佳实践与调试

12.1 代码规范

1.使用有意义的变量名
2.添加必要的注释
3.保持函数简洁(不超过50行)
4.使用适当的缩进(推荐4空格)
5.避免使用全局变量

12.2 调试技巧

1.使用printf调试
2.编译器警告选项:

gcc -Wall -Wextra -pedantic program.c -o program

3.使用GDB调试器:

gcc -g program.c -o program
gdb ./program

12.3 常见错误

// 1. 数组越界
int arr[5] = {1,2,3,4,5};
printf("%d", arr[5]); // 无效访问// 2. 未初始化指针
int *ptr;
printf("%d", *ptr); // 未定义行为// 3. 内存泄漏
int *data = malloc(100 * sizeof(int));
// 忘记 free(data)// 4. 悬空指针
int *ptr = malloc(sizeof(int));
free(ptr);
printf("%d", *ptr); // 访问已释放内存

结语:C 语言学习路径

基础阶段:掌握语法、数据类型、控制结构
进阶阶段:深入指针、内存管理、文件操作
高级阶段:学习数据结构、算法、系统编程
精通阶段:研究操作系统内核、编译器开发

http://www.dtcms.com/a/276105.html

相关文章:

  • Spring Boot整合MyBatis+MySQL+Redis单表CRUD教程
  • STM32中的RTC(实时时钟)详解
  • R 语言绘制 10 种精美火山图:转录组差异基因可视化
  • JavaScript 常见10种设计模式
  • 码头智能哨兵:AI入侵检测系统如何终结废钢盗窃困局
  • Redis专题总结
  • MyBatis实现一对多,多对一,多对多查询
  • Golang操作MySQL json字段优雅写法
  • CPU缓存一致性协议:深入解析MESI协议与多核并发设计
  • HTML/JOSN复习总结
  • 7. JVM类加载器与双亲委派模型
  • PyQt5 — QTimeEdit 学习笔记
  • Java中的wait和notify、Condition接口的使用
  • 分类问题与多层感知机
  • pip国内镜像源一览
  • [es自动化更新] Updatecli编排配置.yaml | dockerfilePath值文件.yml
  • springboot+swagger2文档从swagger-bootstrap-ui更换为knife4j及文档接口参数不显示问题
  • 【高等数学】第三章 微分中值定理与导数的应用——第七节 曲率
  • DirectX Repair修复工具下载,.NET修复,DirectX修复
  • python 中 ‘5‘ 和 5 有什么本质区别?
  • 【深度学习】 1 Deep Learning
  • 12. JVM的垃圾回收器
  • LangChain 代理(Agents)学习
  • 网页五子棋-对战
  • python学习打卡:DAY 37 早停策略和模型权重的保存
  • web网站无法抓包排查;burp无法抓包情况
  • comfyUI-controlNet-线稿软边缘
  • c++中的STL
  • Day59
  • 智能制造——解读50页智能工厂系统集成总体解决方案【附全文阅读】