char强制类型转换为int_既然C语言void指针是“万能指针”,那么malloc还需类型转换吗?...

在C语言程序开发中,动态内存分配是不可避免的,而调用 malloc()/free() 库函数实现这一过程是方便的,事实上,在很多C语言程序中,malloc/free 库函数的使用相当频繁,它俩的C语言函数原型如下,请看:

void *malloc(size_t size);void free(void *ptr);
3f80fdabbddfa9c841a89bf24fdd1878.png

malloc() 函数需要类型转换吗?

正常情况下,malloc() 函数会从堆中申请 size 字节的内存,并且将这块内存的首地址返回,原则上,系统不会再将被 malloc() 申请的内存分配给其他代码使用,除非 free() 函数将 malloc() 申请的内存释放。

malloc() 函数需要类型转换吗?

读者应该注意到,malloc() 函数的返回值是 void * 指针型的。看过我之前文章的读者应该明白,在C语言中,void * 指针是不能够直接用于索引数据的。

512979f8eb0661f0d678ff7aa881c242.png

void * 指针是不能够直接用于索引数据的

因此在实际的C语言程序开发中,程序员调用 malloc() 函数时,一般都会定义其他类型的指针,例如:

char *cp = malloc(size);

读者看到这里,可能会产生疑问:malloc() 函数的返回值类型是 void * 指针型,而变量 cp 则是 char * 指针型,似乎出现了类型不匹配的情况,是否需要类型转换呢?

0597f0cfe9d58b1d61524edbd561edb5.png

是否需要类型转换呢?

事实上,的确不少C语言程序员在调用 malloc() 函数时会使用类型转换:

char *cp = (char *)malloc(size);int *ip = (int *)malloc(size * sizeof(int));...

那么,调用 malloc() 函数时,究竟需要不需要类型转换呢?

不需要?

有程序员认为,C语言经过这么多年的发展,对于 malloc() 函数,如今似乎不再需要类型转换了,因为 void * 指针会自动的并且安全的被转换为对应类型的指针。void * 指针在很多C语言教材中被称为“万能指针”,这里就是一个体现。

4f646feec7ca70f82fe5900861b9dd3f.png

void * 指针在很多C语言教材中被称为“万能指针”

既然 void * 指针可以自动的被转换成对应的指针类型,那么再写类型转换代码似乎就“多余”了,反而会让整个C语言代码啰嗦臃肿,损失可读性,尤其是指针类型名很长的时候,例如:

struct this_is_test *p = (struct this_is_test *)malloc(size);// 不写类型转换代码struct this_is_test *p = malloc(size);

上面的C语言代码显然有重复部分,而且这段重复的C语言代码的“类型转换功能”也是多余的,要是以后需要修改结构体 this_is_test 的名字,还需要修改强制类型转换部分的代码,略显繁琐。与之相对的,下面这行C语言代码明显简洁许多。

a1f6c195c84a4fcacc6c4a6cca0e0218.png

下面这行C语言代码明显简洁许多

这么看来,似乎对 malloc() 函数做类型转换“百害而无一利”了,有程序员甚至认为,在C语言程序开发中,调用 malloc() 函数使用类型转换,只是因为不知道类型转换会带来的潜在不利而已。

需要?

不过,也有C语言程序员持反对意见,他们认为,在调用 malloc() 时使用类型转换可以让代码在 C语言和C++之间可移植,有些程序员以为自己在写C语言程序,但是他们实际上还是会用到C++的一些特性。

c49457677f0ed2225bf5ab0e503ecbb6.png

在 C语言和C++之间可移植

另外,调用 malloc() 函数使用类型转换还可以发现一些潜在的风险,例如有的C语言程序员会在开发中弄混 type * 和 type ** ,如果没有显式的类型转换,这样的错误就会被编译器隐藏掉了。

因此,在对 malloc() 函数的返回值做数据类型转换的过程,本身就是C语言程序员自检代码的过程,这样更加容易在开发阶段就发现 bug。而且,如果C语言程序出现了数据类型相关的错误,调用 malloc() 函数做了类型转换肯定能够更加方便的定位错误。

小结

弄清楚在C语言程序开发中调用 malloc() 函数时,做不做类型转换的各自特点后,应该能够发现其实各有各的好处,那究竟是否需要做类型转换,就在于程序员自己的开发习惯了。

abb1ee37a5fa7c1519e9eb1cfd535283.png

点个赞再走吧

欢迎在评论区一起讨论,质疑。文章都是手打原创,每天最浅显的介绍C语言、linux等嵌入式开发,喜欢我的文章就关注一波吧,可以看到最新更新和之前的文章哦。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
题目:学生通讯录管理系统 任务说明: 通讯录管理系统,至少具有如下功能: 记录通讯录内的人员的 显示所有人员的信息。 通过输入姓名查找人员信息。 通过输入姓名查找到要删除的人员信息,然后可以进行删除。 通过输入姓名查找到要修改的人员信息,然后可以进行修改。 添加人员信息。 系统功能描述: 本程序的功能是为用户提供简单的通讯录进行管理,通过该程序存储联系人信息 ,提供关键字〔只能是英文关键字进行查找〕查找功能,可以对数据进行修改、删除 、添加等操作。 各按钮的功能如下: 查找记录:以姓名为关键字,查找并显示该记录。假设查找不到,那么显示"好象没 有〞; 添加记录:将当前记录按姓名序参加通讯录,然后显示第一条记录; 修改记录:修改当前记录,显示当前记录。姓名为关键字,不允许修改; 删除记录:删除当前记录,然后显示第一条记录; 第一条记录:将当前记录指针移动至首节点,假设已为首节点,那么不移动; 前一条记录:将当前记录指针向前移动一个节点,假设已为首节点,那么不移动; 后一条记录:将当前记录指针向后移动一个节点,假设已为尾节点,那么不移动; 最后一条记录:将当前记录指针移动至尾节点,假设已为尾节点,那么不移动; 保存:保存通讯录数据; 退出:退出系统; 设计思路: 根据要求, 录 图1 系统功能模块图 软件中使用的结构体和结构体数组,如: struct callmember { char name[20]; char address[20]; char code[20]; char callnumber[20]; }; 对用户的信息进行保存,他们都以二进制的形式读写。 其中: char name[20]; char address[20]; char code[20]; char callnumber[20] struct callmember one[100]; #include "stdafx.h" #include"string.h " #include <stdio.h> #include<stdlib.h> 其中还使用 void output(); void del(); void found(); void modify() ; void insert(); void output() { int b=0,i=0; int j; struct callmember one[100]; FILE *fp; if((fp=fopen("e:\\通讯录.txt","r"))==NULL) { printf("无法从已有通讯录输入!\n可能是因为原通讯录不存在或为空!\n建议你检查你 的通讯录文挡!\n"); exit(1); } while(fscanf(fp,"%s%s%s%s",one[i].name,one[i].address,one[i].code,one[i].cal lnumber)!=EOF) i++; j=i; for(i=0;i<j;i++) { printf("%s %s %s %s\n ",one[i].name,one[i].address,one[i].code,one[i].callnumber); } fclose(fp); } void insert() { FILE *fp; struct callmember *p; if((fp=fopen("e:\\通讯录.txt","a+"))==NULL) { printf("操作失败."); exit(1); } p=(struct callmember *)malloc(sizeof(struct callmember)); printf(" ************************\n"); printf(" 姓名:"); scanf("%s",p->name); printf(" 地址:"); scanf("%s",p->address); printf(" :"); scanf("%s",p->code); printf(" :"); scanf("%s",p->callnumber); printf(" ************************\n"); fprintf(fp,"%s %s %s %s",p->name,p->address,p->code,p->callnumber); fclose(fp); free(p); } 通过对这些资源的合理利用使系统初步实现了通讯录管理系统的根本功能。 程序流程图: else printf("\n对不起,通讯录中没有此人的记录。"); fclose(fp); } 结果分析: 1运行进入程序主菜单 2查看所有人员信息界面 可以显示全部的人员的信息。可在3 .3参看流程图。 3

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值