[英]Understanding pointers & memory address
#include<stdio.h>
int g(int *a, int *b);
int main()
{
int a = 2;
int b = 7;
b = g(&b , &a);
printf("a = %d\n", a);
printf("b = %d\n", b);
return 0;
}
int g(int *a, int *b)
{
(*a) = (*a) + 3;
(*b) = 2*(*a) - (*b)+5;
printf("a = %d, b = %d\n", *a, *b);
return (*a)+(*b);
}
The output is:输出是:
a = 10, b = 23
a = 23
b = 33
I'm in an Intro to C programming class and having trouble understanding how this works.我正在学习 C 编程入门课程,但无法理解这是如何工作的。
Thanks for the help!谢谢您的帮助!
Sequencing the events as presented in question:对有问题的事件进行排序:
int main() {
Declaration of
a
andb
and value assignment:a
和b
声明和赋值:int a = 2; int b = 7;
Here is a trick, the address passed to the parameter
int* a
is actually ofb
, and vice-versa on the second parameter:这是一个技巧,传递给参数
int* a
的地址实际上是b
,反之亦然第二个参数:b = g(&b , &a);
Here just printing values of
a
andb
:这里只打印
a
和b
值:printf("a = %d\\n", a); printf("b = %d\\n", b); return 0; }
Since the parameters are pointers, the changes made, in the scope of this function, to the variable addresses pointed by them are permanent:
由于参数是指针,因此在此函数范围内对它们指向的变量地址所做的更改是永久性的:
int g(int *a, int *b) {
Here, dereferencing the pointer (
*a
, the parentheses are not needed in these cases), means you are now working with the value stored in the address pointed bya
, so7 + 3 = 10
, now the value stored in the address pointed bya
is= 10
:在这里,取消引用指针(
*a
,在这些情况下不需要括号),意味着您现在正在使用存储在a
指向的地址中的值,因此7 + 3 = 10
,现在存储在指向的地址中的值由a
是= 10
:(*a) = (*a) + 3;
Here, the same thing, dereferencing pointers, so
2 * 10 - 2 + 5 = 23
, the value stored in the address pointed byb
will be23
:在这里,同样的事情,解引用指针,所以
2 * 10 - 2 + 5 = 23
,存储在b
指向的地址中的值将是23
:(*b) = 2*(*a) - (*b)+5;
Here printing
a = 10
andb = 23
, again, dereferencing pointers means you are working with the values stored in the addresses pointed by them:这里打印
a = 10
和b = 23
,再次取消引用指针意味着您正在处理存储在它们指向的地址中的值:printf("a = %d, b = %d\\n", *a, *b);
The returned value is
10 + 23 = 33
, so forb = g(&b, &a)
,b
will be assigned the value of33
,a
is already23
so it stays that way:返回的值是
10 + 23 = 33
,所以对于b = g(&b, &a)
,b
将被赋值为33
,a
已经是23
所以它保持这种状态:return (*a)+(*b); }
With &
you give the address of the variable to the function, instead of the value.使用
&
将变量的地址提供给函数,而不是值。 With *
you can access the value of an address.使用
*
您可以访问地址的值。
With b = g(&b , &a);
随着
b = g(&b , &a);
you give the address of the variable b
and a
to the function.您将变量
b
和a
的地址提供给函数。 But you can access the address of b
with * a
because you declare the function that way: int g (int * a, int * b)
:但是您可以使用
* a
访问b
的地址,因为您以这种方式声明函数: int g (int * a, int * b)
:
*a
points to the address of your b
variable. *a
指向b
变量的地址。*b
points to the address of your a
variable. *b
指向a
变量的地址。 I think the different variable names are what confuses you.我认为不同的变量名称会让你感到困惑。
To make it easier for yourself you could change the declaration to int g (int * b, int * a)
In case you want to change it:为了方便您自己,您可以将声明更改为
int g (int * b, int * a)
如果您想更改它:
*b
would point to the address of your b
variable and *b
将指向您的b
变量的地址和*a
would point to the address of your a
variable. *a
将指向a
变量的地址。Remember that C passes all function arguments by value - that means that the formal parameter in the function body is a separate object in memory from the actual parameter in the function call, and the value of the actual parameter is copied to the formal parameter.请记住,C 通过值传递所有函数参数——这意味着函数体中的形参与函数调用中的实参在内存中是一个单独的对象,并且实参的值被复制到形参中。
For any function to modify the value of a parameter, you must pass a pointer to that parameter:对于任何修改参数值的函数,您必须传递一个指向该参数的指针:
void foo( T *ptr ) // for any type T
{
*ptr = new_T_value(); // write a new value to the thing ptr points to
}
void bar( void )
{
T var;
foo( &var ); // write a new value to var
}
In the code above, all of the following are true:在上面的代码中,以下所有条件都为真:
ptr == &var
*ptr == var
Thus, when you write a new value to the expression *ptr
, it's the same as writing a new value to var
.因此,当您向表达式
*ptr
写入新值时,它与向var
写入新值相同。
I think part of what's making this confusing for you is that the names of your formal parameters ( a
and b
) and your pointers ( a
and b
) are flipped - g:a
points to main:b
and vice versa.我认为让您感到困惑的部分原因是您的形式参数(
a
和b
)和指针( a
和b
)的名称被翻转 - g:a
指向main:b
,反之亦然。
g:a == &main:b // I'm using g: and main: here strictly to disambiguate
*g:a == main:b // which a and b I'm talking about - this is not based on
// any real C syntax.
g:b == &main:a
*g:b == main:a
by using the *
you access the object referenced by the pointer.通过使用
*
您可以访问指针引用的对象。 As the pointers are referencing int
variables a & b you do the operations on those variables.当指针引用
int
变量 a & b 时,您对这些变量进行操作。 I think the same variable names are confusing you我认为相同的变量名让你感到困惑
int g(int *p1, int *p2)
{
(*p1) = (*p1) + 3;
(*p2) = 2*(*p1) - (*p2)+5;
printf("*p1 = %d, *p2 = %d\n", *p1, *p2);
return (*p1)+(*p2);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.