-1

我有一个简单的问题。我是 C 中指针的新手,我不明白为什么这是有效的,我可以更改指针的值

int main()
{
    int x = 7;
    int *aptr = &x;
    printf("%d",*aptr);
    *aptr = 21;
    printf("%d",*aptr);
}

但这不会打印任何数字

int main()
{
    int x = 7;
    int *aptr = 21;
    printf("%d",*aptr);
}

感谢帮助!

4

4 回答 4

1

int *aptr = 21;不存储21*aptr. 在=声明中使用时,它为被声明的事物(即aptr)设置初始值,而不是为用于声明(*aptr)的“表达式图片”设置初始值。

在 C 声明中,我们使用某种图片来描述类型。通常,在类似 的声明中,给出了我们将用作. 例如,says将是 an ,因此它声明为指向 an 的指针。另一个例子是说将是一个,所以它声明是一个数组。请注意,这些是声明, not or ,因此,当给定初始值时,它是用于初始化, not or 。int declaratordeclaratorintint *foo*foointfoointint foo[3]foo[i]intfoointfoo*foofoo[i]foo*foofoo[i]

21不是指针的正确值,因此编译器会抱怨。(可以使用强制转换将整数转换为指针,但这是一个特殊用例,需要确保整数表示 C 实现中可用的地址。)

于 2021-11-23T18:55:25.133 回答
1

虽然其他人为您的问题提供了正确答案,但获得该答案的最佳方法是让编译器告诉您问题所在。当您使用 gcc(大多数 Linux 机器上的默认编译器)编译程序时,您会得到:

$ gcc -o prog prog.c
prog.c: In function ‘main’:
prog.c:6:17: warning: initialization of ‘int *’ from ‘int’ makes pointer 
from integer without a cast [-Wint-conversion]
    6 |     int *aptr = 21;
      |                 ^~

...这基本上就是@EricPostpischil 告诉你的:-)

微软的 Visual C++ 也会说类似的话(godbolt.org)。

因此,阅读编译器生成的警告非常重要!

此外,您应该考虑在启用其他编译器警告标志的情况下进行编译。在这里阅读:

为什么我应该总是启用编译器警告?

于 2021-11-23T19:17:01.387 回答
0

因此,您当前正在将存储在 aptr 中的地址设置为21

这相当于设置:

int a = 7;
int *aptr = 0xFFFFFFFF //this could be a memory address

您只是将 aptr 指向的内容分配为内存地址 7,但您不知道该地址(或是否在范围内)存储了什么,所以这就是您收到错误的原因。

要了解有关指针的更多信息,请尝试查看这篇文章:https ://www.tutorialspoint.com/cprogramming/c_pointers.htm

于 2021-11-23T18:58:45.130 回答
0

变量的指针存储地址不是值。在这里,您声明int *aptr为整数指针,这意味着它将存储任何整数变量的地址,而不是整数。

int x = 7;  // x is an integer variable.

int *aptr = 21;  // aptr is an integer pointer.

你应该写:

 int *aptr = &x;
                              1X 
      ____                     ____
aptr | 1X |  ---------->    x | 7  |

aptr 指向 1X,它是整数变量 x 的地址。

于 2021-11-23T19:11:05.567 回答