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.pswp.cn/news/914238.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/914238.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

单细胞分析教程 | (二)标准化、特征选择、降为、聚类及可视化

在完成质控&#xff08;QC&#xff09;后&#xff0c;我们已经过滤掉了低质量细胞、双细胞和低表达基因&#xff0c;获得了较为干净的单细胞数据集单细胞分析教程 | &#xff08;一&#xff09;Python单细胞质控全流程。接下来&#xff0c;我们将进行以下关键步骤&#xff1a; …

大模型 Agent(智能体)技术简介

大模型 Agent&#xff08;智能体&#xff09;技术 是当前人工智能领域的前沿方向&#xff0c;它赋予大型语言模型&#xff08;LLM&#xff09;自主感知、规划、决策和行动的能力&#xff0c;使其不再局限于“被动应答”&#xff0c;而是能主动完成复杂任务。简单来说&#xff0…

OneCode 3.0架构深度剖析:工程化模块管理与自治UI系统的设计与实现

引言 OneCode 3.0作为新一代低代码开发平台&#xff0c;其架构设计围绕"工程模块化"与"UI自主化"两大核心目标展开。本文将从底层接口到上层应用&#xff0c;全面解析OneCode 3.0的技术架构&#xff0c;包括核心工厂类、工程管理接口、数据仓库设计以及动态…

功耗校准数据PowerProfile测试方法建议

场景步骤版本:xxxxA1A2结果&#xff08;mA&#xff09;screen,full1.打开飞行模式&#xff0c;灭屏时间最长&#xff0c;其他的基础功能关2.进入到日历应用界面3.将亮度设置至最大&#xff08;4095&#xff09;&#xff0c;待电流稳定后&#xff0c;测试5分钟&#xff0c;记录电…

[附源码+数据库+毕业论文]基于Spring+MyBatis+MySQL+Maven+vue实现的供电公司安全生产考试管理系统,推荐!

摘 要 使用旧方法对安全生产考试信息进行系统化管理已经不再让人们信赖了&#xff0c;把现在的网络信息技术运用在安全生产考试信息的管理上面可以解决许多信息管理上面的难题&#xff0c;比如处理数据时间很长&#xff0c;数据存在错误不能及时纠正等问题。 这次开发的供电公…

输入框过滤选项列表,el-checkbox-group单选

需求&#xff1a;根据输入的文本动态过滤选项列表&#xff0c;并在下方显示匹配到的选项。当用户勾选匹配到的选项时&#xff0c;把该选项的值赋值给输入框中绑定的值。当用户取消选择时&#xff0c;输入框中的字段可以随意编辑。组件&#xff1a;el-input、el-checkbox-group、…

身份认证缺陷

Authentication Bypasses审计创建AccountVerificationHelper实例&#xff0c;用于处理账户验证逻辑parseSecQuestions函数的作用是从请求体中遍历参数名&#xff0c;找到包含secQuestion的参数&#xff0c;将其值存入Map中并返回这里直接把AccountVerificationHelper整个分析一…

火山引擎:字节跳动的技术赋能初解

火山引擎是字节跳动旗下的企业级智能技术服务平台&#xff0c;于2020年6月正式上线。它通过开放字节跳动在大数据、人工智能、视频云等领域的核心技术&#xff0c;助力企业实现数字化转型与业务增长。火山引擎界面核心能力与技术亮点:1.全栈云服务公有云与混合云&#xff1a;提…

VUE 带有搜索功能的穿梭框(简单demo)

一、template/ 组件代码<el-dialog :title"title" :visible.sync"dialogVisible" width"60%" :before-close"handleClose" class"custom-dialog-line" ><div style"text-align: center ; width: 100%; height…

写个扫雷小游戏

1.test.c&#xff08;测试源文件&#xff09;2.game.c&#xff08;游戏源文件&#xff09;3.头文件

【Linux庖丁解牛】— system V共享内存!

1. 什么是system VSystem V IPC&#xff08;Interprocess Communication&#xff0c;进程间通信&#xff09;是Unix系统中一种经典的进程间通信机制&#xff0c;由AT&T在System V.2版本中引入&#xff0c;并广泛应用于Linux等现代操作系统中。它通过三种核心机制实现进程间…

从输入到路径:AI赋能的地图语义解析与可视化探索之旅(2025空间智能全景)

​​摘要​​在空间智能爆发的2025年&#xff0c;地图系统已从静态导航工具进化为​​实时决策中枢​​。本文深度解析AI如何重构地理信息处理全链路&#xff1a;通过​​多模态语义理解​​&#xff08;文本/语音/图像→空间意图&#xff09;、​​动态路网建模​​&#xff0…

安全运维新趋势:AI 驱动的自动化威胁检测

在数字化浪潮中&#xff0c;网络攻击正从 “单点突破” 进化为 “链状打击”&#xff1a;2024 年某金融机构遭遇供应链攻击&#xff0c;恶意代码通过运维通道潜伏 3 个月&#xff0c;传统规则引擎因未识别 “正常运维指令中的异常参数”&#xff0c;导致数据泄露损失过亿。这背…

数据库复合索引设计:为什么等值查询列应该放在范围查询列前面?

前言作为后端开发工程师&#xff0c;我们经常会遇到数据库查询性能问题。在一次系统优化中&#xff0c;我发现一个简单的索引顺序调整竟然让查询速度提升了10倍&#xff01;这让我意识到复合索引列顺序的重要性。今天&#xff0c;我就来分享一下这个经验&#xff0c;希望能帮助…

【PMP备考】每日一练 - 2

1、一个建筑项目的项目经理发现&#xff0c;他管理的项目所在地附近正在新建一条新的水管线。公司政策要求&#xff0c;在他的团队继续完成这个项目之前&#xff0c;必须先填写一系列有关城市环境变化的表格。这是那两种情况的例子&#xff1f;&#xff08;选2个选项&#xff0…

【三】ObservableCollection 与 List 的区别

文章目录前言一、核心概念简介ObservableCollectionList二、关键差异对比三、典型使用场景ObservableCollection 的适用场景List 的适用场景四、在Community Toolkit MVVM中使用ObservableCollection<Data>和List<Data>场景1&#xff1a;动态列表&#xff08;Obser…

网安-SSRF-pikachu

目录 SSRF:Server-Side Request Forgery PHP curl PHP 可能引起SSRF的函数 PHP其他函数 CURL其他协议 SSRF利用&#xff1a; SSRF的发现 工具 SSRF的防御 pikachu-SSRF 一&#xff1a;curl 1.访问连接&#xff1a; 2.读取本地文件 3.dict协议扫描主机端口 二&…

在Centos系统上如何有效删除文件和目录的指令汇总

CentOS系统是一款开源的类Unix操作系统&#xff0c;极其亲和程序员和技术人员。这个系统最大的优势就是其高度自由化的特性&#xff0c;世界各地的开发者可以依照实际需求去修改和运行。在这个操作系统中&#xff0c;如果你想删除文件和目录&#xff0c;你可以使用各式各样的命…

Spring(四) 关于AOP的源码解析与思考

Spring&#xff08;四&#xff09; 关于AOP的源码解析与思考 每种语言都有其独特的机制和特点&#xff0c;那么说到Java你可能会首先想到反射&#xff0c;反射是Java语言提供的一种能够在程序运行时动态操作类或对象的能力&#xff0c;比如获取某个对象的类定义、获取类声明的属…

Android 15 Settings 搜索框:引入关键字过滤功能

在日常使用 Android 手机时,我们经常会用到“设置”应用中的搜索功能来快速定位所需选项。然而,有时搜索结果可能会包含一些我们不希望看到或者过于宽泛的条目。 本文将深入探讨这一变化,通过分析 SearchResultsAdapter.java 文件中的代码修改,揭示 Android 如何实现对特定…