| 什么是数据类型?为什么需要数据类型? 数据类型是为了更好进行内存的管理,让编译器能确定分配多少内存。 |
我们现实生活中,狗是狗,鸟是鸟等等,每一种事物都有自己的类型,那么程序中使用数据类型也是来源于生活。
当我们给狗分配内存的时候,也就相当于给狗建造狗窝,给鸟分配内存的时候,也就是给鸟建造一个鸟窝,我们可以给他们各自建造一个别墅,但是会造成内存的浪费,不能很好的利用内存空间。
我们在想,如果给鸟分配内存,只需要鸟窝大小的空间就够了,如果给狗分配内存,那么也只需要狗窝大小的内存,而不是给鸟和狗都分配一座别墅,造成内存的浪费。
当我们定义一个变量,a = 10,编译器如何分配内存?计算机只是一个机器,它怎么知道用多少内存可以放得下10?
所以说,数据类型非常重要,它可以告诉编译器分配多少内存可以放得下我们的数据。
| 狗窝里面是狗,鸟窝里面是鸟,如果没有数据类型,你怎么知道冰箱里放得是一头大象! |
数据类型基本概念:
|
概念:数据类型宏定义
typedef比起define可以一起同时定义多个变量数据类型
| typedef unsigned int u32; typedef struct _PERSON{ char name[64]; int age; }Person; void test(){ u32 val; //相当于 unsigned int val; Person person; //相当于 struct PERSON person;起到简化关键字的作用 } |
应用场景:
1.起到简化结构体创建变量
2.比起define数据可以做到区分数据类型
3.提高代码的移植性
很多处数据类型需要改动的时候只用改动宏定义就可以了
只用修改一处代码即可。
4.void数据类型--特殊数据类型 万能指针概念:
不能定义变量,不知道分配多少内存空间
void字面意思是”无类型”,void* 无类型指针,无类型指针可以指向任何类型的数据。
void* 可以指向任何类型的数据,被称为万能指针
- void定义变量是没有任何意义的,当你定义void a,编译器会报错。
- 应用场景:
void真正用在以下三个方面:
- 对函数返回的限定;
- 对函数参数的限定;
- void* 常用于数据类型的封装
示例代码:
| //1. void修饰函数参数和函数返回 void test01(void){ printf("hello world"); } //2. 不能定义void类型变量 void test02(){ void val; //报错 } //3. void* 可以指向任何类型的数据,被称为万能指针 不通过强制类型转换,就可以转换任意类型指针,而且不会报错 void test03(){ int a = 10; void* p = NULL; p = &a; printf("a:%dn",*(int*)p); char c = 'a'; p = &c; printf("c:%cn",*(char*)p); } //4. void* 常用于数据类型的封装 void test04(){ //void * memcpy(void * _Dst, const void * _Src, size_t _Size); } |
sizeof操作符 (不是一个函数,是操作符)
sizeof是c语言中的一个操作符,类似于++、--等等。sizeof能够告诉我们编译器为某一特定数据或者某一个类型的数据在内存中分配空间时分配的大小,大小以字节为单位。
基本语法:
| sizeof(变量); sizeof 变量; sizeof(类型); |
sizeof 注意点:
- sizeof返回的占用空间大小是为这个变量开辟的大小,而不只是它用到的空间。和现今住房的建筑面积和实用面积的概念差不多。所以对结构体用的时候,大多情况下就得考虑字节对齐的问题了;
- sizeof返回的数据结果类型是unsigned int;
- 要注意数组名和指针变量的区别。通常情况下,我们总觉得数组名和指针变量差不多,但是在用sizeof的时候差别很大,对数组名用sizeof返回的是整个数组的大小,而对指针变量进行操作的时候返回的则是指针变量本身所占得空间,在32位机的条件下一般都是4。而且当数组名作为函数参数时,在函数内部,形参也就是个指针,所以不再返回数组的大小;
- 对于字符串有加上
应用场景:
获取数据类型大小
示例代码:
5 数据类型总结//1. sizeof基本用法
void test01(){
int a = 10;
printf("len:%dn", sizeof(a));
printf("len:%dn", sizeof(int));
printf("len:%dn", sizeof a);
}
//2. sizeof 结果类型 返回值是unsigned int 和int 进行计算统一转换为unsigned int
void test02(){
unsigned int a = 10;
if (a - 11 < 0){
printf("结果小于0n");
}
else{
printf("结果大于0n");
}
int b = 5;
if (sizeof(b) - 10 < 0){
printf("结果小于0n");
}
else{
printf("结果大于0n");
}
}
//3. sizeof 碰到数组 数组名代表一整个数据长度,但是传入函数数组名就是首地址了
void TestArray(int arr[]){
printf("TestArray arr size:%dn",sizeof(arr));
}
void test03(){
int arr[] = { 10, 20, 30, 40, 50 };
printf("array size: %dn",sizeof(arr));
//数组名在某些情况下等价于指针
int* pArr = arr;
printf("arr[2]:%dn",pArr[2]);
printf("array size: %dn", sizeof(pArr));
//数组做函数函数参数,将退化为指针,在函数内部不再返回数组大小
TestArray(arr);
}
- 数据类型本质是固定内存大小的别名,是个模具,C语言规定:通过数据类型定义变量;
- 数据类型大小计算(sizeof);
- 可以给已存在的数据类型起别名typedef;
- 数据类型的封装(void 万能类型);



