一、数据类型
什么是数据类型,为什么需要数据类型?
数据类型是为了更好的进行内存的管理,让编译器能确定分配多少的内存。
例如:我们在进行变量定义的时候,定义了一个整型变量a,将数字10赋给它,开辟了一个4个字节大小的内存;但如果我们在a前面不加上数据类型,假设随意分配了100M给a,它被循环使用100次,会造成大量的内存浪费,因此,编译器制定出数据类型来更好的管理内存空间。
int a = 10;//4字节
a = 10;//100M,for(100次),会造成内存浪费
数据类型基本概念:
类型是对数据的抽象;
类型相同的数据具有相同的表示形式、存储格式以及相关操作;
程序中所有的数据都必定属于某种类型;
数据类型可以理解为创建变量的模具:固定大小内存的别名;
固定大小内存的别名:即int a = 10;我们在内存中开辟了一块4个字节大小的空间,为其起了一个别名a。
基本数据类型:
二、数据类型的别名:typedef的使用
typedef主要用途:给类型起别名
语法:typedef 原名 别名
typedef功能: 1.简化结构体的关键字struct
例如:我们定义了一个结构体变量Person,当我们使用时候必须要带上关键字struct,如果数据量大的话,非常麻烦。
struct Person
{
char name[50];
int age;
};
void test1()
{
struct Person p1 = {"张三",20};
struct Person p2 = {"李四",21};
struct Person p3 = {"王五",22};
}
此时我们可以利用typedef来为Person取一个别名,未来可以直接使用。简化了代码,如图:简化了代码。
typedef struct Person
{
char name[50];
int age;
}MyPerson;
void test1()
{
MyPerson p1 = {"张三",20};
MyPerson p2 = {"李四",21};
MyPerson p3 = {"王五",22};
}
2.区分数据类型
如图:p1,p2为什么数据类型?
void test2()
{
char* p1,p2;//p1为char*类型,p2为char类型
}
p1为char*类型,p2为char类型,很多人很容易混淆。此时我们使用typedef对取一个别名,再使用,此时p1,p2均为char *类型;这样就方便清楚多了.
void test2()
{
typedef char* PCHAR;
PCHAR p3,p4;//p3,p4均为char*类型
}
测试类型结果如图:
3.提高代码移植性
当我们在C99标准下一直使用long long类型,假设它在C89标准下执行不同,需要改为int类型我们此时需要改非常的十分麻烦。此时使用typedef,只需要将long long改为int即可全部替换。
typedef int MYINT;
//typedef long long MYINT;
void test3()
{
MYINT a = 10;
MYINT b = 20;
}
三、void的使用
void:字面意思为无类型。void定义变量没有任何意义,编译器会报错。如图:
void test1()
{
//void a = 10;编译器报错,编译器不知道给a分配多少内存空间。
}
void作用:1.可以限定函数返回值
void fun()
{
return 10;
}
当我们使用void时,却在函数中返回了10,编译器会报错。使用void限定了函数无返回值。
void作用:2.限定函数参数列表
我们在func(void)中加入了void,声明参数为void,但是却传了10编译器报错。
int func(void)//限定函数参数列表
{
return 10;
}
void test3()
{
printf("%d\n",func(10));
}
int main()
{
test3();
return 0;
}
四、void* 万能指针的使用
void * :为无类型指针,任何类型的指针都可以直接赋值给它,无需进行强制类型转换。(sizeof(void*))为4,因为为指针类型。
如图:任何类型的指针都可以直接赋值给它,无需进行强制类型转换。但这并不意味着,void * 也可以无需强制类型转换地赋给其它类型的指针。因为"无类型"可以包容"有类型",而"有类型"则不能包容"无类型"。
void test4()
{
void *p = NULL;
int *pInt = NULL;
char *pChar = NULL;
pChar = (char*)pInt;//必须强转编译器才不会报错
p = pChar ;//可以不需要强制类型转换就可以给等号左边赋值
}
五、变量的修改方式
1.对于内置数据类型:有直接修改和间接修改方式
//对于内置数据类型
void test()
{
int a = 10;
a = 20;//直接修改
printf("%d\n",a);
int*p = &a;
*p = 100;//间接修改
printf("%d\n",a);
}
2.对于自定义类型数据:直接修改、间接修改、地址偏移来修改三种方式,举个例子:
void test()
{
struct Person p1 = {'a',10,'b',20};
//直接修改d
p1.d = 1000;
printf("d = %d\n",p1.d);
//间接修改d,指针修改
struct Person * p = &p1;
p->d = 2000;
printf("d = %d\n",p->d);
//间接修改,地址偏移修改
char * pPerson = (char*)p;
printf("d = %d\n",(*(int*)(pPerson+12))); //pPerson为char类型,步长为1
//所以需要+12为d的地址,再强转为int类型,最后解引用即是d的地址。
printf("d = %d\n",*((int*)pPerson+3)); //先将pPerson强转为int类型,步长为4
//所以需要+3为d的地址,再解引用为d的地址。
}