目录
前言
在上一节中, 我们写了第一个C语言程序, 在屏幕上输出字符串"Hello World!", 这有什么意义呢? 我认为其最重要的意义是: 我们能让计算机帮助我们做事情了, 虽然仅仅是在黑框框中显示一个字符串. 在这一节中, 我们就开始聊聊编程中的另一个小重点 ---- 变量和常量 ~
变量和常量
变量
什么是变量呢? 我们先顾名思义, 变量, 就是一个变化的量, 或者说可以变化的量, 那么变量到底是什么呢? 我们以一个场景来说, 植物大战僵尸中的植物的血量, 僵尸的血量,当前的阳光的数量, 我们在收集到阳光的时候, 当前的阳光的数量就会增加, 当我们的植物攻击到僵尸, 或者僵尸攻击到植物的时候, 僵尸的血量或者植物的血量就会降低, 所以我们说, 在我们的程序运行的过程中, 变化的量就是变量~
C语言中定义变量
变量的声明和定义
在C/C++语言中:
我们使用 变量类型 变量名; 这样的方式来声明一个变量.
我们使用 变量类型 变量名 = 初始值; 这样的方式来定义并且初始化一个变量.
C语言中呢~, 变量在使用之前必须定义, 如果编译器没有发现变量的定义, 会将从上向下的第一个变量的声明转化成变量的定义, 但是初始值为随机值(这一点随不同的编译器而定, 因为C语言标准没有规定)
#include <stdio.h>
int main()
{
int Hp = 100;
printf("Hp = %d\n", Hp);
Hp = Hp - 10;
printf("Hp = %d\n", Hp);
return 0;
}

其他语言定义变量
这里的其他语言, 我们就简单的以Golang语言来说, 因为Golang语言之父, 就是大名鼎鼎的C语言之父, 来自Google, 但是这里我们还是以C语言位置, 其他语言就提一下就好, 让大家有一些其他认识.
package main
func main() {
var Hp int = 100
age := 20 // 编译器根据初始值自定义类型, 但是自定义类型不能使用这样的方式, 像string
}
C语言中提供的数据类型
C语言中, 只提供了很少的类型, 这也是C语言很容易入门, 难以精通的原因之一, 因为很多复杂的类型需要程序员自己定义,
C语言中提供了以下类型:
整形家族
int 整形
char 字符类型, 其中存储的是ASCII码, 也属于整形的一种, 后边详细说
short 短整形
long 长整型
long long 长长整型?
小数类型(浮点数类型)
这里为什么是浮点类型呢? 因为小数可以使用科学计数法来记录, 所以也叫做浮点类型
folat 单精度浮点型
double 双精度浮点型
自定义类型
这个自定义类型, 我们先说说它有哪些? 其他的我们以后再说, 这里说感觉有点点早~
struct 结构体类型, 像后期学习的 socket 类型, task_struct 类型, 本质都是一个结构体
enmu 枚举类型, 像一些可以枚举的常量, 就可以使用枚举类型来定义
union 联合体类型, 像在内存空间比较紧张的时候, 往往会使用联合体类型, 让多个变量占用同一部分空间, 以后详说
指针类型
这个C语言中也提供了, 并且是C语言的精髓, 这里说的说说不清, 下一次
C语言中变量所占的大小
在C语言中, 使用sizeof关键字来计算一个类型, 或者一个变量

这里我们说一下, 为什么 long 类型的大小和 int 类型的大小是一样的, 因为C语言标准之规定了 long 类型是大于等于 int 类型的, 然而 int 类型是占 4个字节, 不同的编译器有不同的实现方式, 所以在VS2019中, long 类型的大小是4个字节
float 类型 和 double 类型, 大小的主要区别在于 存储小数的精度是不同的, 因为在计算机中根据IEEE的标准来说, 小数是没有办法在计算机中进行精确的表示的, 这样就出现了精度的问题!
自定义类型所占空间大小我们以后再说~~
指针类型的变量中存储的一个变量的内存地址空间的编号, 所以他的大小是和机器的大小是相关的, 在32位下, 大小是32个bit位, 就是4个字节, 64位下是64个bit位, 也就是8个字节
局部变量和全局变量
定义在 { } 花括号中的变量都是局部变量, { } 花括号之外的变量是 全局变量, 全局变量和局部变量在内存中的位置是不一样的

这里的 { } 花括号, 可以是日后的 if { } while { } for { } 等等
变量的生命周期
全局变量的声明周期是整个程序执行过程中都是有效的, 但是局部变量出了定义自己的 { } 花括号就不再有效了

我们可以看到, 在代码执行到 定义 num 的 { } 花括号之后, num就不能再使用了! 但是全局变量 GlobalNum还是可以使用的.
数据类型的转化
隐式类型转换
浮点数转成整形 会向下取整, 整形转化为浮点型会在后面加上 .0
整形转化成短整型 会截断 损失精度.
强制类型转换
在需要转换的类型前面写小括号, 小括号里面协商要转化的类型
float c = 3.15;
int d = (float)c;
类型的转化, 必然是伴随着精度丢失的, 所以在使用类型转化的时候还是要小心一些~~
常量
常量, 顾名思义就是不能变化的量
C语言中定义常量的方式:
使用 #define 宏定义 来定义

使用 const 关键字来定义

两者的区别 和 优劣
#define 定义的宏 是通过替换的方式, 是没有数据类型的, 也就是说无论是整形, 浮点数类型都是可以被替换的, 这样就没有了类型的限定, 相较于const 变量类型 定义的变量来说, 就不是很安全
#define 不仅仅可以定义宏常量, 还可以定义宏函数, 想一些简单的宏函数, 我们就可以使用宏来定义, 有点C++中 inline 的意思
#define 定义的宏 是在编译四步骤中的预处理阶段被替换了, 那么我们在调试的时候就没有办法再看到NUM这样常量名称了.
小结
这一节中我们说了什么是常量和变量, 常量和变量的定义方式, , 为我们日后的开发又奠定了一个基础!
番外
注释
单行注释 //
多行注释 /**/

注释的作用了让我们看到之后, 可以明了的知道我们这一段代码干了什么, 方便过了很久之后的我们自己来看, 也方便和我们协同开发的人来看
如论是常量还是变量, 在C语言中, 都是可以通过指针来改变的, 但是这里我们还没有详细说到指针变量, 就日后再说叭. 这里我们主要说说变量在内存中是什么样的?
Linux 进程的虚拟地址空间分布
变量通常是在 stack 栈空间(栈段)中
malloc 申请的指针变量所指向的空间 是在 Heap 堆空间(堆段)中
定义了并且初始化不为0常量通常是在 .rodata段中, 只读数据段
定义了但是没有初始化或者初始化为0的常量通常是在 .bss 段中 未初始化数据段
代码通常是在 .text 段中, 代码段

1592

被折叠的 条评论
为什么被折叠?



