<关键字(1)>——《C语言深度剖析》

news2024/11/17 22:30:18

目录

关键字 - 第一讲

1.关键字分类

2.定义与声明 

2.1 什么是变量(是什么)

2.2如何定义变量(怎么用)

2.3为什么要定义变量(为什么)

2.4 变量定义的本质

2.5 变量声明的本质

3. 最宽宏大量的关键字 - auto

3.1 变量的分类 

3.2 变量的作用域

3.3 变量的生命周期 

3.4 作用域 vs 生命周期

3.5 auto 相关

4. 最快的关键字 - register

4.1 寄存器的认识

4.2 寄存器存在的本质

4.3 register 修饰变量

关键字 - 第二讲

1. 最名不符实的关键字 - static

1.1 认识多文件 

1.2  全局变量和函数的两个结论 

1.3  修饰变量 

1.4 修饰函数

2. 基本数据类型

2.1 数据类型与“模子”

2.2  变量命名规则

3. 最冤枉的关键字sizeof 理解

3.1 经常被误认为函数

3.2  sizeof(int)*p 含义

后记:●由于作者水平有限,文章难免存在谬误之处,敬请读者斧正,俚语成篇,恳望指教!                                                               ——By 作者:新晓·故知 


关键字 - 第一讲

本节重点
  • 初步了解关键字分类
  • 深刻理解变量
  • 深刻理解定义与声明
  • auto关键字的理解
  • 站在存储结构角度,理解register

1.关键字分类

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

关键字

说明
auto声明自动变量
short声明短整型变量或函数
int
声明整型变量或函数
long
声明长整型变量或函数
float
声明浮点型变量或函数
double
声明双精度变量或函数
char
声明字符型变量或函数
struct
声明结构体变量或函数
union
声明共用数据类型
enum
声明枚举类型
typedef
用以给数据类型取别名
const
声明只读变量
unsigned
声明无符号类型变量或函数
signed
声明有符号类型变量或函数
extern
声明变量是在其他文件正声明
register声明寄存器变量
static声明静态变量
volatile
说明变量在程序执行中可被隐含地改变
void
声明函数无返回值或无参数,声明无类型指针
if
条件语句
else
条件语句否定分支(与 if 连用)
switch
用于开关语句
case
开关语句分支
for
一种循环语句
do
循环语句的循环体
while
循环语句的循环条件
goto
无条件跳转语句
continue
结束当前循环,开始下一轮循环
break
跳出当前循环
default
开关语句中的“其他”分支
sizeof
计算数据类型长度
return
子程序返回语句(可以带参数,也可不带参数)循环条件

2.定义与声明 

2.1 什么是变量(是什么)

在内存中开辟特定大小的空间,用来保存数据
关键字:内存

2.2如何定义变量(怎么用)

int x = 10;
char c = 'a';
double d = 3.14;
类型 变量名 = 默认值

2.3为什么要定义变量(为什么)

//理解链
计算机是为了解决人计算能力不足的问题而诞生的。即,计算机是为了进行计算的。
而计算,就需要数据。
而要计算,任何一个时刻,不是所有的数据都要立马被计算。
如同:要吃饭,不是所有的饭菜都要立马被你吃掉。饭要一口一口吃,那么你还没有吃到的饭菜,就需要暂时放在盘子里。
这里的盘子,就如同变量,饭菜如同变量里面的数据。
换句话说,为何需要变量?因为有数据需要暂时被保存起来,等待后续处理。
那么,为什么吃饭要盘子?我想吃一口菜了,直接去锅里找不行吗?当然行,但是效率低。
因为我们吃饭的地方,和做饭的地方,是比较"远"的。

2.4 变量定义的本质

我们现在已知:
1. 程序运行,需要加载到内存中
2. 程序计算,需要使用变量
那么,定义变量的本质:在内存中开辟一块空间,用来保存数据。(为何一定是内存:因为定义变量,也是程序逻辑的一部分,程序已经被加载到内存)

2.5 变量声明的本质

结论:广而告之
注:
所有变量声明的时候不能初始值!(声明没有开辟内存空间!而定义是开辟了内存空间)

3. 最宽宏大量的关键字 - auto

3.1 变量的分类 

局部变量:包含在代码块中的变量叫做局部变量。局部变量具有临时性。进入代码块,自动形成局部变量,退出代码块自动释放。[网上很多说函数中的变量是局部变量,不能说错,但说法是不准确的]
全局变量:在所有函数外定义的变量,叫做全局变量。全局变量具有全局性。
代码块:用{}括起来的区域,就叫做代码块。
#include <stdio.h>
#include <windows.h>
int g_x = 100; //全局变量
int main()
{
	int x = 10; //局部变量,main函数也是函数,也有代码块{}
	printf("x:%d\n", x);
	system("pause");
	return 0;
}

 3.2 变量的作用域

作用域概念:指的是该变量的可以被正常访问的代码区域

局部变量:只在本代码块内有效
//例子同上
全局变量:整个程序运行期间,都有效

//demo 1
#include <stdio.h>
#include <windows.h>
int g_x = 100; //全局变量
void show()
{
	printf("show: 全局: %d\n", g_x); //在任何代码块中都可以被访问
}
int main()
{
	show();
	printf("main: 全局: %d\n", g_x); //在任何代码块中都可以被访问,甚至被修改
	system("pause");
	return 0;
}

 3.3 变量的生命周期 

生命周期概念:指的是该变量从定义到被释放的时间范围,所谓的释放,指的是曾经开辟的空间”被释放“
局部变量: 进入代码块,形成局部变量[开辟空间],退出代码块,"释放"局部变量
全局变量: 定义完成之后,程序运行的整个生命周期内,该变量一直都有效
//通过上面的例子,我们能感知一二,不过真正说清楚,需要等函数讲完,再谈一下。
//尽管,上面理解也没问题。

3.4 作用域 vs 生命周期

//深刻理解两者的区别

3.5 auto 相关

如何使用:一般在代码块中定义的变量,即局部变量,默认都是auto修饰的,不过一般省略
默认的所有变量都是auto吗?不是,一般用来修饰局部变量
中断一下:后面我们所到的,局部变量,自动变量,临时变量,都是一回事。我们统称局部变量
//demo
#include <stdio.h>
#include <windows.h>
int main()
{
	for (int i = 0; i < 10; i++) 
	{
		printf("i=%d\n", i);
		if (1)
		{
			auto int j = 0; //自动变量
			printf("before: j=%d\n", j);
			j += 1;
			printf("after : j=%d\n", j);
		}
	}
	system("pause");
	return 0;
}

思考:i用auto修饰可以吗?去掉j的auto可以吗?
结论:已经很老,基本永不使用。

4. 最快的关键字 - register

其实,CPU主要是负责进行计算的硬件单元,但是为了方便运算,一般第一步需要先把数据从内存读取到CPU内,那么也就需要CPU具有一定的数据临时存储能力。注意:CPU并不是当前要计算了,才把特定数据读到CPU里面,那样太慢了。
所以现代CPU内,都集成了一组叫做寄存器的硬件,用来做临时数据的保存。

距离CPU越近的存储硬件,速度越快。

4.1 寄存器的认识

当前,目前学习可以不用关心硬件细节,只要知道CPU内集成了一组存储硬件即可,这组硬件叫做寄存器。

4.2 寄存器存在的本质

在硬件层面上,提高计算机的运算效率。因为不需要从内存里读取数据。

4.3 register 修饰变量

尽量将所修饰变量,放入CPU寄存区中,从而达到提高效率的目的。
那么什么样的变量,可以采用register呢?
1. 局部的(全局会导致CPU寄存器被长时间占用)
2. 不会被写入的(写入就需要写回内存,后续还要读取检测的话,register的意义在哪呢?)
3. 高频被读取的(提高效率所在)
4. 如果要使用,请不要大量使用,因为寄存器数量有限
这里除了上面的,再有一点,就是register修饰的变量,不能取地址(因为已经放在寄存区中了嘛,地址是内存相关的概念)
//demo
#include <stdio.h>
#include <windows.h>
int main()
{
	register int a = 0;
	printf("&a = %p\n", &a);
	//编译器报错:错误 1 error C2103: 寄存器变量上的“&”
	//注意,这里不是所有的编译器都报错,目前我们的vs2019是报错的。
	system("pause");
	return 0;
}

建议:该关键字,不用管,因为现在的编译器,已经很智能了,能够进行比人更好的代码优化。
早期编译器需要人为指定register,来进行手动优化,现在不需要了。

关键字 - 第二讲

本节重点
  • 在多文件中,关于全局变量和函数的一些结论
  • static的作用
  • 如何看待类型
  • 变量的命令规则
  • sizeof 的理解

1. 最名不符实的关键字 - static

先建立2个源文件进行验证,然后提炼出头文件存在的必要性。

1.1 认识多文件 

//.h:我们称之为头文件,一般包含函数声明,变量声明,宏定义,头文件等内容(header)
//.c: 我们称之为源文件,一般包含函数实现,变量定义等 (.c:c语言)
//test.h
#pragma once //防止头文件被重复包含,当前只需要记住,后面会无数次用
#include <stdio.h>
#include <windows.h>
//test.c
#include "test.h" //""包含头文件,目前只需要知道是自己写的头文件,就用""包含即可
//main.c
#include "test.h" //同上
int main()
{
	printf("hello files!\n");
	system("pause");
	return 0;
}

注:

头文件基本上是要被多个源文件包含,那就会产生重复包含的问题!有多种方式解决,推荐使用的就是在头文件中声明“program once”即

 头文件中一般编写如下内容:

 

 在链接的时候寻找定义的函数或变量。

1.2  全局变量和函数的两个结论 

1. 全局变量,是可以跨文件,被访问的。
2. 全局函数,是可以跨文件,被访问的。

1.3  修饰变量 

1. 修饰全局变量,该全局变量只能在本文件内被使用。
//总结:static修饰全局变量,影响的是作用域的概念,函数类似。而生命周期是不变的。
//具体细节,现场写,当场看效果
//2. 修饰局部变量
void fun1()
{
	int i = 0;
	i++;
	printf("no static: i=%d\n", i);
}
void fun2()
{
	static int i = 0;
	i++;
	printf("has static: i=%d\n", i);
}
int main()
{
	for (int i = 0; i < 10; i++) 
	{
		fun1();
		fun2();
	}
	system("pause");
	return 0;
}
//结论:static修饰局部变量,变量的生命周期变成全局周期。(作用域不变)
//另外,这里需要初步讲一下:初始化与赋值的概念

 有些误导性

 关于C存储布局,我们后面讲到函数会整体来讲,这里不赘述。

1.4 修饰函数

//修饰函数,该函数只能在本文件内被使用。
//现场演示

2. 基本数据类型

经过前面的练习,相信对于定义变量并不陌生了。那么此处,我们讲一些其他内容来便于理解类型。
目前我们只讲内置类型,其他类型我们后面慢慢展开。

2.1 数据类型与“模子”

C常见内置类型
//先见一批,后面慢慢补充
char
short
int
long
long long
float
double
如何看待数据类型
前面已经说过,定义变量的本质:在内存中开辟一块空间,用来保存数据。
而定义一个变量,是需要类型的,这个是基本语法决定的。那么,类型决定了:变量开辟空间的大小。
//demo
#include <stdio.h>
#include <windows.h>
int main()
{
	//sizeof简单介绍,下个主题就讲
	printf("%d\n", sizeof(char));      //1
	printf("%d\n", sizeof(short));    //2
	printf("%d\n", sizeof(int));        //4
	printf("%d\n", sizeof(long));     //4
	printf("%d\n", sizeof(long long)); //8
	printf("%d\n", sizeof(float));     //4
	printf("%d\n", sizeof(double)); //8
	system("pause");
	return 0;
}

在继续讨论之前,先看着一个问题:为什么要根据类型,开辟一块空间,直接将内存整体使用不好吗?

不好。
任何时刻,都不是你一个程序在运行,还有很多其他程序也在运行。你整块用了,让别人怎么办?
另外,你全都用了,一定需要在任何时刻,全部都用完吗?对于暂时不用,但是给你了,对计算机来讲,就是浪费。
那么,问题又来了,我使用部分内存,使用多少由什么决定?其实是由你的场景决定,你的计算场景,决定了你使用什么类型的变量进行计算。你所使用的类型,决定了你开辟多少字节的空间大小。
所以,C语言中,为什么会有这么多的类型?就是为了满足不同的计算场景。
//比如,整形计算,字符计算,字符串计算,浮点数计算等。
然后,在回归到书中,关于"模子"的介绍。为了不让童鞋们感到不适,找了张图

2.2  变量命名规则

例:min-length && max-information
最短长度,最大信息
【规则 1-3】 推荐,这个叫做大驼峰命名,具体我看看情况进行对变量命名
【规则 1-5】 推荐,目前,全局变量可以在变量名前带g_,以表示全局含义
//目前要求:数字字母下划线,见名知意

3. 最冤枉的关键字sizeof 理解

3.1 经常被误认为函数

 

 

3.2  sizeof(int)*p 含义

 

//更多内容,到指针来深入学习。

后记:
●由于作者水平有限,文章难免存在谬误之处,敬请读者斧正,俚语成篇,恳望指教!

                                                               ——By 作者:新晓·故知 

 

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

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

相关文章

汇编语言(第四版)第八章 实验7 习题解答

Power idea 公司从1975年成立一直到1995年的基本情况如下&#xff1a; 下面的程序中&#xff0c;已经定义好了这些数据&#xff1a; assume cs:codesg,ds:datasgdatasg segmentdb 1975,1976,1977,1978,1979,1980,1981,1982,1983db 1984,1985,1986,1987,1988,1989,1990,1991,19…

【12】C语言_几个循环的经典练习

目录 1. 打印n的阶乘; 2、计算 1!2!3!......10! 3、用二分查找在一个有序数组中查找一个数 4、打印如下 5、输入三次密码 6、写一个猜数字游戏 7、如题 8、打印1到100之间 3的倍数 9、给两个数&#xff0c;求出最大公约数 10、找出从1000到2000之间的闰年 11、找出10…

Java是编译性语言还是解释型语言 ?

首先我们应该了解这两种语言的概念 . 高级语言在计算机上执行 , 有两种方式 , 分为编译型语言和解释型语言 . 编译型语言 : 编写源代码–>编译–>链接. 典型的编译型语言 : C/C . 特点 : 源代码中一处有错 , 就不允许编译 ; 编译过程中出现一处错误 , 就停止编译 . 优…

论文投稿指南——中文核心期刊推荐(武器工业)

【前言】 &#x1f680; 想发论文怎么办&#xff1f;手把手教你论文如何投稿&#xff01;那么&#xff0c;首先要搞懂投稿目标——论文期刊 &#x1f384; 在期刊论文的分布中&#xff0c;存在一种普遍现象&#xff1a;即对于某一特定的学科或专业来说&#xff0c;少数期刊所含…

4个免费数据恢复软件:免费恢复您的数据

意外的文件删除或文件损坏可能会令人头疼&#xff0c;尤其是在您不使用云存储的情况下。两者通常都支持已删除的文件恢复和版本控制&#xff0c;以帮助您摆脱此类困境。如果您不使用云&#xff0c;通常唯一的机会就是使用数据恢复软件来找回丢失或损坏的数据。 这种方法有两个…

使用 Burpsuite 测试的常用操作(二)

大家好啊&#xff0c;我是大田。接上篇文章「 使用 Burpsuite 测试的常用操作&#xff08;一&#xff09;」&#xff0c;今天继续分享一下 Burpsuite 在工作中常用操作三、本文中 2 个常用操作1、Burpsuite_proxy 篡改请求通过代理模式可以拦截、查看、修改所有客户端和服务器端…

(二)Linux嵌入式开发——软件安装(Ubuntu)

文章目录&#xff08;二)Linux嵌入式开发——软件安装&#xff08;Ubuntu&#xff09;APP StoreAPT工具问题解决办法1解决办法2deb软件包程序源码问题1解决办法问题2解决办法总结&#xff08;二)Linux嵌入式开发——软件安装&#xff08;Ubuntu&#xff09; 接下来&#xff0c;…

【GD32F427开发板试用】FOC矢量算法研究系列之一:PWM实现呼吸灯

本篇文章来自极术社区与兆易创新组织的GD32F427开发板评测活动&#xff0c;更多开发板试用活动请关注极术社区网站。作者&#xff1a;Q_dGHvwj 前言 有幸被选为此次开发板测评活动的参与者&#xff0c;万分感谢。收到板子后迫不及待的拆来查看&#xff0c;画风整齐美观&#x…

SpringCloudAlibabaNacosConfig学习笔记

目录 1. Nacos配置中心使用 2 搭建nacos-config服务 3 Config相关配置 4 .配置的优先级 5. RefreshScope 1. Nacos配置中心使用 官方文档&#xff1a; https://github.com/alibaba/springcloudalibaba/wiki/Nacosconfig Nacos 提供用于存储配置和其他元数据的key/value 存…

23种设计模式(十三)——代理模式【接口隔离】

文章目录 意图什么时候使用代理真实世界类比代理模式的实现代理模式的优缺点亦称:Proxy 意图 由于某些原因需要给某对象提供一个代理以控制对该对象的访问。这时,访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象之间的中介。 什么时候使用代理 1、…

论文投稿指南——中文核心期刊推荐(环境科学)

【前言】 &#x1f680; 想发论文怎么办&#xff1f;手把手教你论文如何投稿&#xff01;那么&#xff0c;首先要搞懂投稿目标——论文期刊 &#x1f384; 在期刊论文的分布中&#xff0c;存在一种普遍现象&#xff1a;即对于某一特定的学科或专业来说&#xff0c;少数期刊所含…

操作系统-操作系统引论(1)

操作系统的基本概念一、操作系统的定义二、操作系统的产生与发展三、操作系统的特征四、操作系统的功能五、操作系统的运行机制六、操作系统的体系结构一、操作系统的定义 资源管理的观点&#xff1a;操作系统是控制和管理计算机的软、硬件资源&#xff0c;并且合理的组织计算…

通过C++对【图】进行抽丝剥茧(包括广度、深度优先遍历,求最小生成树,求最短路径)

目录 一.图的基本概念 二.图的存储结构 1.邻接矩阵 &#xff08;1&#xff09;无向图、有向图矩阵存储 &#xff08;2&#xff09;实现&#xff1a; 2.邻接表 &#xff08;1&#xff09;无向图邻接表存储 &#xff08;2&#xff09;有向图邻接表存储 &#xff08;3&a…

windows下运行ROSEFusion

其实LZ已经不再是两年前的Linux小白了&#xff0c;至于为什么要在windows下配置环境&#xff0c;是因为LZ在Linux下已经成功编译成功了ROSEFusion&#xff0c;但运行时一直报错Frame could not be processed&#xff0c;在github下的issue里面查询得知可能是CUDA版本问题。另外…

VM16 Pro+ubuntu20.04.5+GAMIT10.71安装(20230118更新包)

VMware Workstation 16 Proubuntu20.04GAMIT10.71安装测绘老中医&#xff08;qq8212714&#xff09;&#xff08;2023-01-20&#xff09;NOTE:安装环境&#xff1a;Windows 10 专业版&#xff0c;64 位操作系统, 基于 x64 的处理器1、首先在计算机中安装VMware Workstation 16 …

交叉编译(全志)

文章目录一、交叉编译概念二 、香橙派交叉编译3.带WiringPi库的交叉编译一、交叉编译概念 交叉编译&#xff0c;就是&#xff1a;在一种平台上编译&#xff0c;编译出来的程序&#xff0c;是放到别的平台上运行即编译的环境&#xff0c;和运行的环境不一样&#xff0c;属于交叉…

【基础】高低位和大小端

大小端模式出现是为了兼容不同CPU采用的不同的指令集 PowerPC架构和x86架构采用的是不同的CPU指令集。PowerPC采用精简指令集&#xff08;RISC&#xff0c;reduced instruction set computer&#xff09;&#xff0c;x86指的是特定微处理器执行的一些计算机语言指令集。 Powe…

Obsidian 插件(一):DataView 的使用

文章目录DataView 的使用一、 环境配置二、 入门介绍1、 快速开始2、 页面和字段3、 创建查询4、 系统字段三、 接口讲解1、 表达式1.1 概述1.2 表达式类型1.3 特定类型的交互2、 函数2.1 构造器2.2 常用函数2.3 工具函数DataView 的使用 一、 环境配置 首先&#xff0c;我们…

ESP32设备驱动-DHT11温度湿度传感器驱动

DHT11温度湿度传感器驱动 1、DHT11介绍 DHT11数字温湿度传感器是一种复合传感器,包含一个经过校准的温湿度数字信号输出。 应用了专用的数字模块采集技术和温湿度传感技术,确保产品具有高可靠性和优异的长期稳定性。 该传感器包括一个电阻感湿元件和一个 NTC 温度测量装置,…

LeetCode题目笔记——1814. 统计一个数组中好对子的数目

文章目录题目描述题目难度——中等方法一&#xff1a;模拟&#xff08;超时&#xff09;&#xff08;参考&#xff09;代码/Python方法二&#xff1a;优化代码总结题目描述 给你一个数组 nums &#xff0c;数组中只包含非负整数。定义 rev(x) 的值为将整数 x 各个数字位反转得…