C语言:数据类型、typedef使用、void及万能指针使用、变量的修改方式

一、数据类型

什么是数据类型,为什么需要数据类型?
数据类型是为了更好的进行内存的管理,让编译器能确定分配多少的内存。
例如:我们在进行变量定义的时候,定义了一个整型变量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的地址。
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值