59

如果我将指针声明pint *p; 在主模块中,我可以p通过分配已经声明的另一个整数变量p = &a;where来更改包含的地址。a我现在想通过使用以下函数来更改地址:

void change_adrs(int*q)
{
    int *newad;
    q = newad;
}

如果我从主模块调用这个函数

int main()
{
    int *p;
    int a = 0;
    p = &a; // this changes the address contained by pointer p
    printf("The address is %u\n", p);
    change_adrs(p);
    printf("The address is %u\n", p); // but this doesn't change the address
    return 0;
}

地址内容不变。将函数用于同一任务有什么问题?

4

5 回答 5

67

在 C 中,函数参数是按值传递的。因此,您的参数会生成一个副本,并且会对该副本进行更改,而不是您希望看到的实际指针对象已修改。如果您想这样做,您将需要更改您的函数以接受指针到指针的参数并更改取消引用的参数。例如

 void foo(int** p) {
      *p = NULL;  /* set pointer to null */
 }
 void foo2(int* p) {
      p = NULL;  /* makes copy of p and copy is set to null*/
 }

 int main() {
     int* k;
     foo2(k);   /* k unchanged */
     foo(&k);   /* NOW k == NULL */
 }

如果您有幸使用 C++,另一种方法是更改​​函数以接受对指针的引用。

于 2012-11-17T13:44:50.520 回答
17

在 C 中,变量是按值传递的——指针的副本被传递给函数。改用另一个指向该指针的指针:

void change(int **p, int *someOtherAddress)
{
    *p = someOtherAddress;
}

int a = 1, b = 2;
int *p = &a;

printf("*p = %d\n", *p);
change(&p, &b);
printf("*p = %d\n", *p);

这打印

*p = 1
*p = 2
于 2012-11-17T13:45:15.323 回答
4

如果你想改变 C 函数中变量的内容,指针也是一种变量,你必须通过指针间接引用传递它,使用总是&地址和*取消引用运算符。我的意思*是在更改变量的值时始终使用运算符并在其前面。

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


void changeIntVal(int *x) {
    *x = 5;
}

void changePointerAddr(int **q) {
    int *newad;
    *q = newad;
}

void changePPAddr(int ***q) {
    int **dummy;
    *q = dummy;
}

int main() {
    int *p;
    int **pp;
    int *tempForPP;
    int a = 0;
    printf("\n The address pointing by p -> %p, pp -> %p, value of a -> %d ", p, pp, a);


    p = &a;
    pp = &tempForPP;
    printf("\n The address pointing by p -> %p, pp -> %p, value of a -> %d ", p, pp, a);

    changeIntVal(&a);        // ----
                             //    |---
    changePointerAddr(&p);   // ----  |---->  parts of what I mean
                             //    |---
    changePPAddr(&pp);       // ----

    printf("\n The address pointing by p -> %p, pp -> %p, value of a -> %d ", p, pp, a);

    return 0;

}
于 2017-06-04T10:32:54.733 回答
1

对于像 an 这样的原始数据类型int,双指针不是必需的。您可以直接写入int存储 的地址,将其地址视为被调用函数中的指针。这与char数组(“字符串”)不同,数组(“字符串”)指向的大小是可变的,因此在从被调用函数中更改它时,您必须使用另一个级别的间接。尝试这个:

void foo(int *oldVal)
{
    int newVal = 99;    // or whatever you want
    *oldVal = newVal;
}

int main(int argc, char *argv[])
{
    int someVal = 0;
    foo(&someVal);      // we send its address to foo()

    printf("someVal is now %d.\n", someVal);

    return EXIT_SUCCESS;
}
于 2014-04-11T08:19:58.427 回答
1

这不会改变实际值,p因为qin 函数是本地的,并且该函数中的更改不会反映在main所以传递地址p而不是p按值传递

在下面使用此语法

void change_adrs(int **q)
{
    int * otheraddess;
    *q = otheraddress; 
}

像这样打电话change_adrs(&p);

或者,您还有其他方法:更改函数的返回类型并捕获返回的地址。

int* change_adrs(int *q)
{
    int * otheraddess;
    q = otheraddress;
    return q; 
}


int main()
{
    p = change_adrs(p);
    return 0;
}
于 2012-11-17T13:45:00.150 回答