(转载)*a和*&a区别(c语言指针传值)

https://blog.csdn.net/weixin_42889479/article/details/81437659

此篇为复习考研专业课(数据结构)笔记,记录一个值得研究的问题。小哥我是为千百计算机考研大军中的一人,专业课数据结构,今天为大家分享一个有关于c语言指针传值的问题,其中夹带了许多个人理解,欢迎批评指正。

大家都知道指针的使用是c语言编程的基础核心,今天我们就来探讨一下传入*a与*&a的区别。

简单的说一下这两个东西:

*a :在定义变量时表示的是一个指针类型的变量,而在代码中(执行部分)则表示取出该指针所指向内容的值。
*&a:通常用于函数的传值,表示传入指针本身,不作复制(后面讲这句话的意思)。

首先,我用一段代码引出要讨论的问题,请看如下代码和执行结果:

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

void transformTrue(int *&point);
void transformCopy(int *point);

int main(){

    int *a,*b,i=0;

    transformTrue(a);
    transformCopy(b);
    for(i=0;i<5;i++) {a[i]=i;}
    printf("-------------------------------\n");
    printf("形参为*&a---->\n");
    for(i=0;i<5;i++){printf("%d  ",a[i]);}
    printf("\n");
    printf("-------------------------------\n");
    printf("形参为*a---->\n");
    for(i=0;i<5;i++) {b[i]=i;}
    for(i=0;i<5;i++){printf("%d  ",b[i]);}
    printf("\n");
    printf("-------------------------------\n");
    return 0;
}
void transformTrue(int *&point){
    point=(int*)malloc(5*sizeof(int));
}
void transformCopy(int *point){
    point=(int*)malloc(5*sizeof(int));
}


执行结果:

在这里插入图片描述

从执行结果我们看到,数组a的内容打印了出来,而数组b的内容没有打印出来,并且报出了一个数组越界的错误(也就是return -1073741819,意思是在通过指针取值的时候在内存中没有找到相应的地址,于是它就返回了一个负数)。

对于上面的代码,简单的说一下。我写了两个动态申请数组空间的函数:

void transformTrue(int *&point);
void transformCopy(int *point);

首先我们提一下天勤数据结构书中对这两种传值的解释:*a表示传入这个指针,通常用作变量的传地址,*&a表示传入指针本身,可以更改指针本身的值。其实对于这两个传参的理解,我们可以相对退一步的理解一下,我们可以对比于基本变量的传值和传址(如有这个概念还没理解的老铁,可以去看一下网上的其他帖子,这里就不做赘述了)。

看完上面的代码,我们会想到一个问题:都进行了数组动态空间的申请,为什么数组a正常的存入了值,而数组b却数组越界呢?

我们可以这样理解:
第一点,*a作为参数传入,那么在函数中便可以对a所指向的内存空间的值指直接进行修改;*&a作为参数传入,我们可以对指针本身这个数据,以及它所指向的数据进行修改。
第二点,对于在函数中的动态数组,其变量所占内存的生存周期等同于该函数的生存周期。
在main函数中,我们定义了两个全局的指针变量,*a、*b。

对于void transformCopy(int *point)函数,我们将b传入,对数组b进行动态空间的申请。但我们需要注意的是,传入函数的b是对全局变量b的一个复制,在函数中所有对b的更改操作,出了这个函数域便是无效的,即我们可以认为全局指针b没有作出任何修改(这里我们再补充一点,指针的空间动态申请便是一种对指针本身属性的修改,即我把它跟谁绑定了。例如简单的一个例子 int*a ;a++; 这相当于有将指针的值加一,然后便导致该指针指向了原本内存空间的下一个位置,这也是一种对指针本身修改的操作),即代码中,b相当于没有申请空间,所以会报内存溢出的错误。

相反的,对于函数void transformTrue(int *&point)函数,我们相当于把全局指针a传入了数组,函数里面对a的操作就是直接对全局指针a的操作,即此函数申请的内存空间是全局有效的,我们把函数写成如下这样,再看运行结果,便更加清晰了。

void transformTrue(int *&point){
    printf("transformTrue--->%d\n",point);
    point=(int*)malloc(5*sizeof(int));
}
void transformCopy(int *point){
    int i;
    point=(int*)malloc(5*sizeof(int));
    printf("transformCopy--->%d\n",point);
    for(i=0;i<5;i++){point[i]=i;}
    printf("在函数域内打印:");
    for(i=0;i<5;i++){printf("%d ",point[i]);}
    printf("\n");
}



运行结果:

猜你喜欢

转载自blog.csdn.net/lijinshanba/article/details/107372416