指针解析(一)(原)
指针这个话题好沉重,思量了好久,不知道如何下笔?下笔的时候手好抖啊,各位大牛看到我这只小菜鸟写的东东可能会笑掉大牙,但是,不管了!我要写下来!!!这东东确实太重要了,无数人对其折腰,无数的bugs隐匿于此。对它是又爱,又痴,又疼,又牙痒痒。有些看官以为我会写“又恨”,说实话,我和指针无仇,我敬佩它,崇拜它。它要是女生,我立马娶它。
我想指针的话题应该可以分成以下几个部分:
1. 指针的基本内容及应用
2. 指针与数组的联系与区别
3. 函数指针
4. 智能指针
就先以上四部分内容吧,我的能力也就知道这些了。各位大牛看过之后,想补充的可以发表评论。写的差的,可以咆哮一下,我很能接受。因为大家看了肯定要花时间,花了时间之后看到一篇烂文,我也觉得不好意思。
1. 指针的基本内容及应用
(一)基本内容
说到指针,我们立马想到这东西和地址有关。说到地址,我们会联想到内存。思维正常点应该可以往这方面联想。计算机内存由很多很多位(bit)组成,这些位上放的不是1,就是0。例如:100010010101110%……&&%¥,我靠,这个东西鬼看的懂啊。所以就要划分字节(byte),每个字节包含八个位,可以表示:0~255。可是这也不够用啊,太小了。于是,出现了字(word),一般由两个字节组成。
现在你可能会问,划分成这样也白搭啊。我也不知道这是要干嘛的(”100010010101110%……&&%¥“),也不知道这如何才能娶到?首先,坦白讲,我也不知道这是干嘛的。例如以下代码:
int a = 100;
float f = 2.11;
这些值在内存中是由0和1组成,我们不能通过检查位来检查类型。必须要放在程序中来它的实际使用方式,再来确定类型问题。
内存的事情唠叨完了,可以说地址了。大家的家里都有门牌号,这样我们在网上买东西,快递就可以寄到我们家里。同样,我们在程序定义一个变量,不是声明哦!这个变量在内存中就有一席之地,它在内存里面就是有一个位置给它,组织上给它分了一个地址。我们通过地址来找这个变量,当然,期间也是经历千辛万苦,现在我不想扯那些os的东西在里面。地址长什么样子呢?可以通过以下代码和图片显示:
#include <iostream>
int main()
{
int a = 100;
int *pa = &a;
std::cout << "这是a的值:" << a << std::endl;
std::cout << "这是a的地址:" << pa << std::endl;
return 0;
}
程序运行的结果:
看到了吧,0x0016FCEC,这是“a = 100”在内存中地址。具体这个地址在内存条的中部,前部,尾部,这个我就不知道了。“0x“代表了十六进制,0016FCEC说明了总共有32位,4个字节,2个字。此时,我发现了两个奇怪的符号:”&“和”*“。以下代码中解释:
int a = 100;
int *pa = &a; // *pa表示int类型的指针,*表示间接寻址或间接引用运算符
// &表示获取值的地址的地址运算符
如图:
(二)基本应用
① 指针,间接访问和左值
以下用代码显示:
int a = 100; // a的左值为100
int *pa = &a; // pa的左值为a的地址
int b = *pa - 10; // b的左值为90,*pa是对pa指针的解引用,代表a的值
来点诡异点的,”*&a = 100“这是神马意思呢?答案应该是和”a = 100“相同。我们分析以下,”&a“是产生a的地址,这是一个指针常量。”*(&a)“,应该看得比较的清楚。”*“解引用了,表示访问操作数所表示的地址。
接下来,我们来看看指针的指针。这个说起来有点拗口!看以下的代码吧:
#include <iostream>
int main()
{
int a = 100;
int *pa = &a;
int **ppa = &pa; // 这个就是指针的指针。二级指针
std::cout << "这是a的值:" << a << std::endl;
std::cout << "这是a的值:" << *pa << std::endl;
std::cout << "这是a的值:" << **ppa << std::endl;
std::cout << "这是a的地址:" << pa << std::endl;
std::cout << "这是pa的地址:" << ppa << std::endl;
return 0;
}
程序运行的结果:
② 指针表达式
是该来点脑力训练了!
char ch = 'a';
char *pch = &ch;
有以下几个问题:
1. &ch 代表什么?
2. pch 代表什么?
3. &pch 代表什么?
4. *pch 代表什么?
5. *pch + 1 代表什么?
6. *(pch + 1)代表什么?
7. ++pch 代表什么?
8. *++pch 代表什么?
9. *pch++ 代表什么?
10. ++*pch 代表什么?
11. (*pch)++ 代表什么?
12. ++*++pch 代表什么?
13. ++*pch++ 代表什么?
这几个问题来源于《C和指针》中指针部分的内容。
③ 未初始化,非法指针
int *a;
....
*a = 12;
看出上面的错误了吗?当你将这段代码敲进电脑之后,执行一下是不是以下这样呢?
这就是我们在使用指针的时候,非常容易犯下的错误。未初始化指针,就拿来使用了。结果就。。。。解决这个问题的方法很简单,使用的时候,先定义,非声明,后使用。
时间有点晚了,没有涉及的内容下一篇在慢慢讲来。睡觉去了。。。
参考文献
1. 《C语言程序设计》
2. 《C和指针》
3. 《C专家编程》