[英]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);
}
输出是:
a = 10, b = 23
a = 23
b = 33
我正在学习 C 编程入门课程,但无法理解这是如何工作的。
谢谢您的帮助!
对有问题的事件进行排序:
int main() {
a
和b
声明和赋值:int a = 2; int b = 7;
这是一个技巧,传递给参数
int* a
的地址实际上是b
,反之亦然第二个参数:b = g(&b , &a);
这里只打印
a
和b
值:printf("a = %d\\n", a); printf("b = %d\\n", b); return 0; }
由于参数是指针,因此在此函数范围内对它们指向的变量地址所做的更改是永久性的:
int g(int *a, int *b) {
在这里,取消引用指针(
*a
,在这些情况下不需要括号),意味着您现在正在使用存储在a
指向的地址中的值,因此7 + 3 = 10
,现在存储在指向的地址中的值由a
是= 10
:(*a) = (*a) + 3;
在这里,同样的事情,解引用指针,所以
2 * 10 - 2 + 5 = 23
,存储在b
指向的地址中的值将是23
:(*b) = 2*(*a) - (*b)+5;
这里打印
a = 10
和b = 23
,再次取消引用指针意味着您正在处理存储在它们指向的地址中的值:printf("a = %d, b = %d\\n", *a, *b);
返回的值是
10 + 23 = 33
,所以对于b = g(&b, &a)
,b
将被赋值为33
,a
已经是23
所以它保持这种状态:return (*a)+(*b); }
使用&
将变量的地址提供给函数,而不是值。 使用*
您可以访问地址的值。
随着b = g(&b , &a);
您将变量b
和a
的地址提供给函数。 但是您可以使用* a
访问b
的地址,因为您以这种方式声明函数: int g (int * a, int * b)
:
*a
指向b
变量的地址。*b
指向a
变量的地址。我认为不同的变量名称会让你感到困惑。
为了方便您自己,您可以将声明更改为int g (int * b, int * a)
如果您想更改它:
*b
将指向您的b
变量的地址和*a
将指向a
变量的地址。请记住,C 通过值传递所有函数参数——这意味着函数体中的形参与函数调用中的实参在内存中是一个单独的对象,并且实参的值被复制到形参中。
对于任何修改参数值的函数,您必须传递一个指向该参数的指针:
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
}
在上面的代码中,以下所有条件都为真:
ptr == &var
*ptr == var
因此,当您向表达式*ptr
写入新值时,它与向var
写入新值相同。
我认为让您感到困惑的部分原因是您的形式参数( 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
通过使用*
您可以访问指针引用的对象。 当指针引用int
变量 a & b 时,您对这些变量进行操作。 我认为相同的变量名让你感到困惑
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.