深刻理解void,void*和sizeof关键字

void的字面值是“无类型”,void*则是"无类型指针"。void*可以指向任何类型的数据。void几乎只有"注释"和限制程序的作用,因为从来没有人会定义一个void变量。

void a;    //编译时提示"illegaluseoftype‘void‘"

void真正发挥的作用在于:对函数返回的限定;对函数参数的限定

如果指针p1和p2的类型相同,那么p1和p2之间可互相赋值;如果p1和p2指向不同的数据类型,则必须使用强制类型转换运算符,把赋值运算符右边的指针类型转换为左边指针的类型,然后才可以赋值。如:

float* p1;

int* p2;

p1 = p2;  //can‘t convert from ‘int*‘ to ‘float*‘,必须改为下面这种形式

p1=(float*)p2;

而void*则不同,任何类型的指针都可以直接赋值给它,无须强制类型转换,例如:void* p1;int* p2;p1 = p2;

但这并不意味沣void*也可无须强制转换地赋值给其他类型的指针,这是因为"无类型"可以包含"有类型",而"有类型"不能包容"无类型"

void关键字使用规则

1.如果函数没有返回值,那么应声明为void类型。在C语言中,凡不加返回值类型限定的函数,就会编译器作为返回整型值处理,但是许多程序员却误认为其为void类型

例如

add(int a,int b)              int main()

{                     {

  return a+b;                printf("2+3=%d",add(2,3));

}                     }  //程序运行结果为2+3=5,这说明不加返回值说明的函数,其返回值的确为int类型

因此,为避免混乱,对于任何函数都必须指定其返回类型。如果函数没有返回值,一定要声明为void类型。发挥代码的自注释作用。这既是程序良好可读性的需要,也是编程规范性的要求

2.如果函数无参数,那么应声明其参数为void.如果在C++语言中声明一个这样的函数

int function(void)      //则进行function(2)是不合法的,因为在C++中,函数参数为void的意思是这个函数不接受任何参数,但如果在Turbo C2.0中编译则正确        

{              //说明在C语言中,可以给无参数的函数传送任意类型的参数,但在C++编译器中编译同样的代码则会出错。所以,若函数不接受任何参数,一定要声明为void

  return 1;

}

3.如果函数的参数可以是任意类型的指针,那么应声明其参数为void*

典型的如内存操作函数:

void* memcpy(void* dest,const void* src,size_t len);

void* memset(void* buffer,int c,size_t num);

这样,任何类型的指针都可以传入memcpy和memset中,这也真实地体现了内存操作函数的意义,因为它操作的对象仅仅是一片内存,而不论这片内存是什么类型

4.void不能代表一个真实的变量

void a      //错误

void体现了一种抽象,这个世界上的变量都是"有类型"的。void的出现只是为了一种抽象的需要,如果你正确地理解了面向对象中"抽象基类"的概念,也很容易理解void数据类型。

二.sizeof

时间: 2024-12-17 13:54:12

深刻理解void,void*和sizeof关键字的相关文章

parent,son深刻理解this,super关键字

核心点: super关键字,表示调用的是父类对象. this关键字,表示调用的是当前运行类对象. 那么如果在父类中,使用了关键字,this,此时的this指的是什么呢? 看下面的例子,再加深理解核心店的第二句话就ok了. parent类: package com.ghsy.thissuper; public class Parent { public void init(){ System.out.println(this.getClass()); //获得当前运行类 System.out.pr

C++ 类的多态一(virtual关键字--构造函数深刻理解)

//virtual关键字--构造函数深刻理解 #include<iostream> using namespace std; /* C语言编译器,c++编译器全部是静态链编,就是一段一段代码的编译,不会考虑上下文 例如编译到void ProtectA(Point pin) 编译器就会认为pin就是Point类型, 而不会去联系上下文,去分析pin有没有可能是子类对象 virtual关键字会自动检测这个父类对象有没有是子类对象 */ /* virtual关键字的作用 假设父类中存在用virtua

深刻理解C#中资源释放

今天我的一个朋友看到我写的那篇<C#中用AJAX验证用户登录>时,给我指出了点小毛 病.就是在用户登录时,如果用户登录失败,在下面这段代码中,都会new出来一个User对象,如果连续登录失败多次,就会生成多个User对象,而它们 在登录失败后已经无用了,依然占据着内存,就算是C#有垃圾回收机制,但不确定什么时候对这些对象进行回收.然后去网上找了一篇C#资源释放的文章,讲的很透彻,和大家分享一下. using System;using System.Collections.Generic;usi

POJ 2752 深刻理解KMP失配指针

思路:刚开始还在想怎么做,虽然以前是理解了失配指针的用处,但是确实不知道失配指针还有如此用处,其实还有很多用处,我用得少了不懂而已. 比如: i   0  1  2  3  4  5   6  7  8  9  10 11 p[i]  A  B R A  C  A  D  A  B  R  A  无 next[i]  0  0  0  0  1  0   1  0  1   2  3   4 next[11]=4这个肯定可以取了,因为这个后缀等于前缀嘛,然后再查询next[next[11]]=n

C语言学习笔记--enum和sizeof关键字

1.enum关键字 C语言中enum关键字用来定义枚举类型 (1)enum 是 C 语言中的一种自定义类型(2)enum 值是可以根据需要自定义的的整型值(3)第一个定义的 enum 值默认为 0 (4)默认情况下的 enum 值是在前一个定义值的基础上加 1 (5)enum 类型的变量只能取定义时的离散值 enum Color { GREEN, //默认 GREEN==0; RED= 2, //自定义 RED==2; BLUE //默认情况,是在前一个的基础上加 1,即 BLUE==3 };

深入理解C 中的mutable关键字

mutalbe的中文意思是“可变的,易变的”,跟constant(既C 中的const)是反义词. 在C 中,mutable也是为了突破const的限制而配置的.被mutable修饰的变量,将永远处于可变的状态,即使在一个const函数中. 我们知道,假如类的成员函数不会改变对象的状态,那么这个成员函数一般会声明成const的.但是,有些时候,我们需要在const的函数里面修改一些跟类状态无关的数据成员,那么这个数据成员就应该被mutalbe来修饰. 下面是个小例子: class ClxTest

【转载】理解C语言中的关键字extern

原文:理解C语言中的关键字extern 最近写了一段C程序,编译时出现变量重复定义的错误,自己查看没发现错误.使用Google发现,自己对extern理解不透彻,我搜到了这篇文章,写得不错.我拙劣的翻译了一下.(原文:http://www.geeksforgeeks.org/understanding-extern-keyword-in-c/)   我确定这篇文章对c语言的初学者会有很大的帮助,因为这将使他们更好更熟练的使用c语言.所以就让我先来说说extern关键字在变量和函数上的应用.最基本

深刻理解Java中形参与实参,引用与对象的关系

声明:本博客为原创博客,未经允许,不得转载!原文链接为http://blog.csdn.net/bettarwang/article/details/30989755 我们都知道,在Java中,除了基本数据类型之外,其他的都是引用类型,当它们作为函数参数时,传递的也是引用,通过引用可以改变对象的值,很多人便因此而忽略形参与实参,引用与对象的关系问题.废话不多说,先看下面一个例子: import java.util.*; public class Student { private String

深刻理解Java中final的作用(一):从final的作用剖析String被设计成不可变类的深层原因

声明:本博客为原创博客,未经同意,不得转载!小伙伴们假设是在别的地方看到的话,建议还是来csdn上看吧(原文链接为http://blog.csdn.net/bettarwang/article/details/26744661),看代码和提问.讨论都更方便. Java中final的作用主要表如今三方面:修饰变量.修饰方法和修饰类.以下就从这两个方面来解说final的作用.在文末从final及类的设计安全性出发,论述了Java中String为何要被设计成不可变类. 1.final修饰变量 fina