了解指针和内存地址

问题描述 投票:3回答:4
#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编程入门课程,并且难以理解其工作原理。

感谢您的帮助!

c pointers memory-address
4个回答
2
投票

按问题顺序排列事件:

int main()
{  

ab的声明以及值分配:

    int a = 2;
    int b = 7;

这是一个技巧,传递给参数int* a的地址实际上是b,而第二个参数则相反:

    b = g(&b , &a);

仅打印ab的值:

    printf("a = %d\n", a);
    printf("b = %d\n", b);

    return 0;
}

由于参数是指针,因此在此函数的范围内,对其所指向的变量所做的更改是永久性的:

int g(int *a, int *b) {

这里7 + 3 = 10,所以存储在a指向的地址中的值为= 10

    (*a) = (*a) + 3;

这里是2 * 10 - 2 + 5 = 23,所以存储在b指向的地址中的值为23

    (*b) = 2*(*a) - (*b)+5;

这里打印a = 10b = 23

    printf("a = %d, b = %d\n", *a, *b);

返回的值是10 + 23 = 33,因此对于b = g(&b, &a),将为b分配33的值,a已经是23,所以它保持这种状态:

    return (*a)+(*b); 
}

1
投票

使用'&',您将变量的地址提供给函数,而不是值。使用“ *”,您可以指定地址的值。

使用b = g(&b , &a);,将变量b和a的地址提供给函数。但是您可以使用'* a'访问b的地址,因为您以这种方式声明了该函数:int g (int * a, int * b)* a指向b变量的地址。* b指向变量的地址。

我认为让您感到困惑的是不同的变量名。

为了使您自己更轻松,您可以将声明更改为int g (int * b, int * a)如果您想更改它* b将指向b变量的地址,并且* a会指向您变量的地址。


1
投票

请记住,C传递所有函数参数按值-这意味着函数主体中的形式参数是内存中与函数调用中的实际参数不同的对象,并复制了实际参数的值形式参数。

对于任何要修改参数值的函数,必须将pointer传递给该参数:

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相同。

[我认为令您感到困惑的部分原因是,形式参数(ab)的名称和指针(ab)的名称都被翻转了-g:a指向[ C0],反之亦然。

main:b

0
投票

通过使用 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 ,您可以访问指针引用的对象。当指针引用*变量a和b时,您需要对这些变量进行操作。我认为相同的变量名称使您感到困惑

int
© www.soinside.com 2019 - 2024. All rights reserved.