指针变量(变量)的直接引用和间接引用


// Tip:

// “指针所指向的内存空间发生了改变”这句话理解起来可能会出现歧义,①内存空间的内容发生改变 ②内存空间的地址发生改变,结合语境理解,看指针的值是否发生了改变,如果指针值被改变则是第二种含义;

// 指针的值即指针指向的内存空间也就是指针指向的地址,指针的值改变即指针指向的地方从一块内存空间变成了另一块内存空间

// 指针变量也是变量,对于变量往函数中传递有两种方法:直接引用(传值)和间接引用(传地址),直接引用不影响主函数中的变量的值,间接引用可以改变主函数中的变量的值,这句话同样适用于指针加以理解

// 一个地址可以被多个指针所指向。在C语言中,多个指针可以指向同一个地址,这些指针可以是同一类型的指针,也可以是不同类型的指针。这种情况下,当通过任何一个指针修改这个地址上的值时,其他指向该地址的指针所指向的值也会被修改。这种行为有时候也被称为指针别名(pointer aliasing)。在一些情况下,指针别名会导致意外的结果,因此在编写程序时需要特别小心。

// 术语:在C语言中,指针是用来存储地址的变量,因此一个地址可以被多个指针所指向。在你的代码中,传入fun1函数的是指向指针的指针,也就是说fun1函数中对指针的修改将直接影响到main函数中指针的值。而在fun2函数中,传入的是指针,所以fun2函数对指针的修改只是修改了指针本身所指向的内存空间,不会对main函数中的指针产生影响。在fun2函数中,如果想要对main函数中指针所指向的内存空间进行修改,需要使用指针的间接引用(即通过*p来访问指针所指向的内存空间)。

// 人话:例如这个函数(fun1),我在main function中,定义了一个指针变量并且给它分配内存空间后,再把它传入fun1函数,后对传进来的指针重新进行内存分配,是不是相当于在子函数中重新定义了一个指针,开始它指向的地址是和主函数中定义的指针所指向的地址,然后对子函数中的指针重新进行内存分配的时候,是不是我只对子函数中相当于新定义的指针给它指向的内存空间进行了改变(指向另一块内存空间),而实际在主函数中定义且分配空间的指针所指向的内存空间始终都是同一块内存空间吗?答:是 

#include <stdio.h>
#include <stdlib.h>

#define num  4
#define size 2

// 直接将指针传入fun1,在fun1中对指针重新分配空间后,主函数仍指向同一块内存空间,只相当于在fun1中重新定义了一个和主函数中指针指向内存空间相同的指针,而在fun1函数中对这个重新定义的指针分配内存空间,不会导致主函数中定义的指针指向的内存空间发生变化(指向另一块内存空间)。
void fun1 (int*** p)    // Direct Refercencing Address
{
    p = (int***)malloc(num * sizeof(int**));
    for (int i = 0; i < num; i ++ )
    {
        printf("blockNum: %d\n", i);
        p[i] = (int**)malloc(size * sizeof(int*));
        for (int j = 0; j < size; j ++ )
        {
            p[i][j] = (int*)malloc(size * sizeof(int));
            for (int k = 0; k < size; k ++ )
            {
                p[i][j][k] = i;
                printf("%d ", p[i][j][k]);
            }
            printf("\n");
        }
    }   
}


// 在fun2函数中是通过间接引用的方法,就是将在主函数中定义的指针的地址(指向指针p的指针)传进fun2函数,而在fun2函数中,就可以通过对这个地址(指向主函数中定义的指针p的指针)的间接引用来实现对主函数中定义的指针指向的内存空间进行修改,即重新分配使他指向另一个内存空间。

// 尽管p(主函数中定义的)是一个三级指针,但是它仍是一个指针,三级或四级只是修饰它(指针)的定语,所以我们可以称呼指向p的指针为指向指针的指针,而不用费力说它(指向p的指针)是什么指向指向...指向int类型的指针...的指针的指针。

void fun2 (int**** p)   // Indirect Refercencing Address
{
    *p = (int***)malloc(num * sizeof(int**));
    for (int i = 0; i < num; i ++ )
    {
        printf("blockNum: %d\n", i);
        (*p)[i] = (int**)malloc(size * sizeof(int*));
        for (int j = 0; j < size; j ++ )
        {
            (*p)[i][j] = (int*)malloc(size * sizeof(int));
            for (int k = 0; k < size; k ++ )
            {
                (*p)[i][j][k] = i;
                printf("%d ", (*p)[i][j][k]);
            }
            printf("\n");
        }
    }   
}



int main ()
{
    int*** p = (int***)malloc(sizeof(int**));

    printf("%x\n", p);

    // fun1(p);
    fun2(&p);

    printf("%x", p);

    return 0;
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值