关于c中指针的一些理解****

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/z498596750/article/details/79236038

接触到一个指针,先不要想它指向哪里,而是把它当成一个变量,这个变量里面存放的值指向哪里

&取值符,一个变量前边加上它,就代表取该变量的内存地址。

*解指针符,例如:int a=10,   *(&a)取的就是该变量的内存地址中存放的内容。

例:int a=10;    int *p_a=&a;   int **p_p_a=&p_a;

定义一个整形变量a的值是10,定义一个指针p_a指向a的内存地址&a,定义一个指向指针的指针p_p_a指向p_a的内存地址&p_a(&p_a的内存地址中的值就是a的内存地址)。所以*p_a=10,**p_p_a=10;

定义一个整形变量并给他赋值,如:int a=10;  这时会在内存中随意找到一个空间,它保存的值是10。内存会有类似一系列的小空间,每个空间都有对应的地址,地址使用16进制的数字来表示(0x01)。如图(这里0x没有写):


像这样,定义的一个指针p就指向a所在的内存地址。这时,如果想通过指针来改变a的值,需要这样写,下面的 改变的是p指向的内存地址,而不是内存地址中的值。

举个例子(只是在c中会这样):

void numplus(int a){
    a++;
}
void main(){
    int a=1;
    numplus(a);
    printf("%d",a);
}
像上面的一段代码,最后的运行结果是a=1,和预想中的结果a=2不同,这是因为在调用numplus()函数时,系统会重新在内存中创建一个名为a的整形变量,并不是将我们之前定义的a传递进去,numplus()函数执行,新创建的整形变量自增, numplus()执行结束,自动销毁,此时新创建的变量a也跟着销毁,从始至终,之前的变量a都没有发生过改变,所以还是输出1。想要通过函数实现变量自增需要用到指针(也有其他方法,就是将返回类型改成int,再用a来接收),如下代码:

void numplus(int *p){
    (*p)++;
}
void main(){
    int a=1;
    numplus(&a);
    printf("%d",a);
}

像这样,a就会自增,这样调用numplus()函数时,会将a的内存地址也就是&a复制给numplus(),就会重新生成一个指针*p,指针*p指向&a,函数执行(*p)++,就是p指针指向的内存地址的值进行自增,函数执行结束后,新生成的*p指针就会销毁掉,可是a中的值也就是&a这个内存地址所存储的值已经发生改变,最后就会输出预期结果2.

再举一个例子:

定义一个数组,一个指针指向数组的第一个数据元素,定义一个方法使指针向后移一位,指向第二个元素。

void remove_p(int arr[],int *p){
    p=&arr[1];
}
void main(){
    int arr[5]={1,2,3,4,5};
    int *p=&arr[0];
    printf("%d\n",*p);
    remove_p(arr,p);
    printf("%d\n",*p);
}
发现结果输出的仍然是1,这是因为在调用函数时传递的是指针p,remove_p()函数会重新生成一个指针p, remove_p()函数执行改变的是新生成的指针p所指向的地址, remove_p()函数执行完毕,新生成的指针p就会被销毁,从始至终想要改变的指针p都没有发生任何改变,输出结果也就是1了。想要通过函数来改变的p需要像这样写(也可以改变返回值将函数生成的指针赋给p):

void remove_p(int arr[],int **p){
    *p=&arr[1];
}
void main(){
    int arr[5]={1,2,3,4,5};
    int *p=&arr[0];
    printf("%d\n",*p);
    remove_p(arr,&p);
    printf("%d\n",*p);
}

这样写,在调用remove_p()函数时,将p指针的内存地址传递给remove_p()函数(不是p指针,传递p指针会报错,**p是接收地址),这样remove_p()函数就会生成一个新指针,新指针指向p的内存地址,也就是说新指针的值就是p的内存地址,remove_p()函数执行,改变p的内存地址后,新指针销毁,但是p的内存地址已经被改变。


总结:

指针在函数这里的使用:

 在函数的形参为int *p时,想要调用函数,不需要定义指针(也可以定义),只需将变量的内存地址&a传递过去即可。

但是当一个指针指向的是一个数组中的某元素,想要调用函数改变指针时,函数形参为int **p时,这时参数只能接收

定义的指针所指向的内存地址也就是&p.而不能接收指针。也就是说,想在void函数方法中使用指针,只能传递指针

指向的内存地址,不能传递指针












猜你喜欢

转载自blog.csdn.net/z498596750/article/details/79236038