有人能解释一下这两者之间的区别吗?
#include <stdio.h>
void main() {
int a = 10;
int *p = &a;
*p = 11;
}
和
#include <stdio.h>
void main() {
int a = 10;
a = 11;
}
对于初学者,请注意,根据C标准,无参数的函数main应像一样声明
int main( void )
所给出的两个程序实际上是等效的,只是在第一个程序中,变量a
通过指向它的指针进行了更改
正如C标准中所写(6.2.5类型,第20页(
。。。指针类型描述一个对象,其值提供对被引用类型的实体的引用。
指针的这个属性在C中用于实现通过引用函数传递对象的机制。
考虑以下程序。
#include <stdio.h>
void f( int x )
{
x = 10;
}
void g( int *px )
{
*px = 10;
}
int main(void)
{
int x = 0;
printf( "Before calling f x = %dn", x );
f( x );
printf( "After calling f x = %dn", x );
x = 0;
printf( "nBefore calling g x = %dn", x );
g( &x );
printf( "After calling g x = %dn", x );
return 0;
}
程序输出为
Before calling f x = 0
After calling f x = 0
Before calling g x = 0
After calling g x = 10
正如您所看到的,在调用函数f
之后,main中声明的变量x
的值没有更改。问题是该函数处理main中声明的变量x
的值的副本。也就是说,函数参数是由main中声明的变量x
的值初始化的函数的局部变量。更改局部变量不会影响main中声明的变量x
。
但是,当变量x
通过指向它的指针的引用被传递给函数g
时,该函数能够通过取消引用传递的指针来改变主声明的原始变量x
。
还要记住,当您动态分配内存时,分配的对象就没有名称。您只有指向动态分配对象的指针。例如
int *px = malloc( sizeof( int ) );
因此,要更改分配的对象,还需要取消引用指针
*px = 10;
在这种情况下什么都没有,但假设您想调用一个函数,如果想编辑该函数内部FROM的值,则需要使用指针。
#include <stdio.h>
void set_a(int *p, int val)
{
*p = val;
}
int main()
{
int a = 2;
printf("a is: %dn", a); // a is 2
set_a(&a, 5);
printf("a is: %dn", a); // a is 5
}
这只是一个用例。例如,当使用堆分配时,您需要使用指针。
这两个程序具有相同的可观察效果。
使用指针更改可变对象的值的目的是什么?
一个好的用途是能够重用逻辑。写一次,用多次。
示例:
void foo(int *X, int *Y) {
/* some complex calculation */
*X = *X + *Y + 1;
*Y = *Y + *X + 2;
}
现在,您可以使用函数来执行以下操作:;复数";对不同变量的计算。您只需要正确地编写和测试它一次,然后就可以多次重用它。
int main() {
int a = 10, b = 20, c = 30, d = 40;
foo(&a, &b);
foo(&c, &d);
//...
}
演示