深入理解C语言-深入理解void
void的字面意思是"无类型",void *
则为"无类型指针",void *
可以指向任何类型的数据
void含义
void几乎只有注释和限制程序的作用,定义一个void变量没有意义
void的真正作用在于
- 对函数返回的限定
- 对函数参数的限定
在C语言中,void *
可以接受任意类型指针的赋值,而不需要进行内存强制转换
void *p1;
int *p2;
p1 = p2;
但这并不意味着,void *
也可以无需强制类型转换地赋给其它类型的指针。因为无类型可以包容有类型,而有类型则不能包容无类型。以下语句在编译时候就会报错
void *p1;
int *p2;
p2 = p1;
void的理解
如果函数没有返回值,那么应声明为void类型
在C语言中,凡不加返回值类型限定的函数,就会被编译器作为返回int类型值处理
但在实际编程中,为了代码的可阅读和可维护,无返回值的时候要加上void
如果函数无参数,那么应声明其参数为void
虽然很多时候,在函数没有参数的时候,需要加上void
在C有的编译器中,如果不添加void,那么此函数会接受任意类型参数
所以,在函数不接受任何参数的时候要用void进行说明
小心使用void指针类型
在不同的C标准中,处理void指针的算法操作有着不一样的宽容度
ANSI认为,一切对void指针的运算操作都是非法的,会报错
而GNU则认为,void指针的算法操作和char *
保持一致
为何兼容二者的思想,一般会对void指针进行转化,然后再对其操作
void * pvoid;
(char *)pvoid++; //ANSI:正确;GNU:正确
(char *)pvoid += 1; //ANSI:错误;GNU:正确
如果函数的参数可以是任意类型指针,那么应声明其参数为void *
典型的如内存操作函数memcpy和memset的函数原型分别为:
void * memcpy(void *dest, const void *src, size_t len);
void * memset ( void * buffer, int c, size_t num );
任何类型的指针都可以传入memcpy和memset中,这也真实地体现了内存操作函数的意义,因为它操作的对象仅仅是一片内存,而不论这片内存是什么类型
这两个函数的返回值也是void *
void不能代表一个真实的变量
void代表了一种抽象,而不是实实在在存在的变量
因此,不能定义一个void变量
void的使用
数据类型的封装
int InitHardEnv(void **handle);
典型的如内存操作函数memcpy和memset的函数原型分别为
void * memcpy(void *dest, const void *src, size_t len);
void * memset ( void * buffer, int c, size_t num );
void修饰函数返回值和参数,仅表示无
如果函数没有返回值,那么应该将其声明为void型
如果函数没有参数,应该声明其参数为void
int function(void)
{
return 1;
}
void指针的意义
C语言规定只有相同类型的指针才可以相互赋值
void*
指针作为左值用于接收任意类型的指针
void*
指针作为右值赋值给其它指针时需要强制类型转换
int *p1 = NULL;
Char *p2 = (char *)malloc(sizoeof(char) * 20);
不存在void类型的变量
C语言没有定义void究竟是多大内存的别名
深入理解C语言-深入理解void的更多相关文章
- 深入理解C语言-深入理解指针
关于指针,其是C语言的重点,C语言学的好坏,其实就是指针学的好坏.其实指针并不复杂,学习指针,要正确的理解指针. 指针是一种数据类型 指针也是一种变量,占有内存空间,用来保存内存地址 指针就是告诉编译 ...
- 深入理解C语言-深入理解数组
数组,作为C语言中常见的复杂数据类型,了解其本质有助于深入了解C语言 数组概念 元素类型角度:数组是相同类型的变量的有序集合测试指针变量占有内存空间大小 内存角度:联系的一大片内存空间 数组初始化 数 ...
- 深入理解C语言-深入理解内存四区
数组与指针 当数组做函数参数的时候,会退化为一个指针 此时在函数内是得不到数组大小的 因此,数组做函数参数的时候需要传递数组大小,也就是多传递一个参数 void func(int arr[], int ...
- 深入理解C语言中的指针与数组之指针篇
转载于http://blog.csdn.net/hinyunsin/article/details/6662851 前言 其实很早就想要写一篇关于指针和数组的文章,毕竟可以认为这是C语言的根本 ...
- 【转载】理解C语言中的关键字extern
原文:理解C语言中的关键字extern 最近写了一段C程序,编译时出现变量重复定义的错误,自己查看没发现错误.使用Google发现,自己对extern理解不透彻,我搜到了这篇文章,写得不错.我拙劣的翻 ...
- 深入理解C语言中的指针与数组之指针篇(转载)
前言 其实很早就想要写一篇关于指针和数组的文章,毕竟可以认为这是C语言的根本所在.相信,任意一家公司如果想要考察一个人对C语言的理解,指针和数组绝对是必考的一部分. 但是之前一方面之前一直在忙各种事情 ...
- 深入理解c语言_从编译器的角度考虑问题_纪念Dennis Ritchie先生
开源中国: Dennis Ritchie教授过世了,他发明了C语言,一个影响深远并彻底改变世界的计算机语言.一门经历40多年的到今天还长盛不训的语言,今天很多语言都受到C的影 响,C++,Java,C ...
- "深入理解C语言" 指针
本文对coolshell中的"深入理解C语言"这篇文章中提到的指针问题, 进行简要的分析. #include <stdio.h> int main(void){ ]; ...
- (C)理解#define write(b,addr) (void)((*(volatile unsigned int *) (addr)) = (b))
理解 #define write(b,addr) (void)((*(volatile unsigned int *) (addr)) = (b)) 嵌入式系统编程,要求程序员能够利用C语言访问固 ...
随机推荐
- Qt 窗体增加滚动条
//滚动区域 m_ScrollArea = new QScrollArea(parentWidget()); m_ScrollArea->setGeometry(, , , ); //垂直滚动条 ...
- springboot 详解RestControllerAdvice(ControllerAdvice)(转)
springboot 详解RestControllerAdvice(ControllerAdvice)拦截异常并统一处理简介 @Target({ElementType.TYPE}) @Retentio ...
- Markdown使用教程(转载收藏)
基础语法 标题 Markdown支持6种级别的标题,对应html标签 h1 ~ h6 # h1 ## h2 ### h3 #### h4 ##### h5 ###### h6 以上标记效果如下: h1 ...
- 观察者模式(Observer)---行为型
1 基础知识 定义:定义了对象之间的一对多依赖,让多个观察者对象同时监听某一个主题对象,当主题对象发生变化时,它的所有依赖(观察者)都会收到通知并更新. 本质:触发联动 使用场景:关联行为场景,建立一 ...
- Java 显示调用隐式调用
当你没有使用父类默认的构造方法时,此时在子类的构造方法中就需要显示的调用父类定义的构造方法.比如:父类:class Animal{ private String name; //如果你定义一个新的构造 ...
- APPLICATION FAILED TO START 报错
错误一 原因@Service 忘记加了
- mac使用php-version切换PHP版本
在开发过程中,有时候我们的程序对某个php版本有着极为重要的限制,特别是大型项目. 因此,我们就需要切换多个php版本来满足我们的需求. 我们使用php-version来达到这个目的. 首先我们先使用 ...
- Python常用模块之hashlib模块
1.hashilib模块的功能 python的hashlib提供了常见的摘要算法,如MD5, SHA1等等. 什么是摘要算法呢?摘要算法又称哈希算法.散列算法.它通过一个函数,把任意长度的数据转换成一 ...
- IDEA2019.1.3的安装和破解
上一篇文章我有写过我会尝试安装IDEA(这玩意儿收费啊!),倘若尝试成功以后都会用它编译,很幸运,我安装成功了,所以今天这篇文章我来写安装和破解方法. IDEA界面: 首先我们访问官方网站:htt ...
- POJ 1144 Network —— (找割点)
这是一题找无向图的割点的模板题,割点的概念什么的就不再赘述了.这里讲一下这个模板的一个注意点. dfs中有一个child,它不等于G[u].size()!理由如下: 如上图,1的size是2,但是它的 ...