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助手:

  1. GitHub Copilot
  2. 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 中,有两种简单的定义常量的方式:

  1. 使用 #define 预处理器: #define 可以在程序中定义一个常量,它在编译时会被替换为其对应的值。
  2. 使用 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 存储类可以提高程序的运行速度。

cpp 复制代码
register int  miles;

4.9.3 static 存储类

cs 复制代码
static int count=10;        /* 全局变量 - static 是默认的 */

static 存储类指示编译器在程序的生命周期内保持局部变量的存在,而不需要在每次它进入和离开作用域时进行创建和销毁。因此,使用 static 修饰局部变量可以在函数调用之间保持局部变量的值。

static 修饰符也可以应用于全局变量。当 static 修饰全局变量时,会使变量的作用域限制在声明它的文件内。

全局声明的一个 static 变量或方法可以被任何函数或方法调用,只要这些方法出现在跟 static 变量或方法同一个文件中。

静态变量在程序中只被初始化一次,即使函数被调用多次,该变量的值也不会重置。

4.9.4 extern 存储类

cs 复制代码
extern void write_extern();

extern 存储类用于定义在其他文件中声明的全局变量或函数。当使用 extern 关键字时,不会为变量分配任何存储空间,而只是指示编译器该变量在其他文件中定义。

4.10 运算符

在 C 语言中,运算符是表示要对一个或多个操作数执行的操作的符号。它们是 C 编程的基本组件

运算符是一种告诉编译器执行特定的数学或逻辑操作的符号。C 语言内置了丰富的运算符,并提供了以下类型的运算符:

C 语言提供了广泛的运算符,根据其功能可以分为 6 种类型:

  1. 算术运算符
  2. 关系运算符
  3. 逻辑运算符
  4. 位运算符
  5. 赋值运算符
  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) 为真。
cs 复制代码
// C program to illustrate the relational operators
#include <stdio.h>

int main()
{

    int a = 25, b = 5;

    // using operators and printing results
    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.3 C 语言中的逻辑运算符

逻辑运算符用于组合两个或多个条件/约束,或补充所考虑的原始条件的评估。逻辑运算符操作的结果是一个布尔值,可以是 truefalse

运算符 描述 实例
&& 称为逻辑与运算符。如果两个操作数都非零,则条件为真。 (A && B) 为假。
|| 称为逻辑或运算符。如果两个操作数中有任意一个非零,则条件为真。 (A || B) 为真。
! 称为逻辑非运算符。用来逆转操作数的逻辑状态。如果条件为真则逻辑非运算符将使其为假。 !(A && B) 为真。
cs 复制代码
// C program to illustrate the logical operators
#include <stdio.h>

int main()
{

    int a = 25, b = 5;

    // using operators and printing results
    printf("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。 > 0&0=0; > 0&1=0; > 1&0=0; > 1&1=1; | a & b |
| 2 | | | ****Bitwise OR/****按位或 | Performs bit-by-bit OR operation and returns the result./对两个操作数的每一位执行逻辑或操作。 **解释:**如果两个相应的位都为 0,则结果为 0,否则为 1。 > 0|0=0; > 0|1=1; > 1|0=1; > 1|1=1; | a | b |
| 3 | ^ | ****Bitwise XOR/****按位异或 | Performs bit-by-bit XOR operation and returns the result./对两个操作数的每一位执行逻辑异或操作。 **解释:**如果两个相应的位值相同,则结果为 0,否则为 1。 > 0^0=0; > 0^1=1; > 1^0=1; > 1^1=0; | a ^ b |
| 4 | ~ | ****Bitwise First Complement/****逐位第一补码 | Flips all the set and unset bits on the number./ 对操作数的每一位执行逻辑取反操作。 **解释:**即将每一位的 0 变为 1,1 变为 0。 > ~1=-2; > ~0=-1; | ~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
cs 复制代码
// C program to illustrate the arithmatic operators
#include <stdio.h>

int main()
{

    int a = 25, b = 5;

    // using operators and printing results
    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);
    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 中的一元、二元和三元运算符

运算符还可以根据其处理的操作数数量分为三种类型:

  1. ****一元运算符:****处理单个操作数的运算符。
  2. ****二进制运算符:****处理两个操作数的运算符。
  3. ****三元运算符:****处理三个操作数的运算符。

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)

  1. if 语句(Statement)
  2. if-else 语句
  3. 嵌套(Nested) if 语句
  4. if-else-if 梯子
  5. switch 语句
  6. 条件运算符------ ? : 运算符(三元运算符)
  7. 跳转语句:
  • 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:

  1. 入口(Entry)控制回路: 在入口控制回路中,在进入回路主体之前检查测试条件。For 循环和 While 循环是 Entry 控制的循环。
  2. 退出受控循环: 在出口控制回路中,测试条件在回路主体的末尾进行评估。循环体将至少执行一次,无论条件是真还是假。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:

cs 复制代码
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 loop
    
    update_expression;
}

Example:

cs 复制代码
// C program to illustrate 
// while loop
#include <stdio.h>

// Driver code
int main()
{
// Initialization expression
int i = 2; 

// Test expression
while(i < 10)
{
	// loop body
	printf( "Hello World\n"); 
	
	// update expression
	i++;
} 

return 0;
}

do-while 循环

循环主体都将至少执行一次

Syntax:

复制代码
initialization_expression;
do
{
    // body of do-while loop
    
    
    update_expression;

} while (test_expression);

Example:

cs 复制代码
// C program to illustrate 
// do-while loop
#include <stdio.h>

// Driver code
int main()
{
// Initialization expression
int i = 2; 

do
{
	// loop body
	printf( "Hello World\n"); 

	// Update expression
	i++;
	
	// 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 函数的调用

注意: 函数调用是将程序控制带到函数定义处的必要操作。如果没有调用,函数语句将不会被执行。

代码示例:

cs 复制代码
// 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 variable
  int 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语言函数的不足:

  1. 无法返回多个值。
  2. 由于堆栈帧分配和程序控制传输而导致的内存和时间开销。

4.14 C语言的作用规则

C 语言中有三个地方可以声明变量:

  1. 在函数或块内部的局部变量
  2. 在所有函数外部的全局变量
  3. 形式参数的函数参数定义中

4.14.1 局部变量

在某个函数或块的内部声明的变量称为局部变量。它们只能被该函数或该代码块内部的语句使用。局部变量在函数外部是不可知的。下面是使用局部变量的实例。在这里,所有的变量 a、b 和 c 是 main() 函数的局部变量。

cs 复制代码
#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 全局变量

全局变量在整个程序生命周期内都是有效的,在任意的函数内部能访问全局变量。全局变量可以被任何函数访问。也就是说,全局变量在声明后整个程序中都是可用的。

cs 复制代码
#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;
}

在程序中,局部变量和全局变量的名称可以相同,但是在函数内,如果两个名字相同,会使用局部变量值,全局变量不会被使用。

cs 复制代码
#include <stdio.h>
 
/* 全局变量声明 */
int g = 20;
 
int main ()
{
  /* 局部变量声明 */
  int g = 10;
 
  printf ("value of g = %d\n",  g);
 
  return 0;
}

4.14.3 形式参数

函数的参数,形式参数,被当作该函数内的局部变量,如果与全局变量同名它们会优先使用。下面是一个实例:

cs 复制代码
#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

注意:

全局变量与局部变量在内存中的区别

  • 全局变量保存在内存的全局存储区中,占用静态的存储单元;
  • 局部变量保存在栈中,只有在所在函数被调用时才动态地为变量分配存储单元。
相关推荐
TeYiToKu17 分钟前
笔记整理—linux驱动开发部分(9)framebuffer驱动框架
linux·c语言·arm开发·驱动开发·笔记·嵌入式硬件·arm
dsywws20 分钟前
Linux学习笔记之时间日期和查找和解压缩指令
linux·笔记·学习
道法自然040221 分钟前
Ethernet 系列(8)-- 基础学习::ARP
网络·学习·智能路由器
爱吃生蚝的于勒27 分钟前
深入学习指针(5)!!!!!!!!!!!!!!!
c语言·开发语言·数据结构·学习·计算机网络·算法
cuisidong19972 小时前
5G学习笔记三之物理层、数据链路层、RRC层协议
笔记·学习·5g
乌恩大侠2 小时前
5G周边知识笔记
笔记·5g
南宫理的日知录2 小时前
99、Python并发编程:多线程的问题、临界资源以及同步机制
开发语言·python·学习·编程学习
数据与后端架构提升之路3 小时前
从神经元到神经网络:深度学习的进化之旅
人工智能·神经网络·学习
一行13 小时前
电脑蓝屏debug学习
学习·电脑
咔叽布吉3 小时前
【论文阅读笔记】CamoFormer: Masked Separable Attention for Camouflaged Object Detection
论文阅读·笔记·目标检测