我刚开始讲指针,有点困惑。我知道&意味着一个变量的地址,*可以用在一个指针变量前面,以获得指针所指向的对象的值。但是当你使用数组、字符串或者使用变量的指针副本调用函数时,情况就不同了。很难看出其中的逻辑模式。
什么时候应该使用&和*?
我刚开始讲指针,有点困惑。我知道&意味着一个变量的地址,*可以用在一个指针变量前面,以获得指针所指向的对象的值。但是当你使用数组、字符串或者使用变量的指针副本调用函数时,情况就不同了。很难看出其中的逻辑模式。
什么时候应该使用&和*?
当前回答
当你声明一个指针变量或函数形参时,使用*:
int *x = NULL;
int *y = malloc(sizeof(int)), *z = NULL;
int* f(int *x) {
...
}
注意:每个声明的变量都需要自己的*。
当你想获取一个值的地址时,使用&。当您想读写指针中的值时,请使用*。
int a;
int *b;
b = f(&a);
a = *b;
a = *f(&a);
数组通常就像指针一样。当你在函数中声明一个数组形参时,你可以很容易地声明它是一个指针(它的意思是一样的)。当你将一个数组传递给一个函数时,你实际上是在传递一个指向第一个元素的指针。
函数指针是唯一不完全遵循规则的东西。你可以不使用&而获取函数的地址,也可以不使用*而调用函数指针。
其他回答
简单地说
&表示地址,你会看到在C语言中修改参数变量的函数占位符中,参数变量是按值传递的,使用&表示按引用传递。 *表示指针变量的解引用,即获取该指针变量的值。
int foo(int *x){
*x++;
}
int main(int argc, char **argv){
int y = 5;
foo(&y); // Now y is incremented and in scope here
printf("value of y = %d\n", y); // output is 6
/* ... */
}
上面的例子说明了如何使用引用传递来调用函数foo,与此比较
int foo(int x){
x++;
}
int main(int argc, char **argv){
int y = 5;
foo(y); // Now y is still 5
printf("value of y = %d\n", y); // output is 5
/* ... */
}
下面是使用解引用的示例
int main(int argc, char **argv){
int y = 5;
int *p = NULL;
p = &y;
printf("value of *p = %d\n", *p); // output is 5
}
上面说明了我们如何获得y的地址并将其赋值给指针变量p。然后我们通过将*附加到p的前面来解引用p,以获得p的值,即*p。
好吧,看起来你的帖子被编辑了…
double foo[4];
double *bar_1 = &foo[0];
看看如何使用&来获取数组结构开头的地址?以下
Foo_1(double *bar, int size){ return bar[size-1]; }
Foo_2(double bar[], int size){ return bar[size-1]; }
会做同样的事情。
是的,这可能相当复杂,因为在C/ c++中*被用于许多不同的目的。
如果*出现在已经声明的变量/函数前面,这意味着:
A) *提供对该变量值的访问(如果该变量的类型是指针类型,或者重载了*操作符)。 B) *具有乘法运算符的含义,在这种情况下,必须有另一个变量在*的左边
如果*出现在变量或函数声明中,则意味着该变量是指针:
int int_value = 1;
int * int_ptr; //can point to another int variable
int int_array1[10]; //can contain up to 10 int values, basically int_array1 is an pointer as well which points to the first int of the array
//int int_array2[]; //illegal, without initializer list..
int int_array3[] = {1,2,3,4,5}; // these two
int int_array4[5] = {1,2,3,4,5}; // are identical
void func_takes_int_ptr1(int *int_ptr){} // these two are identical
void func_takes_int_ptr2(int int_ptr[]){}// and legal
如果&出现在变量或函数声明中,通常意味着该变量是该类型变量的引用。
如果&出现在已经声明的变量前面,则返回该变量的地址
此外,您应该知道,当将一个数组传递给一个函数时,您总是必须传递该数组的数组大小,除非该数组是一个以0结尾的cstring (char数组)。
I was looking through all the wordy explanations so instead turned to a video from University of New South Wales for rescue.Here is the simple explanation: if we have a cell that has address x and value 7, the indirect way to ask for address of value 7 is &7 and the indirect way to ask for value at address x is *x.So (cell: x , value: 7) == (cell: &7 , value: *x) .Another way to look into it: John sits at 7th seat.The *7th seat will point to John and &John will give address/location of the 7th seat. This simple explanation helped me and hope it will help others as well. Here is the link for the excellent video: click here.
下面是另一个例子:
#include <stdio.h>
int main()
{
int x; /* A normal integer*/
int *p; /* A pointer to an integer ("*p" is an integer, so p
must be a pointer to an integer) */
p = &x; /* Read it, "assign the address of x to p" */
scanf( "%d", &x ); /* Put a value in x, we could also use p here */
printf( "%d\n", *p ); /* Note the use of the * to get the value */
getchar();
}
附加组件:在使用指针之前总是初始化它们。否则,指针将指向任何东西,这可能导致程序崩溃,因为操作系统将阻止您访问它知道不属于您的内存。但是简单地输入p = &x;,我们为指针分配了一个特定的位置。
首先理解指针是复杂的,你必须做练习和 多多练习。 不要指望在第一次迭代时就能抓住它,也不要指望读到解释 并认为你已经理解了,因为很可能你没有……
如果你想要的不仅仅是理论上的理解,我建议遵循这个 斯坦福CS107课程和练习, 至少遵循前三节课,其中解释了指针。
斯坦福CS107, Jerry Cain
另一个非常有价值的工具是gdb,在那里您可以进行交互 就像你用python写的那样。 用gdb你可以玩和实验:
(gdb) x pp.name
0x555555555060 <_start>: 0x8949ed31
(gdb) x &pp.name
0x7fffffffdc38: 0x55555060
(gdb) p &pp.name
$4 = (char **) 0x7fffffffdc38
(gdb) p *pp.name
$5 = 49 '1'