char
- char-字符型,一个字节的整数,范围【-128-127】
- 字符数据(单引号括起来的字符)的本质是整数类型
- char 类型的变量可以打印为整数或者字符
const
- const 修饰的变量是只读的,本质还是变量
- const 修饰的局部变量在栈上分配空间
- const 修饰的全局变量在只读存储区分配空间
- const 只在编译器有用,在运行期无用
const 修饰的变量不是真正的变量,他只是告诉编译器该变量不能出现在赋值符号的左边;
- 在现代 C 语言编译器中,直接修改 const 全局变量将导致程序崩溃
注意:标准 C 语言编译器不会将 const 修饰的全局变量存储与只读存储区中,而是存储与可修改的全局数据区,其值依然可以改变;
1 |
|
Gcc 将全局 cosnt 存储与只读存储区,当我们试图修改其中的内容时候,就会报 Segmentation fault 错误(这也是标准 C 语言的定义)
其他编译器可能就没问题
- C 语言中的 const 使得变量具有只读属性
- 现代 C 编译器中的 const 将具有全局生命周期的变量存储与只读存储区
1 |
|
modify((int*)&j, 1); // Error
被 static 修饰的变量被存储在全局存储区,const 修饰的全局变量将被存放在只读存储区
modify((int*)&g_array[0], 1); // Error
g_array[0] 是全局变量,被 const 修饰的全局变量将存储区只读存储区
- const 修饰函数参数表示在函数体内不希望改变参数的值
- const 修饰函数返回值表示返回值不可改变,多用于返回指针的情形
C 语言中的字符串字面量存储与只读存储区中,在程序中需要使用 const char* 指针
1 |
|
void
在 C 语言中可以定义 void 类型的指针
1 |
|
不存在 void 类型的变量
C 语言中没有定义 void 究竟是多大内存的别名,无法在内存中开辟出 void 大小对应的变量
而指针是固定 4 或 8 个字节大小的,所以可以开辟指针类型的 void 变量
注意:在非标准 C 语言编译器中有的对 void 规定了大小,比如 gcc 编译器就规定了 void 大小为 1 个字节
printf(“%ld\n”, sizeof(void)); // 1
意义
- C 语言规定只有相同类型的指针才可以互相赋值
- void* 指针作为左值用于 “接收” 任意类型的指针
- void* 指针作为右值使用时需要进行强制类型转换
1 | // malloc() 函数是 C 语言标准库中的一个函数,用于动态地分配内存。 |
- void 是一种抽象的数据类型
- void 类型不能用于定义变量
- void 类型用于声明函数无参数
- void 类型用于声明函数无返回值
- 可以定义 void* 类型的指针
- void* 类型的指针可以接收任意类型的指针值
volatile
- volatile 可理解为 “编译器警告关键字”
- volatile 告诉编译器必须每次去内存中取变量值
- volatile 主要修饰可能被多个线程访问的变量
- volatile 也可以修饰可能被未知因数更改的变量
常量
C 语言中的常量类型
- 字面量
- 直接表示值含义的符号,如:5、’a’、”Ubuntu”
- 宏常量(字符化的字面量)
- 通过 #define 定义,间接表示值的符号,如:FIV => 5.5
- 枚举常量
- 通过 enum 定义,间接表示值的符号,如:First => 1
1 | // 示例 |
常量的类型
- 字面量有其默认的类型,也可通过后缀指定其类型
- #define 定义的宏常量可以是任意类型
- enum 定义的枚举常量只能是整形
字面量是常量,但是它的默认类型由语言提供,也可通过后缀指定其类型;
const
C 语言中的只读变量
- C 语言提供了 const 关键字,用于修饰一个变量
- 被 const 修饰的变量只能作为右值使用
- 无法通过赋值操作改变 const 变量的值
- const 修饰
浮点数
同样是4个字节,为什么float却比int的范围大得多呢?
- float 能表示的具体数字的个数与int相同
- float可表示的数字之间不是连续的,存在间隙
- float只是一种近似的表示法,不能作为精确使用
- 由于内存表示法相对复杂,float的运算速度比int慢很多
注意:
double 与 float 具有相同的内存表示法,因此 double 也是不精确的。由于 double 占用的内存较多,所能表示的精度比 float 高;
小结
- 浮点类型与整数类型的内存表示法不同
- 浮点类型的内存表示更复杂
- 浮点类型可表示的范围更大
- 浮点类型是一种不精确的类型
- 浮点类型的运算速度很慢
类型转换
整形
long
- long 在使用不同的编译器时,可能占用的内存不同
- long 通常占 4 字节内存,也可能占 8 字节内存
- long long表示整形,固定占用 8 字节内存
- long long 是 long long int 的缩写形式
struct
- C 语言中的 struct 可以看作变量的集合
空结构体占用多大内存?
1 | // 示例 |
GCC 编译器允许空结构体的存在,且大小为 0 ,其他编译器如 vs 则不支持空结构体的存在;
柔性数组
- 柔性数组即数组大小待定的数组
- C 语言中可以由结构体产生柔性数组
- C 语言中结构体的最后一个元素可以是未知大小的数组
1 | struct SoftArray { |
SoftArray 中的 array 仅是一个待使用的标识符,不占用存储空间;
此时 SoftArray 的大小就是 int len 的大小 4 个字节;
柔性数组的用法