C-关键字(下)
文章目录
- 循环控制
- switch-case-break-default
- do-while-for
- getchar()
- break-continue
- goto
- void
- void*
- return
- const
- const修饰变量
- const修饰数组
- const修饰指针
- 指针补充
- const 修饰返回值
- volatile
- struct
- 柔型数组
- union联合体
- 联合体空间开辟问题
- 利用联合体的性质,判断机器是大端还是小端
- enum枚举
- typedef
- typedef vs #define
- `typedef static int int32_t` 行不行
循环控制
switch-case-break-default
int main()
{int day = 0;scanf("%d",&day);switch (day)//整形(int char short)||整形表达式{case 1: //case是用来进行判定的printf("星期一\n");break; //充当分支的作用,否则会将后面的都打印default:printf("不是星期一\n");break;}return 0;
}
- 当一个case分支时要执行多条语句或者定义变量时最好加上代码块{}或者将众多代码封装为一个函数就行.
- 当多条分支执行一条语句时,将break删除组合落为一个就行.
int main()
{int day = 0;scanf("%d",&day);switch (day)//整形(int char short)||整形表达式{case 1: case 2:case 3://case是用来进行判定的printf("要上课\n");break; //充当分支的作用,否则会将后面的都打印default:printf("输入内容有误\n");break;}return 0;
}
default分支可以放在任何位置,只是为了好看并且符合语义放在最后.
break不要写成return,可以写但是不方便别人维护的时候好看,可以在循环的时候设置一个bool类型的标记位.
switch-case中绝对不能用const修饰组成的只读常量,必须是真正的常量.
int main()
{const int day = 0;scanf("%d",&day);switch (day)//整形(int char short)||整形表达式{case day:break;//编译报错case 1: case 2:case 3://case是用来进行判定的printf("要上课\n");break; //充当分支的作用,否则会将后面的都打印default:printf("输入内容有误\n");break;}return 0;
}
do-while-for
循环条件初始化,循环判定,循环条件更新.
任何C程序,在默认编译好之后,运行时都会默认打开三个输入输出流.
perror("hello world\n");
getchar()
- 键盘中输入时,多读了一个\n
- 为什么返回值是int类型,不是char类型
字符char类型是8字节,[0,255],ASCII码表中都是合理的值,如果也设置是返回值是char.返回成功时是一个有效字符,如果获取失败,8个bit位只能表示所有的合法字符,但是无法表示返回失败的概念.说白了,char类型的返回值无法表示失败,太小了.
- 键盘中输入的所有的内容或者输出的字符,或者往显示器中打印的,都是字符!
printf的返回值就是表示一共打印了多少个字符.
int a=0; scanf("%d",&a);
说白了就是将键盘中的字符按照类型格式化输入到变量a中.所以会将键盘显示器啥的都叫字符设备.
break-continue
- break对比continue
- continue:在while()和do while()都是跳转到条件判断处,for()循环是跳转到条件更新处.
goto
直接跳转到标签指定处,可以向上或者向下跳转.
- goto 语句实现循环
int main()
{int i = 0;
start:printf("[%d] goto running ...\n", i);i++;if (i < 10){goto start;}printf("goto end...\n");return 0;
}
- goto语句只能在本函数块中使用,不能跨函数或者跨文件使用.
void
-
void不能定义变量.
-
void本身就被编译器定义为空类型,强制的不允许定义变量.
-
void大小是0不能开辟空间导致的,本身是空类型,理论上是不应该开空间的.即使开空间也仅仅是一个占位符.
-
注意:不同的编译器对于void大小的规定也是不一样的.
-
- C语言函数可以不带返回值.默认的返回值就是int.避免别人误解,所以使用void告诉别人,我不想返回.只是起到一个占位符的作用,这个返回值无法接收.
- 告知编译器,这个函数不需要传参.
void*
-
void* 可以定义变量只要是指针大小类型就是确定的.
-
void*
可以被任何类型的指针接收.void*
可以接收任意指针类型.- 库,系统接口的设计上,尽量设计为通用接口.例子中,既可以是int类型也可以是double类型.
-
vs中void* 指针变量不能+±-,无法确定向前移动几个字节.而在Linux中是可以编译通过的,因为Linux中有确定的sizof(void)1字节大小.因为不同的平台看待void空间大小是不确定的.
-
不能对void* 类型指针进行解引用.
return
- 字符串类型 vs 字符串
C语言没有字符串类型,存在字符串,以\0结尾,不是数据长度,但是占据一字节的容量大小,字符串本身是没有名字的.使用字符数组访问.
-
计算机中删除数据释放空间是否是将数据全部清空?
计算机中删除数据本质只需要设置该数据无效即可(文件系统部分理解).所以下载数据很慢但是删除很快.
调用函数,形成栈帧,函数返回,栈帧空间释放.函数栈帧中的数据并不会被释放,仅仅代表这个空间是可以被覆盖的.printf()也是函数,所以使用printf的时候会形成新的函数栈帧,覆盖之前show()函数栈帧的部分.
- 开辟栈帧时,如何确定开辟多大的空间呢?
在调用函数之前,编译器可以通过定义变量的数量和类型,是可以预估这个函数应该是多少的空间的.不同的编译器预估的方式也是不同的.
-
递归的情况会不断创建栈帧空间,会存在栈溢出的情况.
-
为什么临时变量具有临时性?
函数中的变量基本都是临时变量在一个函数栈帧中,函数返回栈帧空间被释放.所有的临时变量都是依托于函数栈帧开辟空间的.
int GetData()
{int x = 0x11223344;printf("get data success!\n");return x;
}
int main()
{int ret = GetData();printf("ret: %x\n",ret);return 0;
}
- GetData()函数中的变量x在函数返回时已经被销毁,是如何交给ret的呢?
函数的返回值,通过寄存器eax的方式返回给函数调用方.
- 有ret进行接收,就将eax中内容交给ret
- 没有ret接收,仍然放到eax中,但是函数并不会做任何处理.
- main函数的返回值是给谁的呢?为什么经常是0?(进程部分讲解)
const
const修饰变量
为变量添加只读属性,const修饰的变量是不可直接被修改(二次赋值).通过指针就可以间接修改.
- const修饰变量的意义?是在编译期间的处理
让编译器进行直接修改式检查.告诉其他人不可修改.(是一种软性要求,不是强制性约束)
- 真正意义上的不可被修改,操作系统层面的处理.
- 数组开辟的空间大小必须是真常量.const修饰的变量vs中是编不过的.在Linux中是可以编过的,不同的平台支持的c的版本是不同的.
- const只能在初始化的时候赋值,二次赋值时不允许的.
const修饰数组
数组中的元素都是不可被修改的.const int arr[] = {1,2,3,4,5};
const修饰指针
地址就是指针,提高CPU内存寻址的效率.
-
地址是数据吗?是
-
数据可以被保存吗?4字节空间存储,这个内存空间就叫做指针变量.
-
任何一个变量名在不同的应用场景中代表不同的含义.
int a=10; int* p=&a; p=&b;//p的空间,变量的属性,左值 q=p; //p中的内容,数据的属性,右值
指针补充
&
整形变量为例,对应他的指针变量中存储的是变量4字节中的最低的那个地址空间.
*
解引用
类型相同的时候,对指针解引用,指针所指向的目标.
int main()
{int a = 10;const int *p1 = &a;//p指向的变量不可以直接修改p1 = 200;*p1 = 100;//errorint const *p2 = &a;//p指向的变量不可以直接修改//const修饰的是指针变量p中地址内容不可直接被改变int* const p3 = &a;*p3 = 1200;int b = 20;p3 = &b;//error//const修饰的是指针变量p中地址内容不可直接被改变const int* const p4 = &a;*p4 = 200;//errorp4 = &b;//errorreturn 0;
}
- 函数传参需要产生临时变量吗?
C中,任何函数参数都一定要产生临时变量,包括指针变量.
const 修饰返回值
如果不想用函数返回值修改函数中变量的值时,可以选择使用const修饰返回值.
const int* GetVal()
{static int a = 10;return &a;
}
int main()
{const int* p = GetVal();//外部接收使用const修饰*p = 100;//error
}
volatile
- 内存被覆盖的情况
不让CPU进行优化,每次都去访问内存,而不是优化被放进寄存器中数据的值,一直访问寄存器中的数据.
#include <stdio.h>
int pass = 1;
//volatile int pass = 1;
int main()
{while(pass){}return 0;
}
- 不加volatile
- 加上volatile
const volatile int a = 10;
在vs2013和gcc 4.8中都能编译通过
const是在编译期间起效果
volatile在编译期间主要影响编译器,形成不优化的代码,进而影响运行,故:编译和运行都起效果。
const要求你不要进行写入就可以。volatile意思是你读取的时候,每次都要从内存读。
两者并不冲突。
虽然volatile就叫做易变关键字,但这里仅仅是描述它修饰的变量可能会变化,要编译器注意,并不是它要求对应变量必须变化!这点要特别注意
struct
#define NUM 64
struct stu
{char name[NUM / 2];int age;char sex;char addr[NUM];
}a,c,b;//struct类型就是类型,和int啥的定义变量是相同的
int main()
{struct stu x;strcpy(x.name,"张三");//x.name = "张三";//error 支持整体初始化,不支持整体赋值x.age = 18;struct stu* p = &x;printf("sut.name:%s\n",p->name);printf("sut.name:%s\n",(*p).name);//为什么结构体访问会存在两种形式?//结构体可能贯穿多个函数,这时候传指针就很节省空间并且效率高//在日常访问的时候使用.更方便
}
- vs中结构体必须有一个成员,不支持空结构体.Linux中gcc可以定义,大小是0
柔型数组
-
必须放在结构体内.
-
首元素最好不是柔性数组,建议使用时前面最好还有一个有效的成员.
-
柔性数组是不占用结构体空间的.所以想要动态开辟结构体大小的空间时,需要根据设定大小和类型自定义开辟.
struct data
{ int num;int arr[];
};
int main()
{struct data d;struct data* p = malloc(sizeof(struct data)+sizeof(int)*10);p->num = 10;for (int i = 0; i < p->num; i++){p->arr[i] = i;}free(p);
}
union联合体
union un
{int a;char b;
};
int main()
{union un u;u.a = 10;union un* p_un = &u;p_un->a = 20;printf("%d\n",sizeof(union un));//4return 0;
}
联合体空间开辟问题
- 联合体的地址和联合体中最大元素的地址是相同的
- 联合体中最小元素b的地址也是联合体起始地址,也就是最低地址.
所以,联合体中的所有变量的起始地址在数字上都是相同的,取最大变量的大小开辟空间,所有变量以放射状的方式从低地址向高地址开辟空间.
- 开辟的空间是属于大家的,每个变量都认为自己独占所有空间,每一个元素都是第一个元素.
利用联合体的性质,判断机器是大端还是小端
int main()
{union un u;u.a = 1;if (u.b == 1){printf("小端机器");}else{printf("大端机器");}
}
enum枚举
存储常量.制作整合一些具有强相关性的常量.使用英文单词相对于数字,具有自描述性.
enum en
{RED,BLACK,BLUE,GREEN
};
int main()
{int a = BLUE;//如果直接用数字初始化a,需要添加注释别人才能看懂printf("%d\n",a);//2enum en c = BLUE;printf("%d\n",RED);//0printf("%d\n",BLACK);//1
}
typedef
类型重命名
typedef unsigned int u_int;
struct data
{ int num;int arr[];
} a;//a 叫全局定义的一个变量
typedef struct Student
{int num;char name[10];char sex;
}Stu;//Stu 就是结构体类型typedef int a[10];//a是一个数组类型
int main()
{u_int t = -10;Stu s;a b;return 0;
}
typedef vs #define
- 类型重命名并不是简单的某种类型替换,应该理解为一个全新的类型,而不是替换之后*先和那个变量结合.
- typedef 之后不能再引入其他关键字来修饰类型
typedef static int int32_t
行不行
- 存储类型关键字(5个)
auto
:声明自动变量,一般不使用
extern
:声明变量是在其他文件中声明
register
:声明寄存器变量
static
:声明静态变量
typedef
:用以给数据类型取别名(但是该关键字被分到存储关键字分类中,虽然看起来没什么相关性)
存储类型关键字不可以同时出现,在一个变量定义的时候只能有一个.报错:指定一个以上的存储类
-
其他关键字(3个)
const
:声明只读变量
sizeof
:计算数据类型长度
volatile
:说明变量在程序执行中可被隐含地改变 -
控制语句关键字(12个)
1. 循环控制(5个)
for :一种循环语句
do :循环语句的循环体
while :循环语句的循环条件
break :跳出当前循环
continue :结束当前循环,开始下一轮循环
2. 条件语句(3个)
if : 条件语句
else :条件语句否定分支
goto :无条件跳转语句
3. 开关语句 (3个)
switch :用于开关语句
case :开关语句分支
default :开关语句中的“其他”分支
4. 返回语句(1个)
return :函数返回语句(可以带参数,也看不带参数)
-
数据类型关键字(12个)
char :声明字符型变量或函数 short :声明短整型变量或函数 int : 声明整型变量或函数 long :声明长整型变量或函数 signed :声明有符号类型变量或函数 unsigned :声明无符号类型变量或函数 float :声明浮点型变量或函数 double :声明双精度变量或函数 struct :声明结构体变量或函数 union :声明共用体(联合)数据类型 enum :声明枚举类型 void :声明函数无返回值或无参数,声明无类型指针
相关文章:

C-关键字(下)
文章目录循环控制switch-case-break-defaultdo-while-forgetchar()break-continuegotovoidvoid*returnconstconst修饰变量const修饰数组const修饰指针指针补充const 修饰返回值volatilestruct柔型数组union联合体联合体空间开辟问题利用联合体的性质,判断机器是大端还是小端enu…...

关于电商商品数据API接口列表,你想知道的(详情页、Sku信息、商品描述、评论问答列表)
目录 一、商品数据API接口列表 二、商品详情数据API调用代码item_get 三、获取sku详细信息item_sku 四、获得淘宝商品评论item_review 五、数据说明文档 进入 一、商品数据API接口列表 二、商品详情数据API调用代码item_get <?php// 请求示例 url 默认请求参数已经URL…...

232:vue+openlayers选择左右两部分的地图,不重复,横向卷帘
第232个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+openlayers项目中自定义js实现横向卷帘。这个示例中从左右两个选择框中来选择不同的地图,做了不重复的处理,即同一个数组,两部分根据选择后的状态做disabled处理,避免重复选择。 直接复制下面的 vue+openlayers…...

溯源取证-内存取证 高难度篇
今天的场景依然是windows场景,只不过此次场景分为两个镜像,本次学习主要学习如何晒别钓鱼邮件、如何提取钓鱼邮件、如何修复损坏的恶意文件、如何提取DLL动态链接库文件 本次需要使用的工具: volatility_2.6_lin64_standalone readpst clams…...

JAVA语言中的代理模式
代理可以进一步划分为静态代理和动态代理,代理模式在实际的生活中场景很多,例如中介、律师、代购等行业,都是简单的代理逻辑,在这个模式下存在两个关键角色: 目标对象角色:即代理对象所代表的对象。 代理…...

最后一步:渲染和绘制
浏览器的工作步骤如下: URL>字符流>词(token)流>DOM树(不含样式信息的 DOM)>DOM树CSS规则(含样式信息的 DOM)>根据样式信息,计算了每个元素的位置和大小>根据这些…...

C++类和对象终章——友元函数 | 友元类 | 内部类 | 匿名对象 | 关于拷贝对象时一些编译器优化
文章目录💐专栏导读💐文章导读🌷友元🌺概念🌺友元函数🍁友元函数的重要性质🌺友元类🍁友元类的重要性质🌷内部类(不常用)🌺内部类的性…...

拼多多按关键字搜索商品 API
一、拼多多平台优势: 1、独创拼团模式 拼团拼单是拼多多独创的营销模式,其特点是基于人脉社交的裂变传播,非常具有传播性。 由于本身走低价路线,加上拼单折扣,商品的分享和人群裂变效果非常明显,电商前期…...

全链路日志追踪
背景 最近线上的日志全局追踪 traceId 不好使了,不同请求经常出现重复的 traceId,或者通过某个请求的 traceId 追踪搜索,检索出了与该请求完全不相干的日志。我领导叫我去排查解决这个问题,这里我把我排查的过程思路以及如何解决…...

ZYNQ:【1】深入理解PS端的TTC定时器(Part1:原理+官方案例讲解)
碎碎念:好久不见,甚是想念!本期带来的是有关ZYNQ7020的内容,我们知道ZYNQ作为一款具有硬核的SOC,PS端很强大,可以更加便捷地实现一些算法验证。本文具体讲解一下里面的TTC定时器,之后发布的Part…...

蓝牙设备如何自定义UUID
如何自定义UUID 所有 BLE 自定义服务和特性必须使用 128 位 UUID 来识别,并且要确保基本 UUID 与 BLE 定义的基本 UUID(00000000-0000-1000-8000-00805F9B34FB)不一样。基本 UUID 是一个 128 位的数值,根据该值可定义标准UUID&am…...

好看的html登录界面,
界面效果: 代码: <!DOCTYPE html> <html><head><title>Login Page</title><style>body {background-color: #f2f2f2;font-family: Arial, sans-serif;}form {background-color: #fff;border-radius: 5px;box-shado…...

Java模拟星空
目录 前言 JavaFX基础 1. GraphicsContext 2. AnimationTimer 代码实现 完整代码 前言 看了Python模拟星空很漂亮,Java也应该必须有一个! 环境:只需要JDK1.8就好!不需要外部包!!! Jav…...

YGG 代表 Web3 Gaming 参加 2023 年游戏开发者大会
Yield Guild Games(YGG)在 2023 年 3 月 20 日至 24 日在加州旧金山举行的游戏开发者大会(GDC)上大显身手,这是游戏开发者的重要交流学习活动。虽然 GDC 本身提供了多种多样的活动,包括讲座、小组讨论、圆桌…...

水库安全运行智慧管理平台解决方案筑牢防汛“安全墙”
解决方案 水库安全运行智慧管理系统解决方案,系统主要由降雨量监测站、水库水位监测站、大坝安全监测中的渗流量、渗流压力和变形监测站及视频和图像监测站等站点组成,同时建立规范、统一的监测平台,集数据传输、信息共享、数据储存于一体&a…...

Exchange升级部署方案
目录 前言 一、需求分析 二、升级前准备 1.备份当前 Exchange Server 数据...

AE开发之图层渲染20210603
AE开发之图层渲染比例符号化地图的整饰唯一值符号的符号化过程点符号设置,线符号设置标注图层,(写得不好,不推荐看) 唯一值符号化,字段进行设置,这里用到了UniqueValueRenderer接口,这里面有一…...

需要了解的过滤器
过滤器 1. 概念 过滤器: 从名字上理解就是对于事件的过滤操作,在web 中的过滤器,就是对于请求进行过滤操作,我们使用过滤器,就可以对于请求进行拦截操作,然后进行响应的处理操作,实现很多的特殊…...

VUE3的setup函数
文章目录 目录 文章目录 前言 一、setup函数是什么? 二、使用步骤 三、vue3中文文档和面向vue3的组件库 总结 前言 Vue3是一个面向数据驱动的渐进式JavaScript框架,其的设计理念包括简洁、灵活和高效。相比Vue2,Vue3的架构设计有很大的不同&…...

停车场管理系统文件录入(C++版)
❤️作者主页:微凉秋意 ✅作者简介:后端领域优质创作者🏆,CSDN内容合伙人🏆,阿里云专家博主🏆 文章目录一、案例需求描述1.1、汽车信息模块1.2、普通用户模块1.3、管理员用户模块二、案例分析三…...

线程(Thread)的三种等待唤醒机制详解
1、为什么需要线程的等待和唤醒 线程的等待唤醒机制是一种经典的“生产者和消费者”模型。例如食品加工厂,食品加工人员和原料补给人员,在有充足原料时,补给人员是在等待,等到原料不够时,食品加工人员通知补给人员&am…...

从零学习python - 13模块的导入与使用(实现单例模式)
模块基础知识 # 项目 > 包 > 模块 > 变量\方法\类 # 在python中,模块是代码组织的一种方式,把功能相近的函数或类放到一个文件中,一个文件(.py)就是一个模块,模块名就是文件名去掉py后缀. # 好处:提高代码可复用性和可维护性,一个模块编写完成后,很方便在其他项目中导…...

国产SSD、内存卷哭国外大厂,三星宣布减产涨价在路上了
PC 圈有一句话是这么说的:论价格屠夫还得看国产品牌! 可不是嘛,国产长鑫、长江算是彻底将全球存储芯片市场搅局者这一「骂名」坐实了! 不说特别早期,前几年吧,普通单条 8G DDR4 内存都能卖到六七百元&…...

数据库管理-第六十六期 SQL Domain(20230413)
数据库管理 2023-04-13第六十六期 SQL Domain1 基本介绍2 Domain的表达式和条件3 语法4 语义5 示例总结第六十六期 SQL Domain 上一期一笔带过了部分Oracle 23c的新特性,这一期重点讲一下SQL Domain新特性。 【https://docs.oracle.com/en/database/oracle/oracle-…...

《Vue3实战》 第一章 nods/npm安装、配置
1、nods.js安装(Windows) 1.1、下载并安装node https://nodejs.org/en/ , 安装到d盘nodejs目录 1.2、配置环境变量 path配置 1.3、配置全局包存放目录和缓存目录 在根目录下创建node_global(全局包存放目录)和node_cache&…...

JAVA练习104-四数相加 II
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 目录 前言 一、题目-四数相加 II 1.题目描述 2.思路与代码 2.1 思路 2.2 代码 总结 前言 提示:这里可以添加本文要记录的大概内容: 4月10日练…...

【C++基础】引用(引用的概念;引用的特性;常引用;使用场景:做输出型参数、大对象传参、做输出型返回值、返回大对象的引用);引用和指针的区别)
六、引用 6.1 引用的概念 引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间。(语法上) 格式:类型& 引用变量名(对象名) …...

Redis只用来做缓存?来认识一下它其他强大的能力吧。
当今互联网应用中,随着业务的发展,数据量越来越大,查询效率越来越高,对于时序数据的存储、查询和分析需求也越来越强烈,这时候 Redis 就成为了首选的方案之一。 Redis 提供了多种数据结构,如字符串、哈希表…...

【ES】数据同步集群
【ES】数据同步&集群3.数据同步3.1.思路分析3.1.1.同步调用3.1.2.异步通知3.1.3.监听binlog3.1.4.选择3.2.实现数据同步3.2.1.思路3.2.2.导入demo3.2.3.声明交换机、队列1)引入依赖2)声明队列交换机名称3)声明队列交换机3.2.4.发送MQ消息…...

37岁男子不愿熬夜,回乡养鸡每天准时下班,青山绿水中养鸡,直播间里卖鸡蛋...
37岁男子不愿熬夜,回乡养鸡每天准时下班,青山绿水中养鸡,直播间里卖鸡蛋。今天和大家分享一个创业案例,他叫胡铭浩,来自安徽省旌德县,今年37岁,曾做过车床操作工,开过婚纱摄影店&…...