1

在研究双指针时,普遍的共识似乎是当想要更改任何变量的值并在从函数返回时保留新值时,需要传入其指针值。

当已经使用指针时,需要传入一个双指针。

以下示例处理代码主要部分中的指针,将相同的指针传递给函数,更改其值并且新值在 main 中可见。

根据我阅读的内容,应该需要一个双指针,否则新值在 main 中将不可见。

如果这确实有效,那么如何修改它以显示需要双指针?

void func1(int *z)
{
(*z)++;
printf("z=%d\n", *z);
}   


int _tmain(int argc, _TCHAR* argv[])
{

int x = 100;
int *y = &x;
printf("y=%d\n", *y);
func1(y);
printf("y=%d\n", *y);
return 0;
}
4

5 回答 5

3

如果您要更改 y 指向的内容,则需要一个指向指针的指针,例如:-

static int blah = 42;
void func1(int **z)
{
(*z) = &blah;
printf("z=%d\n", *(*z));
}   

int _tmain(int argc, _TCHAR* argv[])
{

int x = 100;
int *y = &x;
printf("y=%d\n", *y);
func1(&y);
// y does not point to x anymore;
printf("y=%d\n", *y);
return 0;
}

在您的原始文件中,您正在更改 x,在此您将单独留下 x 并更改指针 y。

通常,您不会经常使用这些(您会不时使用它们),但更一般地说,指向指针的指针是一种更有趣的类型。

所以...

typedef struct 
{
   int *y;
} Z;

void f(Z *z)
{
  z->y = &blah;
}

void main()
{
  int x;
  Z a;
  a->y = &x;
  f(&a);
}

所以这实际上是同一件事,但是现在您使用结构来保存指针,并且您将结构的指针作为“指向指针的指针”传递,但现在它是指向包含指向指针的结构的指针一个整数。

但是你命名的东西更有趣一点:-

typedef struct 
{
  char *name;    
} Person;

static char* default_name = "blah";
void set_default_name_of_person(Person* person)
{
   person->name = default_name;
}

void main()
{
   Person person;
   set_default_name_of_person(&person);
}

现在您的代码开始看起来像您实际编写的内容。(除了这有点人为的例子)

于 2014-05-20T02:43:35.447 回答
0

指针很简单。只需将其视为一种地址。

有一个盒子。这个盒子有一个号码牌,上面写着 1-101。

方框是变量,车牌是指针,1-101是实际地址(抽象概念)。

我可以给你盒子,你可以用纸填满它,但我也只能给你看车牌,你可以伸手去填。

假设有一个带有“pp1-100”的车牌,您找到了车牌架,但它是另一个带有“p1-100”的车牌。你再次找到持有人,可以找到盒子。

这是“指向指针的指针”。


为什么我们需要双/三/四指针?因为我们想要它,出于各种原因(但谁在乎呢?)。

于 2014-05-20T02:47:18.417 回答
0

首先 - 说“指向指针”更清楚,因为“双指针”可能是double *

假设T是某种类型,你有:

T t;
func( &t );

为了func能够改变t,它必须知道的地址t。对象的地址是指向该对象的指针(这是术语指针的定义)。

所以函数签名必须是:

func( T *t_ptr )

在您的示例T中是int. 也许您对T已经是指针类型的示例感到困惑。指针类型没有什么“魔法”。int *和是类型int **int ***就像int. 相同的规则适用于所有这些。

如果Tint *,那么函数签名必须看起来像func( int **t_ptr_ptr ),以此类推。

于 2014-05-20T02:31:33.797 回答
0

如果将局部变量的地址分配给单个指针,它仍然可以工作。所以基思尼古拉斯的开场白很有意义,应该被接受为一个有效的答案。如果您需要更改原始地址中的值,则需要一个指针,但如果您通过更改位置本身来更改值,则需要指向指针的指针。您应该了解您正在按值传递指针,因此函数堆栈具有该指针变量(及其值)的副本。通过取消引用 main 指针变量的副本,原始变量的值会发生变化,因为它是原始变量地址的副本。但是,如果您将该 ponter 的副本指向不同的值,它将不会得到反映。通过取消注释 1 和 2(一次一个)来运行下面的代码以观察差异。

#include <stdio.h>
void func1(int *z)
{
    int k=11;

//*z=k;   //1
//z=&k;    //2
printf("z=%d\n", *z);
}   


int main (int argc, char* argv[])
{

int x = 100;
int *y = &x;
printf("y=%d\n", *y);
func1(y);
printf("y=%d\n", *y);
printf ("%d",x);
return 0;
}
于 2022-02-24T19:55:15.613 回答
-1

您已使用该函数更改 的值x,也称为*y

您看到的代码片段并没有尝试更改 的值x,而是实际上更改了 的值,y以便y在函数调用之后指向不同的东西。为了让函数改变 的值y,它需要一个指向 的指针y。因为y已经是一个指针,所以你最终会得到一个指向指针的指针。

这是您重写的代码以更改y指向的内容,以便在函数调用之后,y指向w并且 printf 显示333.

void func1( int **yptr, int *wptr )
{
    *yptr = wptr;
}

int main( void )
{
    int x = 100;
    int w = 333;

    int *y = &x;
    func1( &y, &w );
    printf( "*y=%d\n", *y );

    return 0;
}
于 2014-05-20T03:01:10.520 回答