C语言快速学习笔记
学习网站:C 语言教程 | 菜鸟教程 (runoob.com)C 语言教程 | 菜鸟教程 (runoob.com)C 语言教程 | 菜鸟教程 (runoob.com)
这个网站知识完整,讲解清晰。
在线C语言编程工具:菜鸟教程在线编辑器 (runoob.com)
国外学习网站:C语言介绍 - GeeksforGeeks
算法知识网站:算法通关手册(LeetCode) | 算法通关手册(LeetCode) (itcharge.cn)
0.前言
静态语言和动态语言
动态语言:是运行时才确定数据类型的语言,变量在使用之前无需申明类型,通常变量的值是被赋值的那个值的类型。比如Php、Asp、JavaScript、Python、Per等等。
静态语言:是编译时变量的数据类型就可以确定的语言,大多数静态语言要求在使用变量之前必须声明数据类型。比如Java、C、C++、C#等。

图片来源:动态语言和静态语言的区别(如python与c++)-CSDN博客
1.C语言的简介
C 语言是一种通用的高级语言,最初是由丹尼斯·里奇在贝尔实验室为开发 UNIX 操作系统而设计的。
1.1特点

- 易学习
 - 结构化语言
 - 高效率
 - 底层处理
 - 使用多种计算机
 - 通用和便携(General Purpose and Portable)
 
1.2 C与C++的区别
- C++ 支持 OOP 范式,而 C 只有编程的过程概念。
 - C++ 具有异常处理功能。在 C 语言中,我们必须手动解析。
 - C 中没有引用。
 
2 环境配置
教程:从零开始的vscode安装及环境配置教程(C/C++)(Windows系统)_vscode搭建编译器环境-CSDN博客
C 代码的编辑器 :VSCode(全称:Visual Studio Code)是一款由微软开发且跨平台的免费源代码编辑器,VSCode 开发环境非常简单易用。
C 代码的编译器 :最常用的免费可用的编译器是 GNU 的 C/C++ 编译器。
windows安装编译器:为了在 Windows 上安装 GCC,您需要安装 MinGW。
AI助手:
- GitHub Copilot
 - Fitten Code
 
3、C 程序结构
C程序主要包括以下部分:

- 预处理器指令:#include <stdio.h>
 - 函数:int main() 是主函数
 - 变量:int a
 - 语句&表达式:{里面的}
 - 注释:/*...*/
 
4 C基本语法
4.1 C的令牌
C 程序由各种令牌组成,令牌可以是关键字、标识符、常量、字符串值,或者是一个符号。
4.2 分号
在 C 程序中,分号是语句结束符。也就是说,每个语句必须以分号结束。它表明一个逻辑实体的结束。
4.3 注释
两种注释方式
1、单行注释: //
2、/* */ 这种格式的注释可以单行或多行。
4.4 标识符
C 标识符是用来标识变量、函数,或任何其他用户自定义项目的名称。一个标识符以字母 A-Z 或 a-z 或下划线 _ 开始,后跟零个或多个字母、下划线和数字(0-9)。C 标识符内不允许出现标点字符,比如 @、$ 和 %。C 是区分大小写的编程语言。
4.5 常见的关键字
| 关键字 | 说明 | 
|---|---|
| auto | 声明自动变量 | 
| break | 跳出当前循环 | 
| case | 开关语句分支 | 
| char | 声明字符型变量或函数返回值类型 | 
| const | 定义常量,如果一个变量被 const 修饰,那么它的值就不能再被改变 | 
| continue | 结束当前循环,开始下一轮循环 | 
| default | 开关语句中的"其它"分支 | 
| do | 循环语句的循环体 | 
| double | 声明双精度浮点型变量或函数返回值类型 | 
| else | 条件语句否定分支(与 if 连用) | 
| enum | 声明枚举类型 | 
| extern | 声明变量或函数是在其它文件或本文件的其他位置定义 | 
| float | 声明浮点型变量或函数返回值类型 | 
| for | 一种循环语句 | 
| goto | 无条件跳转语句 | 
| if | 条件语句 | 
| int | 声明整型变量或函数 | 
| long | 声明长整型变量或函数返回值类型 | 
| register | 声明寄存器变量 | 
| return | 子程序返回语句(可以带参数,也可不带参数) | 
| short | 声明短整型变量或函数 | 
| signed | 声明有符号类型变量或函数 | 
| sizeof | 计算数据类型或变量长度(即所占字节数) | 
| static | 声明静态变量 | 
| struct | 声明结构体类型 | 
| switch | 用于开关语句 | 
| typedef | 用以给数据类型取别名 | 
| unsigned | 声明无符号类型变量或函数 | 
| union | 声明共用体类型 | 
| void | 声明函数无返回值或无参数,声明无类型指针 | 
| volatile | 说明变量在程序执行中可被隐含地改变 | 
| while | 循环语句的循环条件 | 
4.6、 C语言的数据类型
4.6.1 字、字节(Byte)、比特(bit)
比特bit是二进制位(Binary digit)的简称,一个二进制包含的信息量成为一比特bit。比特bit是计算机内部数据存储的最小单位。二进制在效率和成本方面的优势为全世界所接受,现在电脑所有的信息都是二进制的,就是0和1组成的。
字节Byte是计算机数据处理的最小单位,习惯上用大写的B表示,每个字节有8个二进制位,其中最右边的一位为最低位,最左边的一位为最高位,每个二进制位的值不是0就是1。一个字节由8个二进制位组成。也就是1字节Byte等于8比特Bit。
字和字节都是计算机的存储单元。字由若干个字节组成,一个字节是8个比特bit。字的位数叫做字长,即cpu一次处理二进制代码的位数。字的长度与计算架构有关,比如32位机,一个字就是32位,换算成字节就是4字节;同样的64位机,一个字就是64位,也就是8字节。字也是计算机一次处理数据的最大单位。
| 序号 | 类型与描述 | 
|---|---|
| 1 | 基本数据类型 它们是算术类型,包括整型(int)、字符型(char)、浮点型(float)和双精度浮点型(double)。  | 
| 2 | 枚举类型: 它们也是算术类型,被用来定义在程序中只能赋予其一定的离散整数值的变量。  | 
| 3 | void 类型: 类型说明符 void 表示没有值的数据类型,通常用于函数返回值。  | 
| 4 | 派生类型: :包括数组类型、指针类型和结构体类型。  | 
数组类型和结构类型统称为聚合类型。函数的类型指的是函数返回值的类型。
4.6.2 整数类型
| 类型 | 存储大小 | 值范围 | 
|---|---|---|
| char | 1 字节 | -128 到 127 或 0 到 255(ASIICA) | 
| unsigned char | 1 字节 | 0 到 255 | 
| signed char | 1 字节 | -128 到 127 | 
| int | 2 或 4 字节 | -32,768 到 32,767 或 -2,147,483,648 到 2,147,483,647 | 
| unsigned int | 2 或 4 字节 | 0 到 65,535 或 0 到 4,294,967,295 | 
| short | 2 字节 | -32,768 到 32,767 | 
| unsigned short | 2 字节 | 0 到 65,535 | 
| long | 4 字节 | -2,147,483,648 到 2,147,483,647 | 
| unsigned long | 4 字节 | 0 到 4,294,967,295 | 
注意,各种类型的存储大小与系统位数有关,但目前通用的以64位系统为主。
为了得到某个类型或某个变量在特定平台上的准确大小,您可以使用 sizeof 运算符。表达式 sizeof(type) 得到对象或类型的存储字节大小。
4.6.3 浮点类型
下表列出了关于标准浮点类型的存储大小、值范围和精度的细节:
| 类型 | 存储大小 | 值范围 | 精度 | 
|---|---|---|---|
| float | 4 字节 | 1.2E-38 到 3.4E+38 | 6 位有效位 | 
| double | 8 字节 | 2.3E-308 到 1.7E+308 | 15 位有效位 | 
| long double | 16 字节 | 3.4E-4932 到 1.1E+4932 | 19 位有效位 | 
头文件 float.h 定义了宏,在程序中可以使用这些值和其他有关实数二进制表示的细节。
4.6.4 void 类型
| 序号 | 类型与描述 | 
|---|---|
| 1 | 函数返回为空 C 中有各种函数都不返回值,或者您可以说它们返回空。不返回值的函数的返回类型为空。例如 void exit (int status);  | 
| 2 | 函数参数为空 C 中有各种函数不接受任何参数。不带参数的函数可以接受一个 void。例如 int rand(void);  | 
| 3 | 指针指向 void 类型为 void * 的指针代表对象的地址,而不是类型。例如,内存分配函数 void *malloc( size_t size ); 返回指向 void 的指针,可以转换为任何数据类型。  | 
4.6.5 类型转换
类型转换是将一个数据类型的值转换为另一种数据类型的值。
C 语言中有两种类型转换:
-  
隐式类型转换:隐式类型转换是在表达式中自动发生的,无需进行任何明确的指令或函数调用。它通常是将一种较小的类型自动转换为较大的类型,例如,将int类型转换为long类型或float类型转换为double类型。隐式类型转换也可能会导致数据精度丢失或数据截断。
 -  
显式类型转换:显式类型转换需要使用强制类型转换运算符(type casting operator),它可以将一个数据类型的值强制转换为另一种数据类型的值。强制类型转换可以使程序员在必要时对数据类型进行更精确的控制,但也可能会导致数据丢失或截断。
 
4.7 C变量基本变量
变量的名称可以由字母、数字和下划线字符组成。它必须以字母或下划线开头。大写字母和小写字母是不同的,因为 C 是大小写敏感的
| 类型 | 描述 | 
|---|---|
| char | 通常是一个字节(八位), 这是一个整数类型。 | 
| int | 整型,4 个字节,取值范围 -2147483648 到 2147483647。 | 
| float |   单精度浮点值。单精度是这样的格式,1位符号,8位指数,23位小数。 
  | 
| double |   双精度浮点值。双精度是1位符号,11位指数,52位小数。 
  | 
| void | 表示类型的缺失。 | 
4.7.1 变量定义
type value
type 表示变量的数据类型,可以是整型、浮点型、字符型、指针等,也可以是用户自定义的对象。
variable_list 可以由一个或多个变量的名称组成,多个变量之间用逗号,分隔,变量由字母、数字和下划线组成,且以字母或下划线开头。
比如:
- int age;
 - char grade;
 - int i,j,k;
 - >>>
 
4.7.2 变量初始化
type variable_name = value;
其中,type 表示变量的数据类型,variable_name 是变量的名称,value 是变量的初始值。
4.7.3 后续初始化变量
type variable_name;    // 变量定义
 variable_name = new_value;    // 变量初始化
注意:为了避免不确定的行为和错误,建议在使用变量之前进行初始化。
4.7.4 变量不初始化
对于全局变量和静态变量(在函数内部定义的静态变量和在函数外部定义的全局变量),它们的默认初始值为零。
以下是不同类型的变量在没有显式初始化时的默认值:
- 整型变量(int、short、long等):默认值为0。
 - 浮点型变量(float、double等):默认值为0.0。
 - 字符型变量(char):默认值为'\0',即空字符。
 - 指针变量:默认值为NULL,表示指针不指向任何有效的内存地址。
 - 数组、结构体、联合等复合类型的变量:它们的元素或成员将按照相应的规则进行默认初始化,这可能包括对元素递归应用默认规则。
 
需要注意的是,局部变量(在函数内部定义的非静态变量)不会自动初始化为默认值,它们的初始值是未定义的(包含垃圾值)。因此,在使用局部变量之前,应该显式地为其赋予一个初始值。
4.7.5 变量声明
变量的声明有两种情况:
- 1、一种是需要建立存储空间的。例如:int a 在声明的时候就已经建立了存储空间。
 - 2、另一种是不需要建立存储空间的,通过使用extern关键字声明变量名而不定义它。 例如:extern int a 其中变量 a 可以在别的文件中定义的。
 - 除非有extern关键字,否则都是变量的定义。
 
4.8 C 常量
常量是固定值,在程序执行期间不会改变。这些固定的值,又叫做字面量。
常量可以是任何的基本数据类型,比如整数常量、浮点常量、字符常量,或字符串字面值,也有枚举常量。
4.8.1 整数常量
整数常量可以是十进制、八进制或十六进制的常量。前缀指定基数:0x 或 0X 表示十六进制,0 表示八进制,不带前缀则默认表示十进制。
整数常量也可以带一个后缀,后缀是 U 和 L 的组合,U 表示无符号整数(unsigned),L 表示长整数(long)。后缀可以是大写,也可以是小写,U 和 L 的顺序任意。
4.8.2 字符常量
字符常量是括在单引号中,例如,'x' 可以存储在 char 类型的简单变量中。
| 转义序列 | 含义 | 
|---|---|
| \\ | \ 字符 | 
| \' | ' 字符 | 
| \" | " 字符 | 
| \? | ? 字符 | 
| \a | 警报铃声 | 
| \b | 退格键 | 
| \f | 换页符 | 
| \n | 换行符 | 
| \r | 回车 | 
| \t | 水平制表符 | 
| \v | 垂直制表符 | 
| \ooo | 一到三位的八进制数 | 
| \xhh . . . | 一个或多个数字的十六进制数 | 
4.8.3 字符串常量
字符串字面值或常量是括在双引号 " " 中的。一个字符串包含类似于字符常量的字符:普通的字符、转义序列和通用的字符。
4.8.4 定义常量
在 C 中,有两种简单的定义常量的方式:
- 使用 #define 预处理器: #define 可以在程序中定义一个常量,它在编译时会被替换为其对应的值。
 - 使用 const 关键字:const 关键字用于声明一个只读变量,即该变量的值不能在程序运行时修改。
 
#define 预处理器:#define 常量名 常量值 -> #define PI 3.14159
const 关键字:const 数据类型 常量名 = 常量值; -> const int MAX_VALUE = 100;
注意:建议使用 const 关键字来定义常量,因为它具有类型检查和作用域的优势,而 #define 仅进行简单的文本替换,可能会导致一些意外的问题。
4.9 存储类
存储类定义 C 程序中变量/函数的存储位置、生命周期和作用域。
这些说明符放置在它们所修饰的类型之前。
下面列出 C 程序中可用的存储类:
- auto
 - register
 - static
 - extern
 
4.9.1 auto类
auto 存储类是所有局部变量默认的存储类。
定义在函数中的变量默认为 auto 存储类,这意味着它们在函数开始时被创建,在函数结束时被销毁。
4.9.2 register 存储类
register 存储类用于定义存储在寄存器中而不是 RAM 中的局部变量。register 存储类定义存储在寄存器,所以变量的访问速度更快,但是它不能直接取地址,因为它不是存储在 RAM 中的。在需要频繁访问的变量上使用 register 存储类可以提高程序的运行速度。
register int  miles; 
4.9.3 static 存储类
static int count=10;        /* 全局变量 - static 是默认的 */
 
static 存储类指示编译器在程序的生命周期内保持局部变量的存在,而不需要在每次它进入和离开作用域时进行创建和销毁。因此,使用 static 修饰局部变量可以在函数调用之间保持局部变量的值。
static 修饰符也可以应用于全局变量。当 static 修饰全局变量时,会使变量的作用域限制在声明它的文件内。
全局声明的一个 static 变量或方法可以被任何函数或方法调用,只要这些方法出现在跟 static 变量或方法同一个文件中。
静态变量在程序中只被初始化一次,即使函数被调用多次,该变量的值也不会重置。
4.9.4 extern 存储类
extern void write_extern(); 
extern 存储类用于定义在其他文件中声明的全局变量或函数。当使用 extern 关键字时,不会为变量分配任何存储空间,而只是指示编译器该变量在其他文件中定义。
4.10 运算符
在 C 语言中,运算符是表示要对一个或多个操作数执行的操作的符号。它们是 C 编程的基本组件

运算符是一种告诉编译器执行特定的数学或逻辑操作的符号。C 语言内置了丰富的运算符,并提供了以下类型的运算符:
C 语言提供了广泛的运算符,根据其功能可以分为 6 种类型:
- 算术运算符
 - 关系运算符
 - 逻辑运算符
 - 位运算符
 - 赋值运算符
 - 杂项运算符
 
4.10.1 算术运算符
The arithmetic operators are used to perform arithmetic/mathematical operations on operands. There are 9 arithmetic operators in C language(算术运算符用于对操作数执行算术/数学运算。C语言中有9个算术运算符:
|   S.No.  |   Symbol  | Operator | Description |   Syntax  | 
|---|---|---|---|---|
|   1  |   +  |   Plus  | Adds two numeric values. 把两个操作数相加 |   a + b  | 
|   2  |   –  |   Minus  | Subtracts right operand from left operand.第一个操作数减第二个操作数 |   a – b  | 
|   3  |   *  |   Multiply  | Multiply two numeric values.两个操作数相乘 |   a * b  | 
|   4  |   /  |   Divide  | Divide two numeric values. 第一个操作数除以第二个操作数 |   a / b  | 
|   5  |   %  |   Modulus  | Returns the remainder after diving the left operand with the right operand.   返回左操作数除以右操作数后的余数。  |   a % b  | 
|   6  |   +  |   Unary Plus  | Used to specify the positive values.用于指定正值。 |   +a  | 
|   7  |   –  |   Unary Minus  | Flips the sign of the value.  翻转值的符号。  |   -a  | 
|   8  |   ++  |   Increment  | Increases the value of the operand by 1. 将操作数的值增加1 |   a++  | 
|   9  |   —  |   Decrement  | Decreases the value of the operand by 1. 将操作数的值减少1。 |   a–  | 
4.10.2 关系运算符(Logical Operator)
C 中的关系运算符用于比较两个操作数。所有这些运算符都是二进制运算符,它们作为比较的结果返回真值或假值。(The relational operators in C are used for the comparison of the two operands. All these operators are binary operators that return true or false values as the result of comparison.)
| 运算符 | 描述 | 实例 | 
|---|---|---|
| == | 检查两个操作数的值是否相等,如果相等则条件为真。 | (A == B) 为假。 | 
| != | 检查两个操作数的值是否相等,如果不相等则条件为真。 | (A != B) 为真。 | 
| > | 检查左操作数的值是否大于右操作数的值,如果是则条件为真。 | (A > B) 为假。 | 
| < | 检查左操作数的值是否小于右操作数的值,如果是则条件为真。 | (A < B) 为真。 | 
| >= | 检查左操作数的值是否大于或等于右操作数的值,如果是则条件为真。 | (A >= B) 为假。 | 
| <= | 检查左操作数的值是否小于或等于右操作数的值,如果是则条件为真。 | (A <= B) 为真。 | 
// C program to illustrate the relational operators
#include <stdio.h>int main()
{int a = 25, b = 5;// using operators and printing resultsprintf("a < b  : %d\n", a < b);printf("a > b  : %d\n", a > b);printf("a <= b: %d\n", a <= b);printf("a >= b: %d\n", a >= b);printf("a == b: %d\n", a == b);printf("a != b : %d\n", a != b);return 0;
}
 
4.10.3 C 语言中的逻辑运算符
逻辑运算符用于组合两个或多个条件/约束,或补充所考虑的原始条件的评估。逻辑运算符操作的结果是一个布尔值,可以是 true 或 false。
| 运算符 | 描述 | 实例 | 
|---|---|---|
| && | 称为逻辑与运算符。如果两个操作数都非零,则条件为真。 | (A && B) 为假。 | 
| || | 称为逻辑或运算符。如果两个操作数中有任意一个非零,则条件为真。 | (A || B) 为真。 | 
| ! | 称为逻辑非运算符。用来逆转操作数的逻辑状态。如果条件为真则逻辑非运算符将使其为假。 | !(A && B) 为真。 | 
// C program to illustrate the logical operators
#include <stdio.h>int main()
{int a = 25, b = 5;// using operators and printing resultsprintf("a && b : %d\n", a && b);printf("a || b : %d\n", a || b);printf("!a: %d\n", !a);return 0;
}
 
4.10.4 位运算符(Bitwise Operators)
按位运算符用于对操作数执行位级操作。首先将运算符转换为位级,然后对操作数执行计算。加法、减法、乘法等数学运算可以在位级别执行,以加快处理速度。
|   S.No.  |   Symbol  | Operator | Description |   Syntax  | 
|---|---|---|---|---|
|   1  |   &  | Bitwise AND/按位与 |   Performs bit-by-bit AND operation and returns the result./对两个操作数的每一位执行逻辑与操作。 解释:如果两个相应的位都为 1,则结果为 1,否则为 0。 
  | a & b | 
|   2  |   |  | Bitwise OR/按位或 |   Performs bit-by-bit OR operation and returns the result./对两个操作数的每一位执行逻辑或操作。 解释:如果两个相应的位都为 0,则结果为 0,否则为 1。 
  | a | b | 
|   3  |   ^  | Bitwise XOR/按位异或 |   Performs bit-by-bit XOR operation and returns the result./对两个操作数的每一位执行逻辑异或操作。 解释:如果两个相应的位值相同,则结果为 0,否则为 1。 
  | a ^ b | 
|   4  |   ~  | Bitwise First Complement/逐位第一补码 | Flips all the set and unset bits on the number./  对操作数的每一位执行逻辑取反操作。 解释:即将每一位的 0 变为 1,1 变为 0。 
  | ~a | 
|   5  |   <<  | Bitwise Leftshift/逐位左移 | Shifts the number in binary form by one place in the operation and returns the result./将操作数的所有位向左移动指定的位数。左移 n 位相当于乘以 2 的 n 次方。 | a << b | 
|   6  |   >>  | Bitwise Rightshilft/逐位右移 | Shifts the number in binary form by one place in the operation and returns the result./  将操作数的所有位向右移动指定的位数。右移n位相当于除以 2 的 n 次方。  | a >> b | 
4.10.5 赋值运算符(Assignment Operators)
赋值运算符用于为变量赋值。赋值运算符左侧的操作数是变量,右侧的操作数是值。右侧的值必须与左侧的变量属于相同的数据类型,否则编译器会报错。
赋值运算符可以与 C 中的其他运算符组合使用,从而使用单个运算符提供多项运算。这些运算符称为复合运算符。
| 运算符 | 描述 | 实例 | 
|---|---|---|
| = | 简单的赋值运算符,把右边操作数的值赋给左边操作数 | C = A + B 将把 A + B 的值赋给 C | 
| += | 加且赋值运算符,把右边操作数加上左边操作数的结果赋值给左边操作数 | C += A 相当于 C = C + A | 
| -= | 减且赋值运算符,把左边操作数减去右边操作数的结果赋值给左边操作数 | C -= A 相当于 C = C - A | 
| *= | 乘且赋值运算符,把右边操作数乘以左边操作数的结果赋值给左边操作数 | C *= A 相当于 C = C * A | 
| /= | 除且赋值运算符,把左边操作数除以右边操作数的结果赋值给左边操作数 | C /= A 相当于 C = C / A | 
| %= | 求模且赋值运算符,求两个操作数的模赋值给左边操作数 | C %= A 相当于 C = C % A | 
| <<= | 左移且赋值运算符 | C <<= 2 等同于 C = C << 2 | 
| >>= | 右移且赋值运算符 | C >>= 2 等同于 C = C >> 2 | 
| &= | 按位与且赋值运算符 | C &= 2 等同于 C = C & 2 | 
| ^= | 按位异或且赋值运算符 | C ^= 2 等同于 C = C ^ 2 | 
| |= | 按位或且赋值运算符 | C |= 2 等同于 C = C | 2 | 
// C program to illustrate the arithmatic operators
#include <stdio.h>int main()
{int a = 25, b = 5;// using operators and printing resultsprintf("a = b: %d\n", a = b);printf("a += b: %d\n", a += b);printf("a -= b: %d\n", a -= b);printf("a *= b: %d\n", a *= b);printf("a /= b: %d\n", a /= b);printf("a %= b: %d\n", a %= b);printf("a &= b: %d\n", a &= b);printf("a |= b: %d\n)", a |= b);printf("a >>= b: %d\n", a >> b);printf("a <<= b: %d\n", a << b);return 0;
}
 
4.10.6 其它运算符(other Operators)
C 语言中还有一些其他运算符可用于执行某些特定任务。
| 运算符 | 描述 | 实例 | 
|---|---|---|
| sizeof() | 返回变量的大小。 | sizeof(a) 将返回 4,其中 a 是整数。 | 
| & | 返回变量的地址。 | &a; 将给出变量的实际地址。 | 
| * | 指向一个变量。 | *a; 将指向一个变量。 | 
| ? : | 条件表达式 | 如果条件为真 ? 则值为 X : 否则值为 Y | 
点 (.) 和箭头 (->) 运算符:
- 成员运算符用于引用类、结构和联合的单个成员。
 - 点运算符应用于实际对象。
 - 箭头运算符与指向对象的指针一起使用。
 
4.10.7 C 中的一元、二元和三元运算符
运算符还可以根据其处理的操作数数量分为三种类型:
- 一元运算符:处理单个操作数的运算符。
 - 二进制运算符:处理两个操作数的运算符。
 - 三元运算符:处理三个操作数的运算符。
 
4.10.8 C 中的运算符优先级和关联性
运算符的优先级确定表达式中项的组合。这会影响到一个表达式如何计算。某些运算符比其他运算符有更高的优先级,例如,乘除运算符具有比加减运算符更高的优先级。
将按运算符优先级从高到低列出各个运算符,具有较高优先级的运算符出现在表格的上面,具有较低优先级的运算符出现在表格的下面。在表达式中,较高优先级的运算符会优先被计算。
C 中的运算符优先级
运算符优先级确定当表达式具有多个运算符时,首先计算哪个运算符。例如,100-2 * 30将产生 40,因为它被求值为100 - (2 * 30)而不是(100-2)* 30。原因是乘法*的优先级高于减法(-)。
C 中的关联性
是指当表达式中有两个或多个具有相同优先级的运算符时,这些运算符的执行顺序。例如,乘法和除法算术运算符具有相同的优先级,假设我们有一个表达式5 * 2/10,这个表达式将被计算为(5 * 2)/ 10,因为这些运算符的关联性是从左到右。类似地,20/2 * 5将被计算为(20/2)*5。
| 类别 | 运算符 | 结合性 | 
|---|---|---|
| 后缀 | () [] -> . ++ - - | 从左到右 | 
| 一元 | + - ! ~ ++ - - (type)* & sizeof | 从右到左 | 
| 乘除 | * / % | 从左到右 | 
| 加减 | + - | 从左到右 | 
| 移位 | << >> | 从左到右 | 
| 关系 | < <= > >= | 从左到右 | 
| 相等 | == != | 从左到右 | 
| 位与 AND | & | 从左到右 | 
| 位异或 XOR | ^ | 从左到右 | 
| 位或 OR | | | 从左到右 | 
| 逻辑与 AND | && | 从左到右 | 
| 逻辑或 OR | || | 从左到右 | 
| 条件 | ?: | 从右到左 | 
| 赋值 | = += -= *= /= %=>>= <<= &= ^= |= | 从右到左 | 
| 逗号 | , | 从左到右 | 
4.11 判断
C 语言中条件语句的类型(Types of Conditional Statements in C)

- if 语句(Statement)
 - if-else 语句
 - 嵌套(Nested) if 语句
 - if-else-if 梯子
 - switch 语句
 - 条件运算符—— ? : 运算符(三元运算符)
 - 跳转语句:
 
- break
 - continue
 - goto
 - return
 
if-else-if 梯子流程图

switch 语句流程图

条件运算符
(condition) ? [true_statements] : [false_statements];

break

continue

4.12 C语言中的循环(C – Loops)
Loops in programming are used to repeat a block of code until the specified condition is met. A loop statement allows programmers to execute a statement or group of statements multiple times without repetition of code.--编程中的循环用于重复代码块,直到满足指定的条件。循环语句允许程序员多次执行一个语句或一组语句,而无需重复代码
There are mainly two types of loops(循环) in C:

- 入口(Entry)控制回路:在入口控制回路中,在进入回路主体之前检查测试条件。For 循环和 While 循环是 Entry 控制的循环。
 - 退出受控循环: 在出口控制回路中,测试条件在回路主体的末尾进行评估。循环体将至少执行一次,无论条件是真还是假。do-while 循环是 Exit。
 
| 循环类型 | 描述 | 
|---|---|
| while 循环 | 当给定条件为真时,重复语句或语句组。它会在执行循环主体之前测试条件。 | 
| for 循环 | 多次执行一个语句序列,简化管理循环变量的代码。 | 
| do...while 循环 | 除了它是在循环主体结尾测试条件外,其他与 while 语句类似。 | 
| 嵌套循环 | 您可以在 while、for 或 do..while 循环内使用一个或多个循环。 | 
for 循环(Loop)

Syntax(语法):
 for (initialize expression(初始化表达式); test expression(测试表达式); update expression(更新表达式))
{//// body of for loop//
} 
 
example:
for(int i = 0; i < n; ++i)
{printf("Body of for loop which will execute till n");
} 
While 循环(Loop)

语法(Syntax):
 initialization_expression;while (test_expression)
{// body of the while loopupdate_expression;
} 
 
Example:
// C program to illustrate 
// while loop
#include <stdio.h>// Driver code
int main()
{
// Initialization expression
int i = 2; // Test expression
while(i < 10)
{// loop bodyprintf( "Hello World\n"); // update expressioni++;
} return 0;
}
 
do-while 循环
循环主体都将至少执行一次。

 Syntax:
  
 initialization_expression;
do
{// body of do-while loopupdate_expression;} while (test_expression); 
 
Example:
// C program to illustrate 
// do-while loop
#include <stdio.h>// Driver code
int main()
{
// Initialization expression
int i = 2; do
{// loop bodyprintf( "Hello World\n"); // Update expressioni++;// Test expression
} while (i < 1); return 0;
}
 
循环控制语句
循环控制语句改变你代码的执行顺序。通过它你可以实现代码的跳转。
C 提供了下列的循环控制语句。点击链接查看每个语句的细节。
| 控制语句 |  
  | 
|---|---|
| break 语句 | 终止循环或 switch 语句,程序流将继续执行紧接着循环或 switch 的下一条语句。 | 
| continue 语句 | 告诉一个循环体立刻停止本次循环迭代,重新开始下次循环迭代。 | 
| goto 语句 | 将控制转移到被标记的语句。但是不建议在程序中使用 goto 语句。 | 
4.13 函数(Function)
C 中的函数是一组语句,调用时执行某些特定任务。它是 C 程序的基本构建块,提供模块化和代码可重用性。函数的编程语句括在{ } 括号内,具有特定含义并执行特定操作。在其他语言中,它们也称为子例程或过程。
接下来将学习函数、函数定义、声明、参数和形参、返回值等等。
函数的组成包括:
- 返回类型:一个函数可以返回一个值。return_type 是函数返回的值的数据类型。有些函数执行所需的操作而不返回值,在这种情况下,return_type 是关键字 void。
 - 函数名称:这是函数的实际名称。函数名和参数列表一起构成了函数签名。
 - 参数:参数就像是占位符。当函数被调用时,您向参数传递一个值,这个值被称为实际参数。参数列表包括函数参数的类型、顺序、数量。参数是可选的,也就是说,函数可能不包含参数。
 - 函数主体:函数主体包含一组定义函数执行任务的语句。
 
4.13.1 函数的声明(Declarations)
语法(Syntax)

return_type name_of_the_function (parameter_1, parameter_2);
注意:声明函数时,参数名称不是强制性的。我们也可以不使用数据变量的名称来声明函数。
4.13.2 函数的定义

4.13.3 函数的调用
 
注意:函数调用是将程序控制带到函数定义处的必要操作。如果没有调用,函数语句将不会被执行。
代码示例:
  
// C program to show function
// call and definition
#include <stdio.h>// Function that takes two parameters 
// a and b as inputs and returns 
// their sum
int sum(int a, int b) 
{ return a + b; 
}// Driver code
int main()
{// Calling sum function and // storing its value in add variableint add = sum(10, 30);printf("Sum is: %d", add);return 0;
}
 
4.13.4 函数类型

1、库函数
库函数也称为“内置函数”。编译器包中已经包含这些函数,每个函数都有特定含义,并包含在包中。内置函数的优点是无需定义即可直接使用,而用户定义函数必须在使用前声明和定义。
比如:
 pow()、sqrt()、strcmp()、strcpy() 等。 
 
C 库函数的优点
- C 库函数易于使用且经过优化,性能更佳。
 - C 库函数节省了大量时间,即函数开发时间。
 - C 库函数很方便,因为它们总是有效。
 
2、用户定义的函数
程序员创建的函数称为用户定义函数或“定制函数”。用户定义函数可以根据程序员的需求进行改进和修改。
用户定义函数的优点
- 可变功能可以根据需要进行修改。
 - 这些函数的代码可以在其他程序中重复使用。
 - 这些功能易于理解、调试和维护。
 
4.13.5 函数参数类型
调用函数时传递的数据称为实际参数。
形式参数是函数声明中提到的变量和数据类型。

两种方式向 C 函数传递参数:
- 按值传递
 
此方法中的参数传递将值从实际参数复制到形式函数参数中。因此,函数内部所做的任何更改都不会反映在调用者的参数中。
- 通过引用传递(指针)
 
调用者的实际参数和函数的实际参数指向相同的位置,因此函数内部所做的任何更改都会反映在调用者的实际参数中。
C语言函数的不足:
- 无法返回多个值。
 - 由于堆栈帧分配和程序控制传输而导致的内存和时间开销。
 
4.14 C语言的作用规则
C 语言中有三个地方可以声明变量:
- 在函数或块内部的局部变量
 - 在所有函数外部的全局变量
 - 在形式参数的函数参数定义中
 
4.14.1 局部变量
在某个函数或块的内部声明的变量称为局部变量。它们只能被该函数或该代码块内部的语句使用。局部变量在函数外部是不可知的。下面是使用局部变量的实例。在这里,所有的变量 a、b 和 c 是 main() 函数的局部变量。
#include <stdio.h>int main ()
{/* 局部变量声明 */int a, b;int c;/* 实际初始化 */a = 10;b = 20;c = a + b;printf ("value of a = %d, b = %d and c = %d\n", a, b, c);return 0;
} 
4.14.2 全局变量
全局变量在整个程序生命周期内都是有效的,在任意的函数内部能访问全局变量。全局变量可以被任何函数访问。也就是说,全局变量在声明后整个程序中都是可用的。
#include <stdio.h>/* 全局变量声明 */
int g;int main ()
{/* 局部变量声明 */int a, b;/* 实际初始化 */a = 10;b = 20;g = a + b;printf ("value of a = %d, b = %d and g = %d\n", a, b, g);return 0;
} 
在程序中,局部变量和全局变量的名称可以相同,但是在函数内,如果两个名字相同,会使用局部变量值,全局变量不会被使用。
#include <stdio.h>/* 全局变量声明 */
int g = 20;int main ()
{/* 局部变量声明 */int g = 10;printf ("value of g = %d\n",  g);return 0;
} 
4.14.3 形式参数
函数的参数,形式参数,被当作该函数内的局部变量,如果与全局变量同名它们会优先使用。下面是一个实例:
#include <stdio.h>/* 全局变量声明 */
int a = 20;int main ()
{/* 在主函数中的局部变量声明 */int a = 10;int b = 20;int c = 0;int sum(int, int);printf ("value of a in main() = %d\n",  a);c = sum( a, b);printf ("value of c in main() = %d\n",  c);return 0;
}/* 添加两个整数的函数 */
int sum(int a, int b)
{printf ("value of a in sum() = %d\n",  a);printf ("value of b in sum() = %d\n",  b);return a + b;
} 
结果:
value of a in main() = 10
value of a in sum() = 10
value of b in sum() = 20
value of c in main() = 30
注意:
全局变量与局部变量在内存中的区别:
- 全局变量保存在内存的全局存储区中,占用静态的存储单元;
 - 局部变量保存在栈中,只有在所在函数被调用时才动态地为变量分配存储单元。
 
相关文章:
C语言快速学习笔记
学习网站:C 语言教程 | 菜鸟教程 (runoob.com)C 语言教程 | 菜鸟教程 (runoob.com)C 语言教程 | 菜鸟教程 (runoob.com) 这个网站知识完整,讲解清晰。 在线C语言编程工具:菜鸟教程在线编辑器 (runoob.com) 国外学习网站:C语言介…...
如何选择易用性高的项目管理软件?
随着项目管理在各行各业的广泛应用,选择一款易用性高的项目管理软件变得越来越重要。易用性高的软件可以帮助企业提高工作效率,降低管理成本,同时还能提升团队之间的协作能力。那么,如何选择一款易用性高的项目管理软件呢…...
vue3基于uni-app 封装小程序request请求
const BASE_URL https://47.122.26.142; // 替换为你的 API 基础 URL const token uni.getStorageSync(token);const request (url: string, method: any, data {}, headers {}) > {return new Promise((resolve, reject) > {uni.request({url: ${BASE_URL}${url},m…...
YOLO在目标检测与视频轨迹追踪中的应用
YOLO在目标检测与视频轨迹追踪中的应用 引言 在计算机视觉领域,目标检测与视频轨迹追踪是两个至关重要的研究方向。随着深度学习技术的飞速发展,尤其是卷积神经网络(CNN)的广泛应用,目标检测与视频轨迹追踪的性能得到…...
版本控制系统:Git 纯应用(持续更新)
基本操作 ctrl上行键:上次代码 本地仓库:Git init 新建文件:touch xxxx.xxx 查看状态:Git status 文件从工作区——暂存区:Git add ./文件名(.是通配符代表所有) 暂存区——仓库:Git commit -m &…...
从0开始搭建vue项目
#先查下电脑有没有安装过node和npm node -v npm -v #安装vue npm install -g vue #安装webpack npm install webpack -g 都安装好后,进入你想创建的文件夹内 创建名字:vue init webpack <project_name> 就默认回车 然后根据项目需求Y/n 比如…...
Java框架常见面试题
在Java框架面试中,面试官通常会考察候选人对常见Java框架的理解、使用经验以及解决问题的能力。以下是一些常见的Java框架面试题及其详细回答: 1. Spring框架相关问题 问题:Spring框架的核心组件有哪些?它们各自的作用是什么&am…...
linux c 应用编程定时器函数
在 Linux C 应用编程中,对于多线程编程中的定时器函数使用,通常可以借助 pthread 库和系统提供的定时器相关的函数来实现。 首先,常见的定时器函数有 setitimer() 和 alarm() 。setitimer() 函数可以更精确地设置定时器,它可以设…...
设备调试上位机GUI
C Fast Qt C 前端 原来真的不需要在 design 上画来画去,有chat-gpt 那里不知道问哪里 全是组件拼起来的,不需要画,最后发现其实也是定式模式,跟着AI 学套路 最终前端界面 鼠标邮件绑定几个功能 太nice 了 在再加一个全局的日志模块 yyds MVC 的架构, 视图…...
项目管理系统厂商:奥博思发布《项目管理系统助力 IPD 高效落地》演讲
一场题为:“标准为基,项目之上 ,持续提升 PMO 卓越中心”的全国 PMO 专业人士年度盛会在京召开。会议围绕 PMO 卓越中心能力提升、项目管理标准化、项目管理体系建设等核心话题力邀业界专家、卓有建树的 PMO 实践精英来演讲、交流、分享。 奥…...
Java项目总结1
1.什么是面向对象(此对象非彼对象) “面向对象的方法主要是把事物给对象化,包括其属性和行为。面向对象编程更贴近实际生活的思想。总体来说面向对象的底层还是面向过程,面向过程抽象成类,然后封装,方便使用…...
Java中的类加载机制详解
Java中的类加载机制详解 大家好,我是微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿! 类加载机制概述 在Java中,类加载机制是Java虚拟机(JVM)将.class文件加载到内存中并转换…...
SwiftUI 中 Grid 内多个 NavigationLink 同时发生导航之诡异问题的解决
问题现象 不知小伙伴们发现了没有?在 SwiftUI 中如果有多个 NavigationLink 视图嵌入在 Grid(包括 LazyVGrid 和 LazyHGrid)容器中,点击其中任意一个 NavigationLink 都会导致所有导航一起发生。 如上图所示,点击 Grid 中任何一个 NavigationLink,所有 NavigationLink 都…...
51单片机第21步_将TIM0用作两个8位定时器同时将TIM1用作波特率发生器
本章重点讲解将TIM0用作两个8位定时器,同时将TIM1用作波特率发生器。 当定时器T0在方式3时,T1不能产生中断,但可以正常工作在方式0、1、2下,大多数情况下,T1将用作串口的波特率发生器。 1、定时器0工作在模式3框图&a…...
API-元素尺寸与位置
学习目标: 掌握元素尺寸与位置 学习内容: 元素尺寸与位置仿京东固定导航栏案例实现bilibili点击小滑块移动效果 元素尺寸与位置: 使用场景: 前面案例滚动多少距离,都是我们自己算的,最好是页面滚动到某个…...
C语言中的基础指针操作
在C语言中,指针是一个非常重要的概念,它提供了直接访问内存地址的能力。指针变量用于存储内存地址,而不是数据值,在某种意义上和门牌号具有相似含义:指针是一个变量,其存储的是另一个变量的内存地址&#x…...
LabVIEW环境下OCR文字识别的实现策略与挑战解析
引言 在自动化测试领域,OCR(Optical Character Recognition,光学字符识别)技术扮演着重要角色,它能够将图像中的文字转换成机器可编辑的格式。对于使用LabVIEW约5个月,主要进行仪器控制与数据采集的你而言…...
中英双语介绍美国的州:堪萨斯州(Kansas)
中文版 堪萨斯州简介 堪萨斯州(Kansas)位于美国中部,以其广阔的平原、丰富的农业资源和多样的文化遗产而著称。以下是对堪萨斯州的详细介绍,包括其地理位置、人口、经济、教育、文化和主要城市。 地理位置 堪萨斯州位于美国中…...
信息收集---端口服务信息收集
1. 什么是端口 是设备与外界通讯交流的出口。端口可分为虚拟端口和物理端口,其中虚拟端口指计算机内部或交换机路由器内的端口,不可见。例如计算机中的80端口、21端口、23端口等。物理端口又称为接口,是可见端口,计算机背板的RJ45…...
Python知识点背诵手册,超详细知识梳理
一、手册介绍 《Python知识点背诵手册》是一份详尽的Python学习资料,旨在帮助学习者系统地掌握Python语言的基础知识和进阶技能。该手册将Python的所有关键语法和概念进行了精炼的总结,并以易于理解和记忆的方式呈现。以下是手册的主要特点和内容概述&a…...
在软件开发中正确使用MySQL日期时间类型的深度解析
在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...
Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误
HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误,它们的含义、原因和解决方法都有显著区别。以下是详细对比: 1. HTTP 406 (Not Acceptable) 含义: 客户端请求的内容类型与服务器支持的内容类型不匹…...
Java 语言特性(面试系列1)
一、面向对象编程 1. 封装(Encapsulation) 定义:将数据(属性)和操作数据的方法绑定在一起,通过访问控制符(private、protected、public)隐藏内部实现细节。示例: public …...
(十)学生端搭建
本次旨在将之前的已完成的部分功能进行拼装到学生端,同时完善学生端的构建。本次工作主要包括: 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...
从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路
进入2025年以来,尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断,但全球市场热度依然高涨,入局者持续增加。 以国内市场为例,天眼查专业版数据显示,截至5月底,我国现存在业、存续状态的机器人相关企…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...
解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错
出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上,所以报错,到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本,cu、torch、cp 的版本一定要对…...
Kafka入门-生产者
生产者 生产者发送流程: 延迟时间为0ms时,也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于:异步发送不需要等待结果,同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...
在 Spring Boot 项目里,MYSQL中json类型字段使用
前言: 因为程序特殊需求导致,需要mysql数据库存储json类型数据,因此记录一下使用流程 1.java实体中新增字段 private List<User> users 2.增加mybatis-plus注解 TableField(typeHandler FastjsonTypeHandler.class) private Lis…...
【LeetCode】算法详解#6 ---除自身以外数组的乘积
1.题目介绍 给定一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O…...


