栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

小朋友学C语言(41):二级指针与多级指针

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

小朋友学C语言(41):二级指针与多级指针

一、二级指针

指向指针的指针是一种多级间接寻址的形式,或者说是一个指针链。通常,一个指针包含一个变量的地址。当我们定义一个指向指针的指针时,第一个指针包含了第二个指针的地址,第二个指针指向包含实际值的位置。

1.jpg

一个指向指针的指针变量必须如下声明,即在变量名前放置两个星号。例如,下面声明了一个指向 int 类型指针的指针:

int **p;

当一个目标值被一个指针间接指向到另一个指针时,访问这个值需要使用两个星号运算符,如下面实例所示。

例1:
#include int main (){    int a;    int *ptr;    int **pptr;

    a = 100;    
    ptr = &a;    
    pptr = &ptr;    
    printf("a = %dn", a);    printf("*ptr = %dn", *ptr );    printf("**pptr = %dn", **pptr);    return 0;
}

运行结果:

a = 100
*ptr = 100
**pptr = 100

可以进一步查看一下指针的地址。

例2:
#include int main(){    int a = 5;    int *ptr = &a;    int **ptr2 = &ptr;printf("%d,%d,%dn", **ptr2, *ptr, a);printf("%p, %p, %pn", *ptr2, ptr, &a);    printf("%p, %pn", ptr2, &ptr);    printf("%pn", &ptr2);    return 0;
}

运行结果:

5,5,5
0061ff0c, 0061ff0c, 0061ff0c
0061ff08, 0061ff08
0061ff04

从结果可以看出,**ptr2, ptr, 指向了a的值。一级指针ptr2和ptr则指向了a的地址。二级指针ptr2指向了一级指针ptr的地址, ptr2本身的地址则是0x0061ff04。

二、多级指针

既然有一级指针和二级指针,就有三级指针、四级指针、五级指针……
以三级指针为例,三级指针是“指针的指针的指针”,或者叫“指向‘指向指针的指针’的指针”。
因为多级指针不好理解,并且在编程时容易写错,所以建议尽量不要使用二级以上的指针。

三、指针指向NULL

经常看到给一级指针赋值为NULL的程序。比如下面的程序。

例3:
#include int main(){    int a = 5;    int *p = NULL;
    p = &a;    printf("%p,%p,%p,%d", &p, p, &a, *p);    return 0;
}

运行结果为:

0061ff08,0061ff0c,0061ff0c,5

这里定义了指针后,把指针指向NULL。这是一种安全的写法。NULL值为0,被放在内存里地址为0x0的区域。这是一块安全的内存区域。程序里p先指向了这块安全区域,然后再指向变量a的地址。
最后打印出来结果可以看出,p本身的地址为0061ff08;p所指向的地址即a的地址为0061ff0c;*p为a的值,即5。

字符’’的值也是0。
虽然值都是0,但意义不一样:
(1)0表示数字
(2)‘’表示字符串结束符。
(3)NULL表示空对象或空指针。

四、NULL内存区域不可读写

0x0这块内存区域是不可写的。NULL这个值在一些编译器连读取都不能。

下面用Codeblocks集成开发环境测试一下。

例4:
#include int main(){    int *p = NULL;    printf("%p, %pn", &p, &(*p));    printf("%dn", *p);    return 0;
}

运行结果:

0x6dfefc 00000000
Process returned -1073741819 (0xC0000005)

从运行结果可以看到,打印出了p指针本身的地址,为0x6dfefc;也打印出了NULL所在的地址00000000。但是,没有打印出p,而是报”Process returned -1073741819 (0xC0000005)”的错误。这里p就是NULL或0。可见在Codeblocks开发环境里NULL内存不能读取。

再看看二级指针的情况。

例5:
1 #include 2 3 int main()4 {5     int a = 5;6     int *ptr = &a;7     int **ptr2 = NULL;8     9     *ptr2 = ptr;10 11     printf("run okn");12 13     return 0;14 }

这个程序运行时报错。下面来分析一下原因:
第6行定义了一个1级指针ptr,接下来的程序里若出现ptr表示指针所指向的地址里的值。即ptr是一个1级指针,ptr是一个整数值。
第7行定义了一个2级指针ptr2,接下来的程序里若出现ptr2表示ptr2所指向的一级指针的地址,若出现ptr2表示2级指针ptr2所指向的一级指针指向的地址里的值。简单地说就是ptr2是一个二级指针,ptr2是一级指针,ptr2是一个整数值。
第9行ptr2 = ptr,表示一级指针指向一级指针,逻辑上没有问题。那么为什么会错呢?
原因在于第7行的ptr2 = NULL,这表示ptr2指向的地址为0x0,即ptr2 = 0x0。0x0是一个特殊的内存块,不能读写,要对他赋值*ptr2 = ptr,显然会出错。



作者:海天一树X
链接:https://www.jianshu.com/p/2b0cfdd02dd6


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/232476.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号