【C语言深度剖析】关键字(全)

news2024/10/6 10:26:30

文章目录

  • 一.存储类型关键字
    • 前言
      • 补充1:内存
      • 思考:
      • 补充2:变量与内存的关系
      • 补充3:变量的分类
      • 补充4:存储类
      • 补充5:删除数据是怎么删除的?
    • 1.auto
    • 2.register
    • 3.static
    • 4.extern
      • 基本用法:
      • 基本功能
    • 5.typedef
      • typedef与define的对比
  • 二.数据类型关键字
    • 1.为什么要有那么多的数据类型?
    • 2.数据类型的大小?数据类型的范围?
    • 3.数据在内存中是如何存储的?
        • 数据类型
        • 内存数据的存储
    • 4.数据到内存中的转换?
        • 1.整型
          • 正数
          • 负数
        • 2.浮点型
          • 浮点数的在内存中的存储方式
          • float类型的比较
    • 5.强制类型转化与真类型转换
      • 0的实际意义
      • 6.自定义类型
  • 三.条件判断关键字
    • 1.if语句与bool值
      • 1.if语句执行的具体逻辑
    • 3.bool值
      • 1.bool值到底有没有?
    • 4.switch(开关语句关键字)
    • 5.goto
  • 四.循环语句关键字
    • 循环操作符的基本结构
      • while
      • do while
      • for
    • break 的使用
    • continue
      • while
      • do while
      • for
    • 死循环
      • do while
      • while
      • for
  • 五 .返回与其余关键字
    • 1.const
    • 2.sizeof
    • 3.return
    • 4.volatile
  • 五 总结

一.存储类型关键字

前言

补充1:内存

内存:用于暂时存放CPU中的运算数据,以及与硬盘等外部存储器交换的数据。它是外存与CPU进行沟通的桥梁,计算机中所有程序的运行都在内存中进行,内存性能的强弱影响计算机整体发挥的水平。
图解:
在这里插入图片描述
补充:外存:又称为辅存,是指除计算机内存及CPU缓存以外的存储器,此类存储器断电后仍能保存数据。常见的外存有硬盘、光盘、U盘等。CPU如果想访问外存中的数据,必须先把外存的数据保存到内存中,CPU再去读取内存中的数据。

思考:

一般我们点击图标打开程序,这一步计算机做了什么?
答:将程序加载到内存中
那为什么要将程序加载到内存中呢?
答:为了提高程序运行的速度。
为什么不用寄存器做为内存的主要部分,这样不是更快吗?
答:寄存器的成本过高,为了使计算机的成本更加亲民,使用了分布式缓存技术,降低了电脑的造价成本的同时,还使电脑的整体效率得到提升。

补充2:变量与内存的关系

变量的类型决定了此变量开辟的空间大小,开辟空间的大小又决定了所存数据的范围,而变量的地址决定了变量的唯一性,在内存中此变量的地址为变量的寻找提高了极大的效率。
举例:如同:要吃饭,不是所有的饭菜都要立马被你吃掉。饭要一口一口吃,那么你还没有吃到的饭菜,就需要暂时放在盘子里。这里的盘子,就如同变量,饭菜如同变量里面的数据

补充3:变量的分类

1.全局变量(具有外部链接属性,也就是其它文件能使用)
2.静态的全局变量(不具有外部链接属性,同理)
3.局部变量(在代码段中的变量)——进大括号创建,出大括号销毁
说明:代码块:用{}括起来的区域,就叫做代码块
说明:临时变量,自动变量 也称为局部变量
4.静态的局部变量(在代码段中被static修饰的变量)

关键字static具体可看:初始C语言第三篇:常用操作符与关键字
变量的具体内容请看:【初始C语言】变量与字符

int main()
{
	int a = 0;
	//这里的a变量在开辟的时候,会看其类型为int(4个字节),在内存中寻找4的字节的空间,并为其变量分配地址
	//然后将0值放在a变量的空间中,使CPU能通过地址,准确地对变量a进行操作。
	return 0;
}

补充4:存储类

1.静态存储区的变量:全局变量,static修饰的局部变量
2.动态存储区的变量:局部变量(前不加static)
静态存储区的变量的关键字:exern static
动态存储区的变量的关键字:register auto

补充5:删除数据是怎么删除的?

安装下载的时候,那么慢,但是删除只需要几秒这是为啥?
答:删除数据并不是真正的删除了,而是将数据设置为无效数据,这样新的数据就可以将原来的数据进行覆盖。

1.auto

auto 自动存储变量的关键字,实际用处不大。
1.仅在语句块内部使用。
2.不可修饰全局变量
3.修饰对象的生命周期和作用域都只在本代码块
说明:不加修饰的局部变量的生命周期和作用域
生命周期:进大括号创建,出大括号销毁。
作用域:仅在本代码块中有效。
4.对象是具有自动存储期的变量:进入大括号创建出去大括号销毁。

错误提示:

auto int a = 1;//这是错误的,虽然能在VS2019上运行
int main()
{
	printf("%d", a);
	return 0;
}

2.register

1.修饰的对象为具有自动存储期的变量。(全局变量尽量不用,因为会长期占用寄存器)
2.register修饰的变量不能取地址,因为变量有可能呗放在寄存器里面,而寄存器没有地址。
3.register修饰的变量的值可以被修改
4.register修饰的变量 ,是被尽量放在寄存器里面,最终决定是否被放在寄存器里面是由编译器所决定的。

使用建议:

1.被高频使用的变量
2.尽量不要大量使用register
3.不用写回内存的变量
4.对象尽可能为局部变量

补充:如果寄存器中已满,则将由计算机硬件将寄存器中最久未使用的变量调入到高速缓冲存储器(Cache)中,同时放入你的变量。(这是由编译器的实现原理来决定的)

3.static

对象:函数,全局变量,局部变量。
1. 对于函数和全局变量来说,加上static将作用范围锁定在了本文件中,将外部链接属性改为内部链接属性,也就是说只能在本文件中使用,而在其他文件则不能使用,使变量和函数的使用更加安全。
2.对于局部变量来说,static将局部变量的生命周期改为全局,本质上是将局部变量由栈区移至堆区,但作用域并不会发生变化。

具体可看:常用操作符与关键字

4.extern

基本用法:

1.变量:extern +数据类型+变量名+; 注意:声明的时候不可对变量进行赋值。
2.extern是对外部变量进行的声明

基本功能

1.跨文件使用
对于全局变量(不被static修饰),和函数(不被static修饰),因为static会改变变量或者函数的外部链接属性,而导致声明无法使用。
说明:具体例子可看:常用操作符与关键字
2.逆顺序使用
当要在函数的定义之前使用此变量,(编译器是从上往下扫描的)要告诉编译器有这个函数,所以我们要声明一下(没有这个声明,函数也能进行运行,但是会提醒你未定义)。

例:

//extern  int add(int, int); 这最好加上
int main()
{
	int ret = add(1, 2);
	printf("%d", ret);
	return 0;
}
int add(int x, int y)
{

	return x + y;
}

图解:
在这里插入图片描述

5.typedef

基本用法: typedef +已有类型+命名+; 注意:这里的;不可以省去

1.对不加修饰的类型进行重命名

举例:

typedef unsigned int u_int;
int main()
{
	u_int j = 0;
	return 0;
}

2.对结构体重命名

举例:

typedef struct Student
{
	char name[10];
	int age;
	int sex;
	char numbers[32];
}Student;

3.对数组类型重命名

typedef int arr[4];
int main()
{
	arr x = {0};
	//跟 int x[4]={0};等效
	return 0;
}

4.对数组指针类型重命名

typedef int (*ptr)[4];

int main()
{
	ptr a = NULL;
	//我们可以把这里的ptr a理解为把a替换到int (*ptr)[4]的ptr中
	//也就是int(*a)[4];
	return 0;
}

5.函数指针重命名

举例:

typedef int(*ptr1)(int, int);
int add(int x, int y)
{
	return x + y;
}
int main()
{
	int (*p)(int, int) = NULL;
	p = add;
	int ret = (*p)(1, 2);
	printf("%d\n", ret);
	ptr1 p2 = add;
	//同理我们可以把这里的ptr1 p2理解为把a替换到int(*ptr1)(int, int)的ptr1中
	//也就是int (*p2)(int, int)
	ret = (*p2)(3, 3);
	printf("%d\n", ret);
	return 0;
}

typedef与define的对比

typedef:是对类型进行封装,使之成为一个真正的类型。
define:定义类型是对类型进行替换

代码:

#define ptr int* 
typedef int* ptr1;
typedef static int ptr1;//这个定义是错误的,因为这个算是对本身变量的修饰而改变了改变量的存储形式,
//typedef只能是封装一个存储类型,而int已经是一个存储类型了,所以加上static不能修饰。
int main()
{
	int* p1, p2, * p3;//p1,p3为指针,p2为整形变量
	ptr p4, p5, * p6;//p4,p6为指针,p5为整形变量
	ptr1 p7, p8, p9;//p7,p8,p9都为指针
	return 0;
}

二.数据类型关键字

数据类型关键字
char :声明字符型变量或函数
short :声明短整型变量或函数
int : 声明整型变量或函数
long :声明长整型变量或函数
signed :声明有符号类型变量或函数
unsigned :声明无符号类型变量或函数
float :声明浮点型变量或函数
double :声明双精度变量或函数
struct :声明结构体变量或函数
union :声明共用体(联合)数据类型
enum :声明枚举类型
void :声明函数无返回值或无参数,声明无类型指针

1.为什么要有那么多的数据类型?

数据类型决定开辟空间的大小和内存的存储方式,不同的数据根据需求需要放在不同的数据类型当中以便于能够准确使用。

图解:
在这里插入图片描述

说明:这是月饼的模具,你想要什么样的月饼,就有什么样的模具,对应到数据类型中是不是跟形象?你想存什么样的类型的数据,就用什么"模具"——数据类型

int main()
{
	int x = 0;
	//这里的意思是在空间中开辟4个字节,把0的补码放在内存中。
	return 0;
}

2.数据类型的大小?数据类型的范围?

大小用sizeof关键字进行求解,范围根据类型能够存储的数据的空间和是否是有符号位和无符号位有关,无符号位的数据类型的范围是大于等于0的。

代码:求解基本类型的大小

#include<stdio.h>
int main()
{
	printf("%d\n", sizeof(char)); //1(单位字节)
	//signed char (-2的八次方,2的八次方减一),这是闭区间
	printf("%d\n", sizeof(short)); //2
	//short (-2的16次方,2的16次方减一),这是闭区间
	printf("%d\n", sizeof(int)); //4
	//int (-2的32次方,2的32次方减一),这是闭区间
	printf("%d\n", sizeof(long)); //32位时4,64位可能是8(取决于编译器)
	//long(-2的32次方,2的32次方减一),这是闭区间
	printf("%d\n", sizeof(long long)); //8
	//long long(-2的64次方,2的64次方减一),这是闭区间
	printf("%d\n", sizeof(float)); //4
	float(-2的32次方,2的32次方减一),这是闭区间
	printf("%d\n", sizeof(double)); //8
	double(-2的64次方,2的64次方减一),这是闭区间
	printf("%d\n", sizeof(void));//vs下是0,Linux下是1
	return 0;
}

说明:如果数据类型为有符号位,则符号位为1其它数字为0存的是此类型的最小负数(这是半计算——是负数,规定——表示最小负数),编译器是直接识别此数据的补码而转换成最小数据的,可不要使用原码反码进行计算

3.数据在内存中是如何存储的?

数据类型

在这里插入图片描述

我们需要判断数据的大致类型,有整形家族,浮点型家族,构造类型(数组,结构体,枚举类型),void类型。
说明:void类型的变量是不一定不能够定义的;
1.在Linux系统下void类型的大小是1个字节,说明void类型有大小.
2.在VS2019下,void的大小是0,也就是开辟空间为0,也就是没开辟。既然没开辟空间那数据也无法放进去,所以vs会自动识别void是不能够进行定义变量的。

内存数据的存储

1.左值和右值的类型没有太大的冲突(在一个数据的大类)。
举例:比如说int和unsigned int都在整形家族中,没有太大的类型冲突,所以可以将右值数据在内存中的存储形式,直接放在左值的空间当中,但在存入时需要考虑截断(数据类型的大小)和大小端(内存存储的方式)的问题。

说明:
1.截断:
 截断数据类型空间大的数据放在数据类型空间小的数据类型,需要将空间大的在内存中的数据进行从低位到高位开始数到目标变量的大小能存的最大位数为止.
2.大小端:

int main()
{
	int a = 0x11223344;
	return 0;
}

内存:
在这里插入图片描述

说明:前面的0x00EFF860是此变量的地址

为什么不是:11 22 33 44呢?
这里要引出大小端的问题:
大端(存储)模式,是指数据的低位保存在内存的高地址中,而数据的高位保存在内存的低地址
中;
小端(存储)模式,是指数据的低位保存在内存的低地址中,而数据的高位保存在内存的高地址
简单来说:大异小同。

4.数据到内存中的转换?

1.整型

正数

说明:源码,反码,补码相同。
举例1:

int a =1;

源码:00000000000000000000000000000001
反码:00000000000000000000000000000001
补码:00000000000000000000000000000001(在内存中实际存的数据)
注意:计算机并不是直接把正数的源码存进去了,而是把源码转换为补码存进去了。

负数

说明:遵循着运算逻辑——反码等于源码按位取反(符号位,也就是最高位不变,把源码中的0变成1,1变成0),补码等于反码加上1。
图解:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

特殊:int的取值范围:-2147483648 ~2147483647
负数的最小值的存储为:10000000000000000000000000000000(这是补码,并且这是语法规定的)
因此我们可以这样记住负数与正数的存储形式:

在这里插入图片描述
我们可以看出,这是一个轮回,是不是很神奇?

2.浮点型

浮点数的在内存中的存储方式

可看:数据的存储形式

float类型的比较

1.浮点数的计算存在误差:一个数存到浮点数当中会发生一定的误差,这个误差很小
2.浮点数进行计算两数相差是否等于0并不能直接与0进行比较, 应该与规定的最小的精度进行比较,如果比规定的最小精度小那就判断两值相等;反之不等。
说明:这个精度可以自己定义,因为有些时候可能相减的结果比最小的精度大,但我们看上去确实是相等的。
3.如果两数相差等于最小的精度,这时我们最好判断两值不相等,因为最小精度是规定与0不相等相等的最小精度,也就是只有比最小精度小才可以算做相等。

错误示范:

#include <sdtio.h>
int main()
{
	float x = 1.0;
	float y = 0.9;
	float z = x - y-0.1f;
	printf("%.23f\n", z);
	if (fabs(z) == 0.0f)
	{
		printf("与0相等");
	}
	else
	{
		printf("与0不相等");
	}
	return 0;
}

正确示范:

int main()
{

	float x = 1.0;
	float y = 0.9;
	float z = x - y-0.1;
	printf("%.23f\n", z);
	printf("%.23f\n", FLT_EPSILON);
	if (fabs(z) < FLT_EPSILON)
	{
		printf("与0相等");
	}
	else
	{
		printf("与0不相等");
	}
	return 0;
}

5.强制类型转化与真类型转换

0的实际意义

1.字符0
2.字符换行符
3.空指针

#include <sdtio.h>
int main()
{

	void* p = NULL;// ((void *)0)
	char str = '0';// 48
	char str1 = '\0';// 0
	printf("%d %d %d", p, str, str1);
	return 0;
}

真的类型转换比如把字符串“123456”和整形123456互相转换。

1.数字转字符

#include <sdtio.h>
void num_to_strings(int x)
{
	if (x > 9)
	{
		num_to_strings(x / 10);
	}
	printf("%c", "0123456789"[x%10]);
	//如果想要保存,则需要再传进去一个字符数组。
}
int main()
{
	num_to_strings(123456);
	return 0;
}

1.字符串转数字
说明:此代码只适用于全为数字的字符串中。

//字符数字转换为整形数字
void strings_to_num(char* p)
{

	int len = strlen(p);
	int num = 0;
	for (int i = len; i > 0; i--)
	{
		int tmp1 = i;
		int tmp2 = 1;
		while (tmp1 > 1)
		{
			tmp2 = tmp2 * 10;
			tmp1--;
		}
		num = num +((*p++) - 48) * tmp2;
		//这一步是将字符转换为数字,再将数字乘以10的位数减一次方。
	}
	printf("%d", num);
}
int main()
{
	strings_to_num("123456");
	return 0;
}

6.自定义类型

结构体+枚举+联合体

三.条件判断关键字

if : 条件语句
else :条件语句否定分支
goto :无条件跳转语句
开关语句 (3个)
switch :用于开关语句
case :开关语句分支
default :开关语句中的“其他”分支

1.if语句与bool值

1.if语句执行的具体逻辑

1.对表达式进行求值
2.对表达式的结果(逻辑结果或者说bool结果)进行判断(0为假,非0为真)
3.如果为真执行if的下面的语句,这是分支功能。
说明:条件结构的语法的基本功能:
1.分支功能
2.条件判断功能
else与最近的if进行匹配
例如:

int main()
{
	int i = 0;
	int j = 1;
	if (1 == i)
		if (1 == j)
			printf("hello world\n");
	else
		printf("i与1不相等");//else与最近的一个if进行匹配
		//代码运行的结果为啥也不打印
	return 0;
}

3.bool值

1.bool值到底有没有?

C89,C90没有,C99在stdbool.h中引入bool

说明:c99中用define定义bool类型,bool类型的大小为1个字节

注意:VS2019中有微软定义bool 是用int进行typedef的,但是不推荐,因为这样只能在VS的编译器上能跑过,其他平台上不一定能跑过。

4.switch(开关语句关键字)

  1. switch()中只能有整形家族的变量,常量,整形表达式
    2.case 后边的情况取值只能用常量

3.switch()和case的情况的取值,共同实现判断功能,
4. case后面的代码块如果不加大括号是不能定义变量的。
5. break 将每个case分割开而实现分支功能

建议:
1.case里面的代码不建议带return
2.default处理默认情况也就是除了case之外的情况,建议放在最末尾
3.case情况排列按顺序或者按字母排序

除此之外:有一个比较有意思的代码

int main()
{
	int i = 0;
	scanf("%d", &i);
	switch (i)
	{
		 int j = 0;//这句代码,实际上并不会被执行,但是却被定义了
		 //这是因为在编译的时候,会将变量进行处理,导致在运行的时候,我们会
		 //看见这句代码实际上只起了定义变量的作用
	case 1:
		j = 1;
		printf("%d\n", j);
		printf("你好!\n");
		break;
	case 2:
		printf("再见!\n");
		break;
	case 3:
		printf("找个对你好的!\n");
		break;
	default:
		printf("我emo了!\n");
		break;
	}
	return 0;
}

5.goto

说明:go to实际上并不是不用,而是用的场景我们目前还接触不到。

具体语法:分支与循环(下)

四.循环语句关键字

循环操作符的基本结构

循环都包括三部分
1.条件初始化
2.条件判断
3.条件调整
说明:根据实际情况可以适当的少用上面的部分。

while

int main()
{



	int i = 0;// 条件初始化
	while (i < 9)// 条件判断
	{
		i++;//条件调整
		printf("i=%d\n", i);		
	}
	return 0;
}

do while

int main()
{
	int i = 0;// 条件初始化
	do
	{
		i++; //条件调整
		printf("i=%d\n", i);
	} while (i < 9);// 条件判断
	return 0;
}

for

#include<stdio.h>
int main()
{

	for (int i = 0; i < 9; i++)
	//第一个部分为条件初始化
	//第二部分为条件判断
	//第三个部分为条件调整
	{
		printf("%d", i);
	}
	return 0;
}

break 的使用

break 只能用循环吗?答案是no,也可以用于switch分支语句中。
如果有多层循环/switch:
break跳过最进的一层循环。
break终止最近的一层switch

int main()
{
	for (int i = 0; i < 9; i++)
	{
		printf("i==%d\n", i);
		for (int j = 0; j < 9; j++)
		{
			printf("j==%d\n", j);
			if (5 == j)
			{
				break;//当j等于5时,只会跳出离for循环最近的一层。
			}
		}
	}
	return 0;
}

continue

while

int main()
{



	int i = 0;// 条件初始化
	while (i < 9)// 条件判断
	{
		continue;//跳到条件判断部分
		i++;//条件调整
		printf("i=%d\n", i);		
	}
	return 0;
}

do while

int main()
{
	int i = 0;// 条件初始化
	do
	{
		i++; //条件调整
		continue;//跳到条件判断部分
		printf("i=%d\n", i);
	} while (i < 9);// 条件判断
	return 0;
}

for

#include<stdio.h>
int main()
{

	for (int i = 0; i < 9; i++)
	//第一个部分为条件初始化
	//第二部分为条件判断
	//第三个部分为条件调整
	{
		continue;//跳到条件调整部分
		printf("%d", i);
	}
	return 0;
}

死循环

do while

#include<stdio.h>
int main()
{
  do
  {
  }while(1);//判断部分为非0,一直为真————这里只是举个例子,像2也可以
	return 0;
}

while

#include<stdio.h>
int main()
{
 while(1)//判断部分为非0,一直为真————这里只是举个例子,像2也可以
 {
 
 }
	return 0;
}

for

#include<stdio.h>
int main()
{
int i = 0;
for( ; ; )
//这里可证明for循环内的三个部分都可省略,这没有判断进行的语句因此可一直进行。
{
}
for( i=1 ; ; )//这里将1赋给i一直为真,一直进行循环
{
}
for( ; 1; )//这里1为真,一直进行循环
{
}
	return 0;
}

说明:只要判断部分一直为真就是死循环。

五 .返回与其余关键字

const :声明只读变量
sizeof :计算数据类型长度(以字节为单位)
volatile :说明变量在程序执行中可被隐含地改变
return :函数返回语句(可以带参数,也看不带参数)

1.const

代码1:

const int i = 0;//这称之为常变量,这本质上是变量,就像披着羊皮的狼
//常变量是不能直接被修改的!
int *p =(int*)&i;
*p = 1;
//可以通过地址来进行间接修改

代码2:

int main()
{
	//这是真正意义上的不可修改的变量
	const char* p = "hello world\n";//加const与否都不能修改*p
	return 0;
}

代码3:

const 修饰多级指针,具有就近原则。

int main()
{
	char* ptr = NULL;
	char*const* p = &ptr;
	//说明:*p不能修改
	const char** p1 = &ptr;
	//说明:**p1不能进行修改
	return 0;
}

说明:const修饰的变量并不是常量!

2.sizeof

说明:
1.sizeof是关键字也是操作符,但不是函数。
2.sizeof的值为unsigned int

#include<stdio.h>
int main()
{
	printf("%d\n", sizeof(char)); //1(单位字节)

	printf("%d\n", sizeof(short)); //2

	printf("%d\n", sizeof(int)); //4

	printf("%d\n", sizeof(long)); //32位时4,64位可能是8(取决于编译器)

	printf("%d\n", sizeof(long long)); //8

	printf("%d\n", sizeof(float)); //4

	printf("%d\n", sizeof(double)); //8

	printf("%d\n", sizeof(void));//vs下是0,Linux下是1
	return 0;
}

3.return

1.既然函数在返回时会销毁,那返回值是如何进行保存的?
答:是通过寄存器eax进行保存的,然后返回的。
2.return能返回空值吗?
答:函数的返回类型为void能返回空值。
具体可见:函数栈帧

4.volatile

说明:
1. 表明变量可能被修改
2.告诉编译器不要直接进行优化,也就是把变量直接加载到寄存器中,就直接在CPU进行判断,而不考虑变量在内存中是否被改变,就好像是背水一战的感觉。
举例:

int main()
{
	int flag = 0;
	while (flag);
	return 0;
}

说明:
我们在判断条件时,通常是把内存的值放在寄存器中,然后再进行判断,然后重复此循环,但是为了进行优化编译器会直接判断是否需要直接放在寄存器中,死循环会,然后直接放在寄存器中进行判断,之后的每一次循环都会直接从寄存器中进行拿数据,而不再从编译器中再拿数据了。

五 总结

C语言一共多少个关键字呢?一般的书上,都是32个,但是这个都是C90(C89)的标准。其实C99后又新增了5个关键字。不过,目前主流的编译器,对C99支持的并不好,我们后面默认情况,使用C90,即,认为32个。

数据类型关键字
char :声明字符型变量或函数
short :声明短整型变量或函数
int : 声明整型变量或函数
long :声明长整型变量或函数
signed :声明有符号类型变量或函数
unsigned :声明无符号类型变量或函数
float :声明浮点型变量或函数
double :声明双精度变量或函数
struct :声明结构体变量或函数
union :声明共用体(联合)数据类型
enum :声明枚举类型
void :声明函数无返回值或无参数,声明无类型指针

控制语句关键字(12个)
1 循环控制(5个)
for :一种循环语句
do :循环语句的循环体
while :循环语句的循环条件
break :跳出当前循环
continue :结束当前循环,开始下一轮循环

  1. 条件语句(3个)
    if : 条件语句
    else :条件语句否定分支
    goto :无条件跳转语句
  1. 开关语句 (3个)
    switch :用于开关语句
    case :开关语句分支
    default :开关语句中的“其他”分支
  1. 返回语句(1个)
    return :函数返回语句(可以带参数,也看不带参数)
    存储类型关键字(5个)
    auto :声明自动变量,一般不使用
    extern :声明变量是在其他文件中声明
    register :声明寄存器变量
    static :声明静态变量
    typedef :用以给数据类型取别名(但是该关键字被分到存储关键字分类中,虽然看起来没什么相关性)

其他关键字(3个)
const :声明只读变量
sizeof :计算数据类型长度
volatile :说明变量在程序执行中可被隐含地改变

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/403985.html

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

相关文章

「计算机组成原理」数据的表示和运算(二)

文章目录五、奇偶校验码六、算术逻辑单元ALU6.1 电路的基本原理6.2 加法器的设计6.2.1 一位全加器6.2.2 串行加法器6.2.3 串行进位的并行加法器6.2.4 并行进位的并行加法器七、补码加减运算器八、标志位的生成九、定点数的移位运算9.1 算数移位9.2 逻辑移位9.3 循环移位五、奇偶…

Matlab生成sinc信号

Matlab生成sinc信号 在Matlab中生成sinc信号非常容易。首先&#xff0c;我们需要了解什么是sinc波形。 sinc波形是一种理想的信号&#xff0c;它在时域上是一个宽度为无穷的矩形函数&#xff0c;而在频域上则是一个平的频谱。它的公式为&#xff1a; sinc⁡(x)sin⁡(πx)πx\…

YOLOv5源码逐行超详细注释与解读(3)——训练部分train.py

前言 本篇文章主要是对YOLOv5项目的训练部分train.py。通常这个文件主要是用来读取用户自己的数据集&#xff0c;加载模型并训练。 文章代码逐行手打注释&#xff0c;每个模块都有对应讲解&#xff0c;一文帮你梳理整个代码逻辑&#xff01; 友情提示&#xff1a;全文近5万字…

学习电气自动化PLC编程最基础的十大知识点详解

这篇文章其实是学习PLC自动化过程中必须要理解的基础问题&#xff0c;不管是西门子PLC还是三菱PLC&#xff0c;抑或欧姆龙PLC&#xff0c;以及国产品牌的PLC&#xff0c;这些问题都必须理解透&#xff0c;才能更好的开始自动化编程。不然指令学完了梯形图的逻辑可能还是搞不懂&…

Datatables展示数据(表格合并、日期计算、异步加载数据、分页显示、筛选过滤)

系列文章目录 datatable 自定义筛选按钮的解决方案Echarts实战案例代码(21)&#xff1a;front-endPage的CJJTable前端分页插件ajax分页异步加载数据的解决方案 文章目录系列文章目录前言一、html容器构建1.操作按钮2.表格构建二、时间日期计算三、dataTables属性配置1.调用2.过…

java多线程与线程池-03线程池与阻塞队列

第6章 线程池与阻塞队列 6.1 Queue接口 队列是一种特殊的集合,一般队列都具有先进先出(FIFO)的特性(并不绝对要求)。优先级队列(PriorityQueue)按照元素的比较方法排序,其他队列基本采用自然序排队。 队列Queue接口实现了Collection接口,offer()方法负责把元素插入…

带头双向循环链表及链表总结

1、链表种类大全 1、链表严格来说可能用2*2*28种结构&#xff0c;从是否带头&#xff0c;是否循环&#xff0c;是否双向三个角度区分。 2、无头单向循环链表一般不会在实际运用中直接存储数据&#xff0c;而会作为某些更复杂结构的一个子结构&#xff0c;毕竟它只在头插、头删…

【数据结构之二叉树】——二叉树的概念及结构,特殊的二叉树和二叉树性质

文章目录一、二叉树的概念及结构1.概念2.现实中的二叉树3. 特殊的二叉树&#xff1a;3.二叉树的性质二、二叉树练习题总结一、二叉树的概念及结构 1.概念 一棵二叉树是结点的一个有限集合&#xff0c;该集合: 或者为空由一个根节点加上两棵别称为左子树和右子树的二叉树组成…

线性表的链式表示

文章目录1.单链表1.1单链表的表示1.1.1构建 带头结点的单链表1.2基本操作1.2.1 头插法1.2.2 尾插法1.2.3 按序号查找结点1.2.4 按值查找表结点1.2.5 插入结点操作扩展&#xff1a;前插操作1.2.6 删除结点操作扩展&#xff1a;删除结点*p1.2.7 求表长操作2.双链表2.1 双链表的表…

JVM相关知识

JVM类加载过程类什么时候被加载什么情况下会发生栈内存溢出JVM内存模型常量池回收方法区垃圾回收流程圾收集算法分代收集理论标记-清除算法标记-复制算法标记-整理算法类加载过程 加载–验证–准备–解析–初始化–使用–卸载 ​ 加载&#xff1a;通过全类名获取类的二进制流…

【C++】非类型的模板参数,特化

目录 1.类型模板参数和非类型模板参数 2.特化 3. 模板的分离编译 4.模板的优缺点 1.类型模板参数和非类型模板参数 之前写模板传的都是类型——类型模板参数 现在想定义两个静态数组&#xff0c;数组长度不同&#xff0c;就可以用模板参数传数值而不是传类型 非类型模板…

Docker与微服务实战2022

基础篇(零基小白)1.Docker简介1.1 是什么问题&#xff1a;为什么会有docker出现&#xff1f;您要如何确保应用能够在这些环境中运行和通过质量检测&#xff1f;并且在部署过程中不出现令人头疼的版本、配置问题&#xff0c;也无需重新编写代码和进行故障修复&#xff1f; 答案就…

Android源码分析 - View的触摸事件分发

0. 相关分享 Android源码分析 - InputManagerService与触摸事件 1. 接收Input系统发送来的事件 时序图源&#xff1a;稀土掘金 在注册Window的时候&#xff0c;来到ViewRootImpl&#xff0c;其中不仅发起窗口注册&#xff0c;还开启了输入事件的监听&#xff1a; //ViewRoo…

nuxt3使用总结

目录 背景 安装 项目配置 路由 Tailwindcss引入 全局样式配置 css预处理器 安装 Tailwindcss 项目的配置 部署上线 seo优化 背景 新入职了一家公司&#xff0c;刚进入公司第一个需求就是先做一个公司的官网&#xff0c;需要使用vue写&#xff0c;作为祖师爷的粉丝…

Java 电话号码的组合

电话号码的字母组合中等给定一个仅包含数字 2-9 的字符串&#xff0c;返回所有它能表示的字母组合。答案可以按 任意顺序 返回。给出数字到字母的映射如下&#xff08;与电话按键相同&#xff09;。注意 1 不对应任何字母。示例 1&#xff1a;输入&#xff1a;digits "23…

案例学习--016 消息队列作用和意义

简介MQ全称为Message Queue, 是一种分布式应用程序的的通信方法&#xff0c;它是消费-生产者模型的一个典型的代表&#xff0c;producer往消息队列中不断写入消息&#xff0c;而另一端consumer则可以读取或者订阅队列中的消息。主要产品有&#xff1a;ActiveMQ、RocketMQ、Rabb…

【RV1126】RKMedia模块简介

文章目录简介源码与编译rkmedia log等级配置目录参考文档&#xff1a;【Rockchip RKMedia Development Guide】rkmedia的手册在sdk目录下/docs/RV1126_RV1109/Multimedia rkmedia的代码在sdk目录下/external/rkmedia rkmedia的demo在sdk目录下/external/rkmedia/examples&…

antlr4-maven-plugin简单学习

1. 序言 antlr4-maven-plugin的官方介绍为&#xff1a; The ANTLR 4 plugin for Maven can generate parsers for any number of grammars in your project.博客《 mac上的Antlr4环境搭建》&#xff0c;有介绍如何通过antlr4-maven-plugin实现.g4文件的编译 这里将介绍antlr4-…

弹性存储-对象存储OSS部分

对象存储介绍 对象存储&#xff08;object storage service&#xff0c;简称oss&#xff09;&#xff0c;具备与平台无关的rest api接口&#xff0c;可提供99.9999999999%&#xff08;12个9&#xff09;的数据持久性和99.995%的数据可用性。 OSS优势 功能介绍 存储空间bucke…

秒杀高并发解决方案

秒杀高并发解决方案 1.秒杀/高并发方案-介绍 秒杀/高并发 其实主要解决两个问题&#xff0c;一个是并发读&#xff0c;一个是并发写并发读的核心优化理念是尽量减少用户到 DB 来"读"数据&#xff0c;或者让他们读更少的数据, 并 发写的处理原则也一样针对秒杀系统需…