2.1 数据类型
2.1.1 数据类型概念
什么是数据类型?为什么需要数据类型? 数据类型是为了更好进行内存的管理,让编译器能确定分配多少内存。 |
我们现实生活中,狗是狗,鸟是鸟等等,每一种事物都有自己的类型,那么程序中使用数据类型也是来源于生活。
当我们给狗分配内存的时候,也就相当于给狗建造狗窝,给鸟分配内存的时候,也就是给鸟建造一个鸟窝,我们可以给他们各自建造一个别墅,但是会造成内存的浪费,不能很好的利用内存空间。
我们在想,如果给鸟分配内存,只需要鸟窝大小的空间就够了,如果给狗分配内存,那么也只需要狗窝大小的内存,而不是给鸟和狗都分配一座别墅,造成内存的浪费。
当我们定义一个变量,a = 10,编译器如何分配内存?计算机只是一个机器,它怎么知道用多少内存可以放得下10?
所以说,数据类型非常重要,它可以告诉编译器分配多少内存可以放得下我们的数据。
数据类型基本概念:
|
2.1.2 typedef的功能
- 起别名 - 简化struct关键字
- 区分数据类型
- 提高代码移植性
示例代码:
typedef unsigned int u32; //起别名、提高代码移植性
typedef struct _PERSON //简化struct关键字
{
char name[64];
int age;
}Person;
void test(){
u32 val; //相当于 unsigned int val;
Person person; //相当于 struct PERSON person;
}
2.1.3 void数据类型
void字面意思是”无类型”,void* 无类型指针,无类型指针可以指向任何类型的数据。
void定义变量是没有任何意义的,当你定义void a,编译器会报错。
void真正用在以下三个方面:
1.限定函数返回值,函数参数
2.void * 万能指针 可以不通过强制类型转换就转成其他类型指针
3.常用于数据类型的封装
//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:%d\n",*(int*)p);
char c = 'a';
p = &c;
printf("c:%c\n",*(char*)p);
}
//4. void* 常用于数据类型的封装
void test04()
{
//void * memcpy(void * _Dst, const void * _Src, size_t _Size);
}
2.1.4 sizeof操作符
sizeof是c语言中的一个操作符,类似于++、--等等。sizeof能够告诉我们编译器为某一特定数据或者某一个类型的数据在内存中分配空间时分配的大小,大小以字节为单位。
基本语法:
sizeof(变量); sizeof 变量; sizeof(类型); |
sizeof 注意点:
- sizeof返回的占用空间大小是为这个变量开辟的大小,而不只是它用到的空间。所以对结构体用的时候,大多情况下就得考虑字节对齐的问题了;
- sizeof返回的数据结果类型是unsigned int;
- 要注意数组名和指针变量的区别。通常情况下,我们总觉得数组名和指针变量差不多,但是在用sizeof的时候差别很大,对数组名用sizeof返回的是整个数组的大小,而对指针变量进行操作的时候返回的则是指针变量本身所占得空间。而且当数组名作为函数参数时,在函数内部,形参也就是个指针,所以不再返回数组的大小;
示例代码:
//1. sizeof基本用法
void test01()
{
int a = 10;
printf("len:%d\n", sizeof(a));
printf("len:%d\n", sizeof(int));
printf("len:%d\n", sizeof a);
}
//2. sizeof 返回结果的类型
void test02()
{
unsigned int a = 10;
if (a - 11 < 0)
{
printf("结果小于0\n");
}
else
{
printf("结果大于0\n"); //整型遇到无符号整型,整型会自动转换成无符号整型,输出结果
//所以为“结果大于0”
}
int b = 5;
if (sizeof(b) - 10 < 0)
{
printf("结果小于0\n");
}
else
{
printf("结果大于0\n"); //输出结果为“结果大于0”
}
}
//3. sizeof 碰到数组
void TestArray(int arr[])
{
printf("TestArray arr size:%d\n",sizeof(arr)); //返回指针大小
}
void test03()
{
int arr[] = { 10, 20, 30, 40, 50 };
printf("array size: %d\n",sizeof(arr)); //返回数组大小
int* pArr = arr;
printf("array size: %d\n", sizeof(pArr));
//数组做函数函数参数,将退化为指针,在函数内部不再返回数组大小
TestArray(arr);
}
2.1.5 数据类型总结
- 数据类型本质是固定内存大小的别名,是个模具,C语言规定:通过数据类型定义变量;
- 数据类型大小计算(sizeof);
- 可以给已存在的数据类型起别名typedef;
- 数据类型的封装(void 万能类型);
2.2 变量
2.1.1 变量的概念
既能读又能写的内存对象,称为变量;
若一旦初始化后不能修改的对象则称为常量。
变量定义形式: 类型 标识符, 标识符, … , 标识符 |
2.1.2 变量名的本质
- 变量名的本质:一段连续内存空间的别名;
- 程序通过变量来申请和命名内存空间 int a = 0;
- 通过变量名访问内存空间;
- 不是向变量名读写数据,而是向变量所代表的内存空间中读写数据;
- 变量的修改方式
- 直接修改
- 间接修改
void test()
{
int a = 10;
//1. 直接修改
a = 20;
printf("直接修改,a:%d\n",a);
//2. 间接修改
int* p = &a;
*p = 30;
printf("间接修改,a:%d\n", a);
}