学好C语言从关键字开始

简介: 学好C语言从关键字开始

1、C语言数据类型

e3.png


在学习C语言数据类型之前,我们得先了解:为什么要有类型?  类型为什么有这么多种类?


①为什么要有类型?


答:类型本质是对内存进行合理化划分,按需索取


② 类型为什么有这么多种类?


答:应用场景不同,解决应用场景对应的计算方式不同,需要空间的大小也不同。 (本质:用最小成本,解决各种多样化的场景问题)


了解这两个问题之后我们也就知道了  变量定义:是什么?为什么?怎么办?


变量定义是:在内存中开辟一块空间(注:按需索取)

为什么要定义变量:因为我们要解决各种多样化的场景问题

定义变量后怎么办:就可以使用了 (定义变量时要初始化)

定义变量格式:类型  变量名 = 初始化;


(定义变量时 :类型决定了变量需要开辟多大内存空间)


辅助理解: 数据类型跟制作月饼模具很类似

e2.jpeg




如果我们要制作一个小月饼,我们肯定会运用小模具去制作,不会去用大模具去应用,原因是因为小模具可以制作不会造成空间浪费,大模具会造成空间浪费。


数据类型也是如此 如果我们要存储一个字符我们会选择运用  char  类型去存储,不会想着用 int 类型,因为一个字符只占一个字节,刚好 char 类型也只开辟一个字节,而 int 类型开辟4个字节就会造成空间浪费


那我们接来下我们学习一下C语言中常见的内置内类的大小:

e1.png



为什么 long 跟 int 占用的空间一样大?


因为C++标准只规定 long >=  int

2.变量的命名规则

由字母、数字、下划线组成,但不能由数字开头。例如:max 、_max

见名知意。例如:max (一看就知道代表的最大值)、min(一看就知道代表的最小值)

命名应当简洁,不易过长。例如:MaxVal 就比 MaxValueUntilOverflow

当标识符为多个词组成时,每个单词的第一个字母大写,其余的小写(大驼峰命名)。例如:int CurrentVal

程序中不易出现只靠大小写区分的相似的标识符。例如:int  x = 0 、int X = 0 。注意:1(数字1)和 l (小写字母L), 0 (数字0) 和 o (小写字母O)的区分

函数名不易与变量名同名。

所以的宏定义、枚举常量、只读变量都用大写字母命名,下划线分割单词。例如:#define INT_MAX  100 、const  int  MAX_LENGTH = 100

尽量用 n 、i 、j 作为循环变量的使用

定义变量的同时记得初始化,定义变量时编译器不一定清空了这块内存,它的值可能是无效值

3.最冤枉的关键字——sizeof

为什么说它是最冤枉的关键字?


sizeof是关键字不是函数,但是还是会有人认为它是函数。因为我们大部分使用它的时候后面会跟括号 例如:sizeof(int),函数的使用方法也是这样。


那下面我们一起来为这个关键字洗清冤屈吧,证明它不是函数吧!


我们用编译器来证明它是关键字不是函数:

w4.png


从哪看出来它不是函数而是关键字的了?为什么第三个 printf ( ) 会报错了?


我们可以从第四个printf( )看出 sizeof 不是函数,因为函数名后要加括号,而 sizeof 后没有加括号也没有报错。函数调用是会压栈的,sizeof 不会压栈,也说明 sizeof 不是函数。

一个关键字不能直接去求另一个关键字的大小,所以第三 printf ( )  会报错。


w3.png

将第三个printf( )屏蔽后,程序也就可以正常运行了。


注:sizeof 在计算变量所占空间大小时,括号可以省略,而计算类型大小时不能省略。

4、signed和unsigned

signed:有符号

unsigned:无符号

原、反、补

一个变量的创建是要在内存中开辟空间的,空间的大小是根据不同的类型而决定的


那么整型数据在所开辟的内存中是如何存储的了?


①有符号数


int a = 10;

int b = -10;

有符号数可以分为正数和负数


计算机内存储的整型必须是补码,由此我们便引出了原、反、补码的概念


原码:将一个数直接转换成二进制

反码:符号位不变,其他位按位取反

补码:反码+1

正数的原码、反码、补码相同


负数的原码、反码、补码不相同,故负数的原码、反码、补码需要相互转换


任何数据在计算机中,都必须被转化成二进制,这是为什么呢?


答:因为计算机只认识二进制


计算机内存储的整型为什么必须是补码?


答:在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统一处理; 同 时,加法和减法也可以统一处理(CPU只有加法器)。此外,补码与原码相互转换,其运算过程是相同的,不 需要额外的硬件电路


原码、反码、补码三种表示方法均有符号位和数值位两部分


符号位为0:表示正数

符号位为1:表示负数

例1:signed int a = 10


先将字面值转为补码,然后把补码放入变量 a 中


原码:00000000 00000000 00000000 00001010


因为 10 为正数,故 原码、反码 相同


反码:00000000 00000000 00000000 00001010


补码:00000000 00000000 00000000 00001010


例2:signed int  a = -10


先将字面值转为补码,然后把补码放入变量 a 中


原码: 10000000 00000000 00000000 00001010


因为 -10 为负数,故 原码、反码 不相同


反码: 11111111  11111111  11111111  11110101


补码: 11111111  11111111  11111111  11110110


注:在vs中基本类型如果不带 signed 和 unsigned,默认都是有符号的,但是在其他编译器里面就不一定了(大部分不带都是表示有符号的)


补码转原码


方法一:补码 -1 = 反码   反码取反 = 原码


例如:

补码:11111111 11111111 11111111 11101100

反码:11111111 11111111 11111111 11101011

原码:10000000 00000000 00000000 00010100


方法二:补码符号位不变其他位按位取反,然后+1=原码

好处:可以使用一条硬件电路,完成转换


例如:

补码:11111111 11111111 11111111 11101100

           10000000 00000000 00000000 00010011

原码: 10000000 00000000 00000000 00010100


②无符号数


没有符号位,也就说明了 原码 = 反码 = 补码,那我们在取一个无符号整型变量时 也就可以直接取


例如:unsigned  int  a = -10


原码: 10000000 00000000 00000000 00001010


反码: 11111111  11111111  11111111  11110101


补码: 11111111  11111111  11111111  11110110


把 -10 的补码存入 无符号整型 a 中,在读取 a 变量里面的值时默认它是无符号的 直接将它里面存的数值转换为十进制打印。



w2.png


深入理解变量内容的存入和取出

存:字面数据必须先转成补码,在放入空间当中。所以,所谓符号位,完全看数据本身是否携带+-号。和变量是否有符号 无关!

取:取数据一定要先看变量本身类型,然后才决定要不要看最高符号位。如果不需要,直接二进制转成十进制。如果需 要,则需要转成原码,然后才能识别。(当然,最高符号位在哪里,又要明确大小端)

大小端

w1.png


我们可以通过上图发现在给变量赋值时顺序是十六进制12345678,但在内存中显示的十六进制的顺序却相反了,由此我们可以引入一个概念 大小端

q4.png



每个字节都有地址,所有的地址都是不同的,那么肯定是有大小的

地址可以有高地址和低地址之分(按照字节为单位)

int a = 0x12345678


数据也要按照字节为单位划分成若干块

数据按照字节为单位,也是有高权值和低权值之分的

q3.png


大小端就是把高权值放在高地址处还是低地址处的问题?


但是无论怎么放,只要用同等条件去取都可以


大端(存储)模式:是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址 中



q2.png


小端(存储)模式,是指数据的低位保存在内存的低地址中,而数据的高位,,保存在内存的高地 址中  



q1.png

相关文章
|
1月前
|
存储 数据可视化 编译器
【C语言】union 关键字详解
联合体(`union`)是一种强大的数据结构,在C语言中具有广泛的应用。通过共享内存位置,联合体可以在不同时间存储不同类型的数据,从而节省内存。在嵌入式系统、硬件编程和协议解析等领域,联合体的使用尤为常见。理解和正确使用联合体可以使代码更加高效和灵活,特别是在内存受限的系统中。
86 3
【C语言】union 关键字详解
|
1月前
|
编译器 C语言
【C语言】extern 关键字详解
`extern` 关键字在C语言中用于跨文件共享变量和函数的声明。它允许你在一个文件中声明变量或函数,而在其他文件中定义和使用它们。理解 `extern` 的使用可以帮助你组织和管理大型项目的代码。
113 3
|
1月前
|
C语言
【C语言】break 关键字详解
- `break` 关键字用于提前退出循环体或 `switch` 语句的执行。 - 在 `for`、`while` 和 `do-while` 循环中,`break` 可以帮助程序在满足特定条件时退出循环。 - 在 `switch` 语句中,`break` 用于终止 `case` 代码块的执行,避免代码“穿透”到下一个 `case`。 - 注意 `break` 只会退出最内层的循环或 `switch` 语句,确保在嵌套结构中正确使用 `break` 以避免意外的控制流行为。
119 2
|
1月前
|
传感器 安全 编译器
【C语言】enum 关键字详解
`enum`关键字在C语言中提供了一种简洁而高效的方法来定义一组相关的常量。通过使用枚举,可以提高代码的可读性、可维护性,并减少错误的发生。在实际应用中,枚举广泛用于表示状态、命令、错误码等,为开发者提供了更清晰的代码结构和更方便的调试手段。通过合理使用枚举,可以编写出更高质量、更易维护的C语言程序。
118 2
|
1月前
|
缓存 安全 编译器
【C语言】volatile 关键字详解
`volatile` 关键字在 C 语言中用于防止编译器对某些变量进行优化,确保每次访问该变量时都直接从内存中读取最新的值。它主要用于处理硬件寄存器和多线程中的共享变量。然而,`volatile` 不保证操作的原子性和顺序,因此在多线程环境中,仍然需要适当的同步机制来确保线程安全。
65 2
|
1月前
|
存储 编译器 程序员
【C语言】auto 关键字详解
`auto` 关键字用于声明局部变量的自动存储类,其作用主要体现在变量的生命周期上。尽管现代C语言中 `auto` 的使用较少,理解其历史背景和作用对于掌握C语言的存储类及变量管理仍然很重要。局部变量默认即为 `auto` 类型,因此在实际编程中,通常不需要显式声明 `auto`。了解 `auto` 关键字有助于更好地理解C语言的存储类及其在不同场景中的应用。
52 1
|
1月前
|
C语言
【C语言】continue 关键字详解
`continue` 关键字在 C 语言中用于跳过当前循环中的剩余代码,并立即开始下一次迭代。它主要用于控制循环中的流程,使程序在满足特定条件时跳过某些代码。
84 1
【C语言】continue 关键字详解
|
1月前
|
存储 C语言
【C语言】static 关键字详解
`static` 关键字在C语言中用于控制变量和函数的作用域和生命周期。它可以用于局部变量、全局变量和函数,具有不同的效果。理解 `static` 关键字的用法有助于封装和管理代码,提高代码的可维护性和可靠性。
44 3
|
1月前
|
C语言
【C语言】return 关键字详解 -《回家的诱惑 ! 》
`return` 关键字在 C 语言中用于终止函数的执行,并将控制权返回给调用者。根据函数的类型,`return` 还可以返回一个值。它是函数控制流中的重要组成部分。
84 2
|
1月前
|
C语言
【C语言】sizeof 关键字详解
`sizeof` 关键字在C语言中用于计算数据类型或变量在内存中占用的字节数。它是一个编译时操作符,对性能没有影响。`sizeof` 可以用于基本数据类型、数组、结构体、指针等,了解和正确使用 `sizeof` 对于内存管理和调试程序非常重要。
69 2