指针解析(一)(原)

    指针这个话题好沉重,思量了好久,不知道如何下笔?下笔的时候手好抖啊尴尬,各位大牛看到我这只小菜鸟写的东东可能会笑掉大牙吐舌笑脸,但是,不管了!我要写下来恶魔!!!这东东确实太重要了,无数人对其折腰,无数的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;
}

程序运行的结果太阳

d460a796230fe0ee4bc42eba682f551a

    看到了吧,0x0016FCEC,这是“a = 100”在内存中地址。具体这个地址在内存条的中部,前部,尾部,这个我就不知道了。“0x“代表了十六进制,0016FCEC说明了总共有32位,4个字节,2个字。此时,我发现了两个奇怪的符号:”&“和”*“。以下代码中解释:

int a = 100;    
int *pa = &a;    // *pa表示int类型的指针,*表示间接寻址或间接引用运算符
                    // &表示获取值的地址的地址运算符

如图太阳

c72149730c7f2e733594b2e0732d68d0

(二)基本应用

    ① 指针,间接访问和左值

    以下用代码显示:

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;
}

程序运行的结果太阳

6c39a69502d9b1ee87a8a14b70a39b4e

② 指针表达式

    是该来点脑力训练了吐舌笑脸

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;

    看出上面的错误了吗?当你将这段代码敲进电脑之后,执行一下是不是以下这样呢?

1391ef2ef79a913e2a912a532690e377

    这就是我们在使用指针的时候,非常容易犯下的错误。未初始化指针,就拿来使用了。结果就破碎的心。。。。解决这个问题的方法很简单,使用的时候,先定义,非声明,后使用。

    时间有点晚了,没有涉及的内容下一篇在慢慢讲来。睡觉去了沉睡的弯月。。。

    第二篇的链接吐舌笑脸

参考文献

1. 《C语言程序设计》

2. 《C和指针》

3. 《C专家编程》

posted @ 2012-02-26 02:06  云端小飞象cg  阅读(2241)  评论(16编辑  收藏  举报