Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C语言中传递指针地址与指针_C_Pointers - Fatal编程技术网

在C语言中传递指针地址与指针

在C语言中传递指针地址与指针,c,pointers,C,Pointers,我对这两段代码有点困惑: 版本1:(编译后给出警告) 输出: Address of a: 5770a18c Before: 5770a18c After: 5770a18d Address of a: cc29385c Before: cc29385c

我对这两段代码有点困惑:

版本1:(编译后给出警告)

输出:

Address of a: 5770a18c
Before: 5770a18c                                                                                                           
After: 5770a18d 
Address of a: cc29385c
Before: cc29385c                                                                                                           
After: cc293860
第2版:

int func(int **ptr2)
{
    *ptr2 += 1;
}

int main()
{
    int a = 5;
    int *ptr = &a;

    printf("address of a: %x\n", &a);
    printf("Before: %x\n", ptr);
    func(&ptr);
    printf("After: %x\n", ptr);
    return 0;
}
输出:

Address of a: 5770a18c
Before: 5770a18c                                                                                                           
After: 5770a18d 
Address of a: cc29385c
Before: cc29385c                                                                                                           
After: cc293860
如果我在通过引用传递时正确理解了C中的指针,那么我们正在创建一个指向该位置的指针。这允许我们通过解引用运算符更改指针所持有地址处的值

但是,如果我们想更改指针所持有的值,我们就使用指向指针的指针。我们传递指针的地址,并创建一个新指针来保存所述地址。如果我们想更改该值,我们可以使用解引用操作符访问指针(在别处定义)的值


希望我在正确的轨道上,但我正在努力想象版本1具体发生了什么。主要是,我想了解这两个程序在组成和输出方面的差异。我假设版本1仍然是指向指针的指针,但是为什么两个程序的递增值不同呢?如果版本1成功增加了ptr的值(我怀疑不是),为什么我找不到具有相同语法的代码?我想我错过了一些非常琐碎的事情。。。非常感谢您提供的任何帮助

根据您的输出,您似乎正在编译一个32位系统,其中地址和
int
大小相同

当您在类型为
int
的情况下增加
*ptr
处的值时,它只需加1

*ptr
解析为
int*
时,它将增加
sizeof(int)
,因为在这种情况下,当前地址的值是4字节长,因此,我们必须将地址增加
int
消耗的字节数,以便我们指向下一个int。请注意,只有在后续地址实际分配了内存时,这样做才有效。


通常,当被调用方需要修改要指向的地址时,您会传递一个
T**
,例如,被调用方执行
malloc()
,为指针分配空间。

&ptr
是指向指针的指针,但传递给
func()的是
是以实现定义的方式从
&ptr
转换而来的指向
int
的指针。然后,
*ptr2+=1
递增
int
,并将1添加到
ptr2
所指向的内容中(
main()
中的指针
ptr
,它最终与系统中的“int”具有相同的重新表示形式)

在版本2中,指向指针的指针被正确地传递到
func()
。因此,执行指针算术运算,并将
int
的大小添加到地址中

请注意,通过将类型错误的数据传递到
printf()
,调用了未定义的行为。打印指针的正确方法如下所示:

printf("Before: %p\n", (void*)ptr);

如您所见,将指针投射到
void*
并使用
%p
说明符。

在C中没有“按引用传递”,在第一个示例中,您传递了
int**
,但将其当作函数中的
int*
使用。在这两种情况下
func
都会增加
ptr2
指向的值,在这两种情况下,这都是指针的值
ptr
。第1种情况通常也会发出一条警告,提示将
int**
传递给需要
int*
的函数,您不应忽略该警告。最后,
%x
不是指针的正确格式说明符,因此
printf
在技术上调用UB(未定义的行为)。感谢您的回复,这些答案非常好,已经解决了我的主要问题。我注意到,如果我还将指向“a”的指针传递给func(),那么现在可以设置ptr2='a',给ptr调用方中a的地址位置。我猜如果我用提供的地址修改指针值,使用版本1是可以的?你能解释一下当被叫方执行内存分配时,为什么我们要传递ptr**vs ptr*?这与设置数据有关吗?我可能需要做一些刷新/进一步的阅读。C中的参数总是按值传递-如果我传递一个
int
,那么函数将收到一个值的副本。如果我传递一个
int*
,它将收到地址的副本。