【C语言冷知识】02_从上帝视角看变量

文章目录

  • 01 - 变量的语法和语义
  • 02 - 变量的语法
  • 03 - 变量的语义
  • 04 - 变量的语法和语义实践


01 - 变量的语法和语义

  在上文中提及研究编程语言的语法和语义能让自己更加清晰看透本质,知其然并知其所以然,接下来我们讨论一个C语言完整的编程中必然出现的角色——变量,如果问很多人一个问题,C语言里面变量是什么?回答可能有以下:
  1、变量就是带名字的内存,其值可变
  2、变量就是变量,程序里面需要定义然后使用的可变的东西
  3、变量是拿来储存具体数值的
  ……

【C语言冷知识】02_从上帝视角看变量_第1张图片

  上面的说法其实都没错,但是只停留在表明的理解,如果告诉你下面的这个语句也是在操作变量,是否会打破你的认知?

#define BootCrcValue()    (*(uint32_t *)(0x00000002)) &= 0xFF0000FF

  为了摸清变量这个模糊的东西,我们需要提问:一个变量的语法和语义分别代表什么? 或许未曾如此思考过,毕竟教科书很少会折腾变量的解释,更多是使用方法比如需要先定义后使用等,但对此其实是笼统模糊的,缺少一个清晰的认识,小白说出自己的看法:
  变量的语法——外部结构,“定义”过的一段内存区域,此内存区域一般有一个名字,当然也可以没有名字。
  变量的语义——内部结构,代表一段可变和有意义的数值。
【C语言冷知识】02_从上帝视角看变量_第2张图片

02 - 变量的语法

  变量的语法为“定义”过的一段内存区域,这个“定义”是宏观上的,可以理解是人为约束,变量的正常定义如下:

int a;
char b;
double c;
……

  这其实是让编译器决定占用内存的哪一段,既然是占用,当然也可以由程序员自己决定,常见的是内存规划中的约定,比如嵌入式中常带BootLoader,这个BootLoader固定占用内存的一段空间,并且一般会在固定地址存放固定的值,这个固定占用的BootLoader里的各个内存端其实也属于变量,因为它是定义过的,是BootLoader所使用的,假设协助规定BootLoader的前几个字节存放本身的CRC校验码和长度,比如0x00000002的地址存放着CRC校验码,想要对它进行操作,那么上一个语句可以这样表达:

#define BootCrcValue    (*(uint32_t *)(0x00000002))
BootCrcValue = (BootCrcValue & 0xFF0000FF)

  这个和上一个语句是等效的。可以看到,变量可以没有名字,只需要知道地址即可,同时所谓的名字是编译器和程序员的交流语言,实际上编译器不认识变量的名字,想要知道详细内容可以去看看汇编和机器码。
【C语言冷知识】02_从上帝视角看变量_第3张图片

03 - 变量的语义

  变量的语义为代表一段可变和有意义的数值,数值我们都知道,然后这里提及2个内容:可变和有意义,可变代表内存的性质是可以重复修改的,同时约定了此内存可被软件修改(也可以约定不可以被显式修改比如const),有意义代表其解析方式是符合语言本身规则的,因为就机器码而言,内存里的数值全是0和1的组合,随便拿一段内存来看,这究竟代表着什么,如何解析才是有意义的,其实这里讲的就是类型。

  类型代表着这一段内存的解析方式,比如2个字节二进制值为10000000 0000001,如果是short类型,那么它代表十进制的-1,如果是unsigned short,那么它代表十进制的32769,还可以把它强制看为int,那么它又是-1。所以一个内存里面一串01字符究竟代表着什么,就是变量类型所决定的,你可以用不同的类型去解析它,就可能得到不同的结果。
【C语言冷知识】02_从上帝视角看变量_第4张图片

04 - 变量的语法和语义实践

  理清了变量的语法和语义后,遇到一些和变量或者内存操作相关代码时,就能看清为什么会这样,比如:
  1、很多教材有提到类型的强制转换并不改变变量本身,但是没有解释为什么,我们用变量的语义去解释,变量的类型只是单纯的能让01组合变得有意义的解析方式,当对一个变量进行强制类型转换时,内存中的0和1组合并没有改变,只是对这个组合的解析改变了,就像一个圆,你可以说它是苹果,也可以说它是大饼,这里的苹果和大饼就是类型,但是如果脱离了类型,它就变得无意义。
  2、下面的代码是否能看清用途?

void Func(int a, char b, double c)
{
    (void)a;
    (void)b;
    (void)c;

    ……
}

【C语言冷知识】02_从上帝视角看变量_第5张图片

你可能感兴趣的:(C语言冷知识,C语言)