void指针、NULL指针和未初始化指针
一个指针可以被声明为void类型,比如void *x。一个指针可以被赋值为NULL。一个指针变量声明之后但没有被赋值,叫做未初始化指针。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
int *uninit; // int指针未初始化int *nullptr = NULL; // 初始化为NULLvoid *vptr; // void指针未初始化int val = 1;int *iptr;int *castptr;// void类型可以存储任意类型的指针或引用iptr = &val;vptr = iptr;printf("iptr=%p, vptr=%p\n", iptr, vptr);// 通过显示转换,我们可以把一个void指针转成// int指针并进行取值castptr = (int *)vptr;printf("*castptr=%d\n", *castptr);// 打印null和未初始化指针printf("uninit=%p, nullptr=%p\n", uninit, nullptr);// 不知道你会得到怎样的返回值,会是随机的垃圾地址吗?// printf("*nullptr=%d\n", nullptr);// 这里会产生一个段错误// printf("*nullptr=%d\n", nullptr); |
执行上面的代码,你会得到类似下面对应不同内存地址的输出。
|
2
3
|
iptr=0x7fff94b89c6c, vptr=0x7fff94b89c6c*castptr=1uninit=0x7fff94b89d50, nullptr=(nil) |
第1行我们声明了一个未初始化int指针。所有的指针在赋值为NULL、一个引用(地址)或者另一个指针之前都是未被初始化的。第2行我们声明了一个NULL指针。第3行声明了一个void指针。第4行到第6行声明了一个int值和几个int指针。
第9行到11行,我们为int指针赋值为一个引用并把int指针赋值为void指针。void指针可以保存各种其它指针类型。大多数时候它们被用来存储数据结构。可以注意到,第11行我们打印了int和void指针的地址。它们现在指向了同样的内存地址。所有的指针都存储了内存地址。它们的类型只在取值时起作用。
第15到16行,我们把void指针转换为int指针castptr。请注意这里需要显示转换。虽然C语言并不要求显示地转换,但这样会增加代码的可读性。接着我们对castptr指针取值,值为1。
第19行非常有意思,在这里打印未初始化指针和NULL指针。值得注意的是,未初始化指针是有内存地址的,而且是一个垃圾地址。不知道这个内存地址指向的值是什么。这就是为什么不要对未初始化指针取值的原因。最好的情况是你取到的是垃圾地址接下来你需要对程序进行调试,最坏的情况则会导致程序崩溃。
NULL指针被初始化为o。NULL是一个特殊的地址,用NULL赋值的指针指向的地址为0而不是随机的地址。只有当你准备使用这个地址时有效。不要对NULL地址取值,否则会产生段错误。
void指针、NULL指针和未初始化指针的更多相关文章
- c语言中较常见的由内存分配引起的错误_内存越界_内存未初始化_内存太小_结构体隐含指针
1.指针没有指向一块合法的内存 定义了指针变量,但是没有为指针分配内存,即指针没有指向一块合法的内浅显的例子就不举了,这里举几个比较隐蔽的例子. 1.1结构体成员指针未初始化 struct stude ...
- 指针专题6-空指针NULL和void指针
1 NULL指针 一个指针变量可以指向计算机中任何一块内存,不管该内存有没有被分配,也不管该内存有没有使用权限,只要把地址给他,他就可以指向.C语言没有一种机制保证指向内存的正确性,程序员必须自己提高 ...
- 在删除一个指针之后,一定将该指针设置成空指针(即在delete *p之后一定要加上: p=NULL)
在删除一个指针之后,一定将该指针设置成空指针(即在delete *p之后一定要加上: p=NULL)
- [错误记录_C] 还未给指针变量正确赋值的情况下,就使用它的值
错误的代码: 错误的结果: 错误原因分析: 在使用(1) 将pB,pC的值赋给pA的lchild和rchild时: 还未给指针变量pB和pC赋值,现在pB和pC中存的是个垃圾值 Note: (2)- ...
- c++ 虚函数多态、纯虚函数、虚函数表指针、虚基类表指针详解
静态多态.动态多态 静态多态:程序在编译阶段就可以确定调用哪个函数.这种情况叫做静态多态.比如重载,编译器根据传递给函数的参数和函数名决定具体要使用哪一个函数.动态多态:在运行期间才可以确定最终调用的 ...
- c++中多态性、dynamic_cast、父类指针、父类对象、子类指针、子类对象
c++多态性是依靠虚函数和父类指针指向子类对象来实现的.简单来说,父类中定义虚函数,父类指针指向子类对象,父类指针调用函数时调用的就是子类的函数. 父类没有定义虚函数,父类指针指向子类对象时,父类指针 ...
- Qt 智能指针学习(7种QT智能指针和4种std智能指针)
从内存泄露开始? 很简单的入门程序,应该比较熟悉吧 ^_^ #include <QApplication> #include <QLabel> int main(int arg ...
- C指针(4)——数据结构中指针的应用(非常重要)
5-1动态内存分配,分配的是堆内存的空间 分配内存函数 (都集中在库函数 stdlib.h 中) void *malloc (unsigned int num_bytes); //指定分配内存空间大 ...
- c++值传递,指针传递,引用传递以及指针与引用的区别
值传递: 形参是实参的拷贝,改变形参的值并不会影响外部实参的值.从被调用函数的角度来说,值传递是单向的(实参->形参),参数的值只能传入, 不能传出.当函数内部需要修改参数,并且不希望这个改变影 ...
随机推荐
- algorithm: heap sort in python 算法导论 堆排序
An Python implementation of heap-sort based on the detailed algorithm description in Introduction to ...
- 【暑假】[数学]UVa 1262 Password
UVa 1262 Password 题目: Password Time Limit: 3000MS Memory Limit: Unknown 64bit IO Format: %lld ...
- k-近邻分类的Python实现
参见<机器学习实战> # -*- coding:cp936 -*- #=========================================================== ...
- CF390-E. Inna and Large Sweet Matrix(区间更新+区间查询)
题意很好理解,不说了 题解就是每次把值压缩成一维,比如x上,这样就可以求出任意宽度的整个竖条的和. 如这张图,求的是s5-(s1+s3+s7+s9) 因为可以求出一整竖条和一整横条,我们可以求出是s2 ...
- Fragment回调顺序及getActivity()为NullPointerException解决方法
Fragment回调顺序 onAttach->onCreate->onCreateView->onActivityCreated ps:最后发现经常在Fragment里面getAct ...
- hdoj 2817 A sequence of numbers【快速幂】
A sequence of numbers Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Ot ...
- linux下Memcached安装以及PHP的调用
一:安装libevent 由于memcached安装时,需要使用libevent类库,所以先安装libevent 1.官网下载:http://libevent.org/ #wget https:/ ...
- 【不积跬步,无以致千里】Linux下启动Oracle服务和监听程序
oracle数据库是重量级的,其管理非常复杂,将其在linux平台上的启动和关闭步骤整理一下. 安装完毕oracle以后,需要创建oracle系统用户,并在/home/oracle下面的.bash_p ...
- 我的AndroidStudio设置
转载:http://stormzhang.com/devtools/2014/11/25/android-studio-tutorial1/ 官方下载有两个地方,均需要FQ. Android Deve ...
- Codeforces Round #319 (Div. 1) C. Points on Plane 分块
C. Points on Plane Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/576/pro ...