我想从Understanding functions and pointers in C
询问作者caf我意识到我不能在同一页面上问这个问题。
我仍然对使用&将指针的值传递给函数。我一直认为& q只是传递q的地址,如何将q的值转换为int sqp(int * x)?
答案 0 :(得分:2)
没有"翻译"。
你的功能
int sqp(int *x);
接受一个参数x
,其类型为int *
,即"指向整数"的指针。
所以,要调用它,你需要传递一个指向整数的指针,即整数的地址。
&
前缀运算符用于计算其参数的地址,因此您可以这样做:
int foo = 4711;
sqp(&foo);
使用变量sqp()
的地址调用foo
函数。
答案 1 :(得分:1)
使用:
sqp(&q);
您将q
的地址作为函数int sqp(int *x)
中的参数传递。
从现在开始,在此函数中,使用x
您将获得此地址。
使用*x
,您将获得内存中此地址中包含的值。
这就是我们如何模拟" C
中的pass by reference
,通过值将变量本身的地址作为函数中的参数传递。
答案 2 :(得分:1)
就像你说的那样&q
将变量q的内存地址传递给函数,所以我们发送给函数的只是q
的地址。该函数不需要翻译任何值,因为它直接访问原始值,因为它具有存储在指针x
中的地址,并且每次使用*x=7;
执行*
时都会x
你取消引用一个变量,这意味着它没有修改变量x
,而是修改{{1}}指向的任何内容。
答案 3 :(得分:1)
如果通过引用调用,则传递一个地址,以便可以通过引用地址(即引用)进行更改,如果您在参数中传递地址,则应该有一些指向该地址的机制。指针是某种东西指向地址所以在调用时如果已经传递了地址,则必须使用定义中的指针指向它。 示例
calling(&a); //passing address
void calling(int *b) //Pointing to address of 'a' via pointer 'b'
{
//some code
}
答案 4 :(得分:0)
传递参数有两种方法。 传递价值和传递参考。
也许您通常使用按值传递。
#include <stdio.h>
void foo(int i)
{
printf("[foo] `i` was %d\n", i);
i++;
printf("[foo] Now `i` is %d\n", i);
}
int main()
{
int i = 0;
printf("[main] `i` was %d\n", i);
foo(i);
printf("[main] Now `i` is %d\n", i);
}
输出为:(live example)
[main] `i` was 0
[foo] `i` was 0
[foo] Now `i` is 1
[main] Now `i` is 0
是的,i
的{{1}} 未已更改!为什么呢?
因为main()
按值传递 。运行i
时,会复制foo(i)
的值,i
会使用副本,而不是原始foo
。所以它不能被改变。
但是,您已经看到了更改参数的函数 - 例如,i
。
scanf
怎么改变?因为int main()
{
int i = 0;
scanf("%d", &i); /* `i` is changed!! */
}
使用 pass-by-ref 。看看这个例子。
scanf
输出为:(live example)
#include <stdio.h>
void foo(int *pi)
{
printf("[foo] `i` was %d\n", *pi);
(*pi)++; /* please be careful ^o^ */
printf("[foo] Now `i` is %d\n", *pi);
}
int main()
{
int i = 0;
printf("[main] `i` was %d\n", i);
foo(&i);
printf("[main] Now `i` is %d\n", i);
}
怎么可能?因为我们传递了[main] `i` was 0
[foo] `i` was 0
[foo] Now `i` is 1
[main] Now `i` is 1
的指针,而不是i
的副本。 i
的指针为foo
,因此可以访问i
所拥有的i
。我们称之为传递参考。
我希望它可以帮到你!
答案 5 :(得分:0)
稍微缩短相关问题答案的例子:
void sqp(int *x) {
*x = 10;
}
void foo() {
int value = 42;
sqp(&value);
}
所以sqp是一个想要通过参数返回数据的函数,这意味着它必须知道写入的位置。此信息是指针 - 要使用的内存地址。当传递C语言时,不会自动传递指针,但像sqp(value);
这样的语句(如果编译器由于不兼容的类型而不禁止)将传递该值,在本例中为42。然后sqp会看到42并将其解释为地址并尝试写入内存位置42,这很可能不是数据所在的位置。
现在问题是编译器为什么不能自己进行演绎。该函数需要一个指向int的指针,我们提供一个int,因此可以自动推导出来。
我认为至少有两个不做扣除的原因
&
告诉读者我们传递地址并且值可能会更改void *
的函数,编译器可能无法清除是否已经提供指针时是否需要额外的级别。答案 6 :(得分:0)
是的,&q
是q
的地址。 q
的值未被“翻译” - 只是如果您的地址为q
,则可以使用该地址执行的操作之一是访问对象q
本身。
答案 7 :(得分:0)
因此,让我们再次查看sqp
函数定义:
int sqp( int *x ) { ... }
C中的声明基于表达式的类型,而不是对象;如果您有一个指向名为x
的整数的指针,并且您想要访问指向的整数值,则使用一元x
运算符取消引用 *
,像这样:
int y = *x;
表达式的类型 *x
为int
,因此变量 x
的声明写为
int *x;
当你听到某人使用短语&#34;声明模仿使用&#34;时,这就是他们的意思。
当我们将该函数称为
时y = sqp( &q );
表达式 &q
生成q
的地址,表达式的类型为int *
。 x
中的参数sqp
会收到该地址值。
因此,*x
中的表达式sqp
等同于调用函数中的表达式q
;两个表达式都引用内存中的同一个对象,并且都计算为相同的值。同样,x
中的表达式sqp
等同于调用函数中的表达式&q
;两者都将评估q
的地址。