c - 在 C 中使用双指针查询

标签 c pointers double-pointer

在大学里我们做了这段代码:

int cargaArreglo(int ** A);

int main(){

int * A = NULL;
int i = 0;
int dimension = cargaArreglo(&A);

for( i = 0; i < dimension; i++ )
     printf( "[%d]", A[i] );

free( A );
return 0;
}

int cargaArreglo(int ** A){

int i = 0;
char bandera = 's';
(*A) = malloc( 1*sizeof(int) );

while( bandera != 'n' ){
     printf( "Ingrese un numero" );
     scanf( "%d", &(*A)[i] );
     printf( "Desea seguir ingresando?" );
     i++;
     fflush( stdin );
     scanf( "%c", &bandera );
     if( bandera != 'n' )
     (*A) = realloc( (*A), (i+1)*sizeof(int) );
}
return i;
}

我们尝试加载一个动态数组,并无限制地添加值。代码工作得很好,但是在我们需要用双指针声明参数的函数中,是否存在将其转换为简单指针的任何可能性?我的意思是,老师说那是不可能的,因为没有双指针我不能改变全局变量的值。这让我混淆了对指针的尊重。

感谢您的宝贵时间!

PD:如果您发现我的英语有误,请告诉我,因为这对我的学习有很大帮助。

最佳答案

如果您不喜欢指向指针的指针,您始终可以修改函数的签名,以便它返回新的指针值以分配给 A,并通过指针设置维度值:

[...]
int dimension;
int * A = cargaArreglo(&dimension);
[...]


int * cargaArreglo(int * retDimension){
   int i = 0;
   char bandera = 's';
   int * B = malloc( 1*sizeof(int) );

   while( bandera != 'n' ){
        printf( "Ingrese un numero" );
        scanf( "%d", &B[i] );
        printf( "Desea seguir ingresando?" );
        i++;
        fflush( stdout ); /* fflush( stdin ) is UB */
        scanf( "%c", &bandera );
        if( bandera != 'n' )
           B = realloc( B, (i+1)*sizeof(int) );
   }
   *retDimension = i;

   return B;
}

I mean, the teacher said that is impossible, because without the double pointer I cant change the value of the global variable. This made me confuse respect to the pointers.

老师的意思是,当你在C中调用一个函数时,每个参数的一个临时副本被压入栈中,供函数内部使用。因此,如果您在被调用函数中更改参数的值,它不会在调用函数中更改回该值...例如,运行此代码:

void foo(int x, int * A)
{
   x = 6;
   A = NULL;
}

int x = 5;
int * A = &x;
printf("BEFORE x=%i A=%p &x=%p\n", x, A, &x);
foo(x, A);
printf("AFTER x=%i A=%p &x=%p\n", x, A, &x);

... 将打印出:

BEFORE x=5 A=0x2345678 &x=0x2345678
AFTER x=5 A=0x2345678 &x=0x2345678

...也就是说 foo() 实际上并没有改变调用函数中 x 或 A 的值,因为 foo() 只修改了传递给它的 x 的副本和 A 的副本,而不是原始变量。

但是,foo() 可以使用 A 指针(间接)修改调用函数的 x 的值,因为函数的 A 副本仍然指向调用函数的 x,因此您可以实现foo 这样做:

void foo(int * A)
{
   *A = 666;
}

int x = 5;
printf("BEFORE x=%i\n", x);
foo(&x);
printf("AFTER x=%i\n", x);

...你会得到这个输出:

BEFORE x=5
AFTER x=666

... 如果上面的内容对你有意义,那么指针到指针的情况实际上与上面的一样,除了 A 指向一个 int,而不是指向一个 int,它的值的类型指向的是一个指针:

void foo(int ** x)
{
    *x = NULL;
}

int y = 5;
int * x = &y;
int ** A = &x;
printf("BEFORE x=%p\n", x);
foo(A);
printf("AFTER x=%p\n", x);

... 会打印出:

BEFORE x=0x2345845  (actual value will vary depending on your computer)  
AFTER x=NULL

关于c - 在 C 中使用双指针查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37301901/

相关文章:

c - 查找给定两个字符串中的常见单词

c - 使用指针交换 int 数组值

c - 双点列表 C

c - 在c中动态分配双指针

c - Pro*C 将动态数组传递给 PL/SQL 过程

c - 获取协议(protocol)中方法 block 的 NSMethodSignature

pointers - 简洁的 nil 检查结构字段指针?

c - getint 和 getch

c - 如何将 char *a[] 转换为 char **?

c - 在函数调用期间将哪些值压入堆栈?