C语言基础之【C语言概述】
C语言
提到
语言
这个词语,自然会想到的是像英语、汉语等,这样的自然语言,因为它是人和人交换信息不可缺少的工具。而今天计算机遍布了我们生活的每一个角落,除了与人相互交流之外,我们也必须学会和计算机交流。
那用什么的什么样的方式和计算机做最直接的交流呢?人们自然想到的是最古老也最方便的方式一一
语言
,而 C语言就是人和计算机交流的一种语言。
语言是用来交流沟通的。有一方说,有另一方听,必须有两方参与。这是语言最重要的功能:
说的一方传递信息,听的一方接收信息。
说的一方下达指令,听的一方遵循命令做事情。
自然语言是人和人交流的工具,C语言是人和机器交流的工具。
只是,人可以不听另外一个人,但是,计算机是无条件服从。
语言有独特的语法规则
和定义
,双方必须遵循这些规则和定义才能实现真正的交流。
计算机结构组成
计算机系统组成
为什么要学习C语言
C语言特点
优点:
执行速度快
- C语言是一种编译型语言,其编写的程序通常具有很高的运行效率。
非常灵活
- C语言提供了丰富的数据类型和操作符,使得程序员可以灵活地处理各种数据。
底层访问
- C语言允许程序员直接访问内存地址、进行位操作和控制硬件。
广泛应用
- C语言被广泛应用于系统编程、嵌入式系统、操作系统、编译器开发等领域。
丰富的库函数
- C语言拥有丰富的标准库和第三方库,提供了大量的函数和工具,方便开发。
缺点:
内存管理复杂性
- C语言需要程序员手动管理内存分配和释放,容易导致内存泄漏、悬空指针等问题。
开发效率相对较低
- 在开发大型应用程序时,C 语言的开发效率可能不如一些高级编程语言。
编写代码容易出错
- C 语言的灵活性带来了一定的风险,尤其是指针操作。
缺乏现代编程特性
- C 语言缺乏一些高级特性,如面向对象编程(OOP)中的类、对象、继承、多态等机制。
学习C语言理由
C语言应用领域
1.
系统编程
- 操作系统开发:C语言是编写操作系统的主要语言之一。
- 如:
Unix
、Linux
和Windows
操作系统的核心部分都是用C语言编写的- 设备驱动程序:C语言常用于编写硬件设备的驱动程序。
- 因为它可以直接与硬件交互
2.
嵌入式系统
- 微控制器编程:C语言广泛应用于嵌入式系统开发。
- 如:家电、汽车电子、工业控制系统等
- 实时操作系统(RTOS):许多实时操作系统都是用C语言编写的。
- 特别是用于需要高可靠性和实时响应的应用
3.
编译器与解释器开发
- 编译器设计:C语言常用于编写编译器。
- 如:GCC(GNU Compiler Collection)就是用C语言编写的
- 语言实现:C语言常用于编写解释器和虚拟机。
- 许多编程语言(如Python、PHP)的解释器和虚拟机是用C语言实现的
4.
游戏开发
- 游戏引擎:C语言用于编写高性能的游戏引擎。
- 特别是在需要直接操作硬件和内存的场景中
- 图形库:
- 许多图形库(如OpenGL)的底层实现是用C语言编写的
5.
网络编程
- 网络协议栈:C语言用于实现网络协议栈和网络设备驱动程序。
- 如:TCP/IP协议栈
- 服务器开发:高性能的服务器软件常用C语言编写。
- 如:Web服务器、数据库服务器
6.
科学计算与数值分析
- 高性能计算:C语言用于编写科学计算和数值分析软件。
- 特别是在需要高效处理大量数据的场景中
- 数学库:许多数学库是用C语言编写的。
- 如:BLAS、LAPACK
7.
数据库系统
- 数据库管理系统:许多关系型数据库管理系统的核心部分是用C语言编写的。
- 如:MySQL、PostgreSQL
- 存储引擎:C语言用于实现高效的存储引擎和数据处理算法。
8.
工具开发
- 系统工具:许多系统工具是用C语言编写的。
- 如:文本编辑器、调试器、版本控制系统
- 脚本语言解释器:一些脚本语言的解释器是用C语言实现的。
- 如:Lua
9.
图形用户界面(GUI)开发
- GUI库:C语言用于编写图形用户界面库。
- 如:GTK、Qt的底层部分
- 桌面应用程序:一些桌面应用程序是用C语言编写的。
- 如:GIMP
10 .
跨平台开发
- 跨平台应用程序:C语言编写的程序可以在多种操作系统上运行,只需进行少量修改或重新编译。
总结:
C生万物
C语言关键字、控制语句和运算符
C语言仅有
32个关键字
,9 种控制语句
,34 种运算符
,却能完成无数的功能:
第一个C语言程序:hello world
编写C语言代码:hello.c
#include <stdio.h>
int main()
{
printf("hello world\n");
return 0;
}
C 语言的源代码文件是一个普通的文本文件,但
扩展名
必须是.c
通过gcc编译C代码
gcc编译器介绍
编辑器
(如 vim、记事本)是指我们用来写程序(编辑代码)的工具。而我们写的代码语句,电脑是不懂的,我们需要把它转成电脑能懂的语句,
编译器
就是这样的
转化工具。也就是说:我们用编辑器编写的程序,由编译器编译后才可以运行
编译器:
将易于编写、阅读和维护的高级计算机语言
翻译为计算机能解读、运行的低级机器语言
的程序。
gcc (GNU Compiler Collection,GNU 编译器套件),是由 GNU开发的编程语言编译器。
gcc 原本作为 GNU 操作系统的官方编译器
- 现已被大多数类Unix操作系统(如:Linux、BSD、Mac OS X等)采纳为标准的编译器,gcc同样适用于微软的 Windows
gcc 最初用于编译 C语言
- 随着项目的发展 gcc已经成为了能够编译 C、C++、Java、Ada、Fortran、Objective-C、Objective-C++、Go 等语言的编译器大家族。
C语言编译命令模板:
gcc [-option] ... <filename>
C++ 编译命令模板:g++ [-option] ... <filename>
命令
、选项
和源文件
之间使用空格分隔。- 一行命令中可以有零个、一个或多个选项。
- 文件名可以使用文件的绝对路径,也可以使用相对路径。
Windows平台下编译代码
两种运行hello world.c源代码文件的方式:
借助VS编辑工具运行
- 创建项目 —> 创建 helloworld.c 源文件 —> 写 helloworld程序 —> Ctr1 + F5 执行
借助记事本、gcc编译工具运行
system函数
system函数的使用
函数介绍:
system
:用于在程序中执行操作系统命令。
- 这个函数定义在
<stdlib.h>
头文件中
当调用
system
函数并传入一个有效的命令字符串作为参数时:
- 它会使程序暂停当前的执行流程。
- 然后创建一个新的子进程来执行给定的系统命令。
这个系统命令的执行方式就好像在操作系统的命令提示符(如:Windows 的 CMD 或 Linux 的终端)中输入该命令一样。
函数原型:
int system(const char *command);
command
:要执行的命令字符串。
"ls -l"
(在 Linux 下列出当前目录的文件)"dir"
(在 Windows 下列出当前目录的文件)
system
函数可以执行的命令字符串取决于操作系统的命令行解释器
。
- 如:Windows 的
cmd.exe
或 Linux 的/bin/sh
Windows 和 Linux 操作系统上的一些常见的
命令字符串
:
Windows 系统中的常见命令:
1 .系统命令
cls
:清空控制台窗口。system("cls");
pause
:暂停程序执行,等待用户按下任意键继续。system("pause");
exit
:退出当前命令提示符窗口。system("exit");
2 .文件操作
dir
:列出当前目录的文件和子目录。system("dir");
cd
:切换当前目录。system("cd C:\\Users");
mkdir
:创建新目录。system("mkdir new_folder");
del
:删除文件。system("del file.txt");
copy
:复制文件。system("copy file.txt new_file.txt");
move
:移动文件或重命名文件。system("move file.txt C:\\new_location\\file.txt");
3.程序启动
calc
:启动计算器。system("calc");
notepad
:启动记事本。system("notepad");
mspaint
:启动画图程序。system("mspaint");
cmd
:启动新的命令提示符窗口。system("cmd");
4 .网络操作
ping
:测试网络连接。system("ping www.google.com");
ipconfig
:显示网络配置信息。system("ipconfig");
5.系统信息
systeminfo
:显示系统信息。system("systeminfo");
tasklist
:显示当前运行的进程。system("tasklist");
Linux 系统中的常见命令:
1.系统命令
clear
:清空终端窗口。system("clear");
sleep
:暂停程序执行一段时间。system("sleep 5"); // 暂停 5 秒
2.文件操作
ls
:列出当前目录的文件和子目录。system("ls -l");
cd
:切换当前目录。system("cd /home/user");
mkdir
:创建新目录。system("mkdir new_folder");
rm
:删除文件或目录。system("rm file.txt");
cp
:复制文件。system("cp file.txt new_file.txt");
mv
:移动文件或重命名文件。system("mv file.txt /new_location/file.txt");
3.程序启动
gedit
:启动文本编辑器(GNOME 桌面环境)。system("gedit file.txt");
gnome-calculator
:启动计算器(GNOME 桌面环境)。system("gnome-calculator");
4.网络操作
ping
:测试网络连接。system("ping -c 4 www.google.com");
ifconfig
:显示网络配置信息。system("ifconfig");
5.系统信息
uname
:显示系统信息。system("uname -a");
ps
:显示当前运行的进程。system("ps aux");
函数返回值:
- 如果
command
是NULL
,system
会检查系统中是否存在命令行解释器:
- 如果存在,返回非零值
- 如果不存在,返回
0
- 如果
command
不是NULL
,system
会返回命令的执行状态:
- 如果命令成功执行,返回值通常是命令的退出状态
- 如果命令执行失败,返回
-1
函数使用:
#include <stdio.h> #include <stdlib.h> int main() { system("dir"); return 0; }
解决Microsoft Visual Studio提示窗一闪而过的方法:
- 通过system()函数解决
在return 0;
之前添加system(“pause”);
函数调用。- 借助VS工具解决
在项目
上 —> 右键 —>属性
—>配置属性
—>连接器
—>系统
—>子系统
—> 在下拉框中选择控制台 (/SUBSYSTEM:CONSOLE)
—>应用
—>确定
C语言编译过程
C程序编译步骤
选项含义:
选项 | 含义 |
---|---|
-E | 只进行预处理 |
-S | 只进行预处理和编译 |
-c | 只进行预处理、编译和汇编 |
-o filename | 指定生成的输出文件名为 filename |
文件后缀含义:
文件后缀 | 含义 |
---|---|
.c | C语言文件 |
.i | 预处理后的预处理文件 |
.s | 编译后的汇编文件 |
.o | 汇编后的目标文件 |
gcc编译4步骤:
原始的文件
操作
选项
生成的文件的格式
生成的文件的名称
源 文件 预处理 -E xxx.i 预处理文件
预处理文件 编 译 -S xxx.s 汇 编文件
汇 编文件 汇 编 -c xxx.o 目 标文件
目 标文件 链 接 -o xxx.exe 可执行文件
预处理:gcc -E xxx.c -o xxx.i
- 头文件展开-------将指定的头文件内容插入到源代码中。
(不检查语法错误)
- 宏定义替换-------将所有使用
#define
定义的宏替换为对应的值或代码。- 删除注释-------删除源代码中的所有注释,原注释的行变成空行。
- 条件编译处理-------通过
#if
、#ifdef
、#ifndef
、#else
、#elif
、#endif
等指令,来决定哪些代码需要保留,哪些代码需要忽略。
编译:gcc -S xxx.i -o xxx.s
- 逐行检查语法错误-------
(整个编译4步骤中最耗时的过程)
- 词法分析(Lexical Analysis)-------识别出关键字、标识符、常量、运算符等。
- 语法分析(Syntax Analysis)-------检查代码是否符合 C 语言的语法规则。
- 语义分析(Semantic Analysis)-------检查变量是否已声明、类型是否匹配、函数调用是否正确等。
- 代码优化-------对中间代码进行优化,以提高程序的运行效率或减少资源消耗。
汇编:gcc -c xxx.s -o xxx.o
- 将汇编代码转换为机器指令-------将汇编代码(人类可读的低级代码)转换为机器指令(二进制代码)
链接:gcc xxx.o -o xxx.exe
符号解析-------解析目标文件中的符号引用。
- 链接器会查找所有未定义的符号(如函数名、变量名),并在其他目标文件或库中找到其定义。
重定位-------调整符号的地址。
- 在汇编阶段生成的目标文件中,符号的地址可能是临时的,链接器会根据符号的实际地址调整目标文件中的引用。
合并目标文件-------将多个目标文件合并为一个可执行文件。
处理库文件-------链接静态库和动态库。
gcc编译过程
分步编译
预处理:
gcc -E hello.c -o hello.i
编 译:
gcc -S hello.i -o hello.s
汇 编:
gcc -c hello.s -o hello.o
链 接:
gcc hello.o -o hello.exe
一步编译
gcc hello.c -o hello.exe
(也是经过了:预处理、编译、汇编、链接过程的)
CPU内部结构与寄存器
64位与32位系统区别
特性 | 32 位系统 | 64 位系统 |
---|---|---|
数据总线宽度 | 32 位 | 64 位 |
内存寻址能力 | 最大支持4GB的内存地址空间 | 理论上 16 EB,实际支持远大于 4 GB |
寄存器大小 | 32 位 | 64 位 |
性能 | 适合于较小的数据集和简单的任务 | 适合于复杂任务和高性能计算 |
软件兼容性 | 只能运行 32 位软件 | 可以运行 32 位和 64 位软件 |
操作系统支持 | 只能安装 32 位操作系统 | 可以安装 32 位或 64 位操作系统 |
文件系统 | 不支持超大文件(大于4GB的文件) | 支持超大文件(TB 级别的文件) |
安全性 | 较低 | 较高 |
应用场景 | 适合旧设备和轻量级应用程序 | 适合高性能计算和大型应用程序 |
硬件要求 | 对硬件要求较低 | 需要支持 64 位的 CPU 和足够内存 |
数据总线宽度
- 32 位系统:
- 数据总线宽度为 32 位,意味着 CPU 一次可以处理 32 位的数据。
- 64 位系统:
- 数据总线宽度为 64 位,意味着 CPU 一次可以处理 64 位的数据。
内存寻址能力
- 32 位系统:
- 最大支持 4 GB( 2 32 2^{32} 232 字节)的内存地址空间。
- 实际可用内存通常小于 4 GB,因为部分地址空间被硬件保留。
- 64 位系统:
- 理论上支持 16 EB($2^{64} $字节)的内存地址空间。
- 尽管实际支持的内存大小受
操作系统
和硬件
的限制通常远低于这个理论值,但通常远大于 4 GB(如 128 GB 或更高)
单位换算表:
单位名称 缩写 换算关系 位(Bit) b 1 Byte = 8 bits 字节(Byte) B 1 KB = 1024 Bytes 千字节(Kilobyte) KB 1 MB = 1024 KB 兆字节(Megabyte) MB 1 GB = 1024 MB 吉字节(Gigabyte) GB 1 TB = 1024 GB 太字节(Terabyte) TB 1 PB = 1024 TB 拍字节(Petabyte) PB 1 EB = 1024 PB 艾字节(Exabyte) EB 1 ZB = 1024 EB 泽字节(Zettabyte) ZB 1 YB = 1024 ZB 尧字节(Yottabyte) YB 目前最大的数据存储单位
- 位(Bit):
计算机中最小的数据单位
- 字节(Byte):
计算机中存储的基本单位
提示:
16 EB = 16,777,216 TB
16 EB = 17,179,869,184 GB
寄存器名字
8位 | 16位 | 32位 | 64位 |
---|---|---|---|
A | AX | EAX | RAX |
B | BX | EBX | RBX |
C | CX | ECX | RCX |
D | DX | EDX | RDX |
寄存器、缓存、内存三者的关系
特性 | 寄存器 | 缓存 | 内存 |
---|---|---|---|
位置 | CPU 内部 | CPU 和内存之间 | CPU 外部 |
速度 | 最快(1 个时钟周期) | 较快(几到几十个时钟周期) | 较慢(几十到几百个时钟周期) |
容量 | 最小(几十到几百字节) | 适中(几 KB 到几十 MB) | 最大(几 GB 到几十 GB) |
功能 | 存储CPU当前处理的数据 | 存储CPU近期可能使用的数据 | 存储运行中的程序和数据 |
管理 | 硬件直接管理 | 硬件自动管理 | 操作系统管理 |
寄存器(Register)
- 速度极快,但容量非常有限。
- 由硬件直接管理,程序员通常通过
汇编语言
或编译器
间接使用。缓存(Cache)
- 速度较快,容量适中。
- 由硬件自动管理,程序员通常无法直接控制。
内存(Memory,通常指 RAM)
- 速度较慢,但容量较大。
- 由操作系统管理,程序员可以通过
编程语言
(如 C、C++)直接操作。
寄存器、缓存、内存
- 速度:寄存器 > 缓存 > 内存
- 寄存器是 CPU 直接操作的数据存储单元,速度最快。
- 缓存是寄存器和内存之间的缓冲,速度介于两者之间。
- 内存是 CPU 和外部存储(如硬盘)之间的桥梁,速度最慢。
- 容量:内存 > 缓存 > 寄存器
- 内存容量最大,可以存储大量数据和程序。
- 缓存容量适中,用于存储近期可能使用的数据。
- 寄存器容量最小,只能存储少量数据。
- 协作方式:
- 当 CPU 需要数据时,首先检查寄存器中是否有数据。
- 如果寄存器中没有,则检查缓存。
- 如果缓存中没有,则从内存中加载数据到缓存,再加载到寄存器。
- 如果内存中也没有,则从硬盘(或其他外部存储)中加载数据到内存。
- 局部性原理:
时间局部性
:最近访问的数据很可能再次被访问。空间局部性
:访问某个数据时,其附近的数据也可能被访问。
- 缓存和寄存器利用局部性原理,提高数据访问效率。
寄存器、缓存和内存共同构成了
计算机的存储层次结构
,通过协作实现高效的数据存储
和访问
汇编语言
VS中C语言嵌套汇编代码
#include <stdio.h>
int main()
{
//定义整型变量a, b, c
int a;
int b;
int c;
__asm
{
mov a, 3 //3的值放在a对应内存的位置
mov b, 4 //4的值放在b对应内存的位置
mov eax, a //把a内存的值放在eax寄存器
add eax, b //eax和b相加,结果放在eax
mov c, eax //eax的值放在c中
}
printf("%d\n", c);//把c的值输出
return 0;//成功完成
}
VS反汇编
#include <stdio.h>
int main()
{
//定义整型变量a, b, c
int a;
int b;
int c;
a = 3;
b = 4;
c = a + b;
printf("%d\n", c);//把c的值输出
return 0;//成功完成
}
- 设置断点
- 进行调试
- 选择反汇编按钮
- 根据汇编代码分析程序
集成开发环境IDE
Microsoft Visual Studio
Visual Studio简介
Microsoft Visual Studio(简称VS)是美国微软公司的开发工具包系列产品。
Visual Studio
:一个集成开发环境(IDE)
为软件开发者提供了整个软件生命周期中所需的大部分工具。
- 如:UML工具、代码管控工具、集成开发环境(IDE)等。
所写的目标代码适用于微软支持的所有平台。
目前最流行的Windows平台应用程序的集成开发环境。
Visual Studio快捷键大全
1. 代码编辑快捷键
快捷键 | 功能描述 |
---|---|
Ctrl + K + C | 注释选中代码 |
Ctrl + K + U | 取消注释选中代码 |
Ctrl + K + D | 格式化整个文档 |
Ctrl + K + F | 格式化选中代码 |
Ctrl + K + S | 插入代码片段 |
Ctrl + Enter | 在当前行上方插入新行 |
Ctrl + Shift + Enter | 在当前行下方插入新行 |
Ctrl + M + O | 折叠所有代码块 |
Ctrl + M + L | 展开所有代码块 |
Ctrl + M + M | 切换当前代码块的折叠状态 |
Ctrl + Shift + V | 循环粘贴剪贴板历史记录 |
2. 导航快捷键
快捷键 | 功能描述 |
---|---|
F12 | 转到定义(在选中的前提下) |
Ctrl + - | 导航回退(返回上一个光标位置) |
Ctrl + Shift + - | 导航前进 |
Ctrl + T | 快速查找所有符号(在选中的前提下) |
Ctrl + G | 跳转到指定行号 |
Ctrl + F12 | 转到实现(适用于接口和抽象方法)(在选中的前提下) |
Alt + F12 | 查看定义(Peek Definition)(在选中的前提下) |
3. 调试快捷键
快捷键 | 功能描述 |
---|---|
F5 | 启动调试 |
Shift + F5 | 停止调试 |
Ctrl + Shift + F5 | 重启调试 |
F9 | 设置断点 |
F10 | 逐过程调试(不进入函数内部) |
F11 | 逐语句调试(进入函数内部) |
Shift + F11 | 跳出当前函数 |
Ctrl + F5 | 执行但不调试 |
Ctrl + Shift + B | 编译但不执行 |
Qt Creator
Qt Creator简介
Qt Creator
:一个跨平台的集成开发环境(IDE)
- 专门用于开发基于 Qt 框架的应用程序,支持在多种操作系统(如:Windows、Linux、macOS 等)上进行开发。
Qt
:一个强大的 C++ 框架。
- 广泛用于开发图形用户界面(GUI)应用程序、嵌入式系统、移动应用和跨平台桌面应用。
Qt Creator常用快捷键
快捷键 | 功能描述 |
---|---|
Ctrl + / | 注释/取消注释 |
Ctrl + I | 自动格式化代码 |
Alt + Enter | 自动完成类函数定义 |
F4 | 在头文件和源文件之间切换 |
F9 | 设置断点 |
F5 | 启动调试 |
F10 | 逐过程调试(不进入函数内部) |
F11 | 逐语句调试(进入函数内部) |