`
蒙面考拉
  • 浏览: 155685 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

指针深究

阅读更多

在说指向指针的指针之前,不得不说指向变量的指针。先看如下示例:

1. 指向整型指针

先看如下示例:

View Code
复制代码
 1 #include <iostream>
 2 using namespace std;
 3 
 4 int main()
 5 {
 6     int a = 5;
 7     int * p = &a;
 8     cout << "a  = " <<  a << endl
 9          << "&a = " << &<< endl 
10          << "*p = " << *<< endl 
11          << "p  = " << p << endl 
12          << "&p = " << &<< endl;
13 
14     return 0;
15 }
复制代码

运行结果如下:

我们先看下内存分配图:

由上图可以清楚的知道,输出整形变量a的值是5,指针变量p的值是001BFD18,而*号的作用是取值,*p即取地址001BFD18中存放的值,即5。

2. 指向字符型指针

先看如下示例:

View Code
复制代码
 1 #include <iostream>
 2 using namespace std;
 3 
 4 int main()
 5 {
 6     char a[] = "hello";
 7     char *= a;
 8 
 9     cout << "p = " << p << endl
10          <<"p = " << (void *) p << endl
11          << "*p = " << *<< endl;
12         
13         
14     for(int i = 0 ; i < 5; i++)
15     {
16         cout << "&a[" << i << "] = "<< (void *)&a[i] << endl;
17     }
18     return 0;
19 }
复制代码

运行结果图如下:

为什么整型指针p输出的是地址,而字符型指针输出的是字符串呢,字符型指针里存放的不是地址吗?

我们先看下内存分配图:

由上图可以看出,其实p中存放的是地址,只是当cout时,如果指针是字符型指针,那么会输出p中地址指向的内存中的内容(这里是h)直到遇到'\0'才结束。所以直接输出p时会输出hello,而将p强制转换为void *时输出的是地址。

3. 指向整型指针的指针

先看如下示例:

View Code
 1 #include <iostream>
 2 using namespace std;
 3 
 4 int main()
 5 {
 6     int a[5= {12345};
 7     int *= a;
 8     int **point = &p;
 9 
10     cout << "a = " << a << endl
11         << "p = " << p << endl
12         << "&p = " << &<< endl
13         << "point = " << point << endl
14         << "&point = " << &point << endl;
15 
16     for (int i = 0; i < 5; i++)
17     {
18         cout << "&a[" << i << "] = " << &a[i] << endl;
19     }
20     return 0;
21 }

运行结果图如下:

我们先看下内存分配图:

从上图可以看出point指针中存放的是p指针的地址,而p指针中存放的是a[0]的地址。所以*point和p是一样的,前者是取point指针中存放的地址(0025F754)中的值,即取地址0025F754中存放的值(0025F760),而后者就是0025F760,所以两者是等价的。**point和a[0]是等价的,前者可以写成*p,*p是取p中存放的地址(0025F760)中的值,即地址0025F760中存放的值1。由上可以得出*point等于p, **point 等于 a[0]。通过上图可以清晰的对付诸如*point++等问题。

4. 指向字符串指针的指针

先看如下示例:

 

View Code
 1 #include <iostream>
 2 using namespace std;
 3 
 4 int main()
 5 {
 6     char *a[] = {"Wel""To""China"};
 7     char **= a;
 8     for(int i = 0; i < 3; i++)
 9     {
10         for (int j = 0; j < strlen(a[i]) + 1; j++)
11         {
12             cout << a[i][j] << "\t" << (void *)&a[i][j] << endl;
13         }
14         cout << endl;
15     }
16     
17     for (int i = 0; i < 3; i++)
18     {
19         cout << "a[" << i << "] = " << (void *) a[i] << endl
20              << "&a[" << i << "] = " << &a[i] << endl;
21     } 
22 
23 
24     cout << "p  = " << p << endl
25          << "&p = " << &<< endl;
26     return 0;
27 }

 

运行结果图如下:

我们先看下内存分配图:

由上图可以看出a[0]中存放着'W'的地址,a[1]中存放着'T'的地址,a[2]中存放着'C'的地址,只是这些地址都是指向字符型的,所以直接cout的会输出字符串,而指针p中存放着a[0]的地址,所以*p等于a[0],都是获得'W'的地址,即00A778CCC,而**p和a[0][0]等价都获得了地址00A778CCC中存放的值W。由上图我们可以看到字符地址相隔1个字节,而指针地址相隔4个字节,这样就便于++运算,获得下一个地址了,列如++p后,p就指向a[1],p中存放的是a[1]的地址。

分享到:
评论

相关推荐

    对JavaScript中this指针的新理解分享

    一直以来对this的理解只在可以用,会用,却没有去深究其本质。这次,借着《JavaScript The Good Parts》,作了一次深刻的理解。(所有调试都可以在控制台中看到,浏览器F12键) 下面我们一起来看看这个this吧。 在我们...

    C语言数组和指针的问题一道非常值得深思的笔试题

    谁都不敢说自己的C/C++能有多精通,当然,工作一久,很多老毛病也就容易犯了,所以说,理论是真的很重要的,下面这道题,说实话还是挺基础的,虽然当时笔试被我给猜对了,但还是要深究一下具体的转换细节。...

    从汇编看C++系列前4篇

    当遇到较大较复杂的编程任务时,用 C 就会比较吃力,这个时候就应该使用 C++,因此有必要对 C++ 再深究一下。从汇编角度研究 C++,能看到最彻底最本质的东西,学习效果也最好,也更容易看清C++面向对象的底层实质。...

    总结IOS中nil、Nil、NULL和NSNull区别

    这就是在 C/C++ 中的空指针。 在 C 语言中, NULL 是无类型的,只是一个宏,它代表空。我们不研究 C++ 中的 NULL ,因为在 C++11 以后又有了新的定义,我们不深究。 这就是 C 语言中所谓的 NULL ( C++ 的定义比较...

    寒江独钓-Windows内核安全编程(高清完整版).part1

    13.1.4 NDIS包描述符结构深究 439 13.2 中间层驱动的入口与绑定 442 13.2.1 中间层驱动的入口函数 442 13.2.2 动态绑定NIC设备 443 13.2.3 小端口初始化(MpInitialize) 445 13.3 中间层驱动发送数据包 447 13.3.1 ...

    易语言-易语言目前最快的JSON解析 simdjson

    5. 由于解析的时候它会拷贝数据, 我不清楚有没有可能会产生 64-bit 的内存地址, 暂时就是指针到文本当 32-bit 用, 但心里很没底, 希望 eWOW64Ext 作者有空可以帮忙看一下... @shier2817 谢谢! 6. 库用的是 10.0....

    simdjson目前最快的 JSON 解析-易语言

    5. 由于解析的时候它会拷贝数据, 我不清楚有没有可能会产生 64-bit 的内存地址, 暂时就是指针到文本当 32-bit 用, 但心里很没底, 希望 eWOW64Ext 作者有空可以帮忙看一下... @shier2817 谢谢! 6. 库用的是 10.0....

    寒江独钓-Windows内核安全编程(高清完整版).part2

    13.1.4 NDIS包描述符结构深究 439 13.2 中间层驱动的入口与绑定 442 13.2.1 中间层驱动的入口函数 442 13.2.2 动态绑定NIC设备 443 13.2.3 小端口初始化(MpInitialize) 445 13.3 中间层驱动发送数据包 447 13.3.1 ...

    寒江独钓-Windows内核安全编程(高清完整版).part7

    13.1.4 NDIS包描述符结构深究 439 13.2 中间层驱动的入口与绑定 442 13.2.1 中间层驱动的入口函数 442 13.2.2 动态绑定NIC设备 443 13.2.3 小端口初始化(MpInitialize) 445 13.3 中间层驱动发送数据包 447 13.3.1 ...

    寒江独钓-Windows内核安全编程(高清完整版).part4

    13.1.4 NDIS包描述符结构深究 439 13.2 中间层驱动的入口与绑定 442 13.2.1 中间层驱动的入口函数 442 13.2.2 动态绑定NIC设备 443 13.2.3 小端口初始化(MpInitialize) 445 13.3 中间层驱动发送数据包 447 13.3.1 ...

    寒江独钓-Windows内核安全编程(高清完整版).part6

    13.1.4 NDIS包描述符结构深究 439 13.2 中间层驱动的入口与绑定 442 13.2.1 中间层驱动的入口函数 442 13.2.2 动态绑定NIC设备 443 13.2.3 小端口初始化(MpInitialize) 445 13.3 中间层驱动发送数据包 447 13.3.1 ...

    寒江独钓-Windows内核安全编程(高清完整版).part5

    13.1.4 NDIS包描述符结构深究 439 13.2 中间层驱动的入口与绑定 442 13.2.1 中间层驱动的入口函数 442 13.2.2 动态绑定NIC设备 443 13.2.3 小端口初始化(MpInitialize) 445 13.3 中间层驱动发送数据包 447 13.3.1 ...

    寒江独钓-Windows内核安全编程(高清完整版).part3

    13.1.4 NDIS包描述符结构深究 439 13.2 中间层驱动的入口与绑定 442 13.2.1 中间层驱动的入口函数 442 13.2.2 动态绑定NIC设备 443 13.2.3 小端口初始化(MpInitialize) 445 13.3 中间层驱动发送数据包 447 13.3.1 ...

    Windows内核安全与驱动开发光盘源码

    8.5.2 修改类驱动的分发函数指针 127 8.5.3 类驱动之下的端口驱动 128 8.5.4 端口驱动和类驱动之间的协作机制 129 8.5.5 找到关键的回调函数的条件 129 8.5.6 定义常数和数据结构 130 8.5.7 打开两种键盘端口...

    Windows内核安全驱动开发(随书光盘)

    8.5.2 修改类驱动的分发函数指针 127 8.5.3 类驱动之下的端口驱动 128 8.5.4 端口驱动和类驱动之间的协作机制 129 8.5.5 找到关键的回调函数的条件 129 8.5.6 定义常数和数据结构 130 8.5.7 打开两种键盘端口...

    基于SIP开发软件电话的一些资源(转自YOUTOO)

    最简单的方法,不用深究,直接再创建一个工程,同上述创建动态链接库方法,创建一个Win32静态链接库工程,直接编译,即可得到osipparser2.lib。 -----------------------------...

Global site tag (gtag.js) - Google Analytics