我是C语言的新手。如果我将局部变量的地址分配给全局指针,会发生什么?像,
#include <stdio.h>
void func();
int *ptr;
int main()
{
func();
}
void func()
{
int i = 0;
ptr = &i;
}
将局部变量的地址分配给全局指针是否正确?
答案 0 :(得分:2)
它只是做你做的事情,没有什么不妥,除了它可能不是你想要的。
因此,它只会在您指定的位置将i
的地址指定给ptr
。离开func
时,此指针无效。
注意此行为已完全定义:已定义将i
分配给全局变量的位置的地址,因此您可以对其进行分配。该问题仅在稍后发挥作用,当您尝试在之后取消引用变量时,您离开了函数func
。只要你在func
中使用全局变量就没有问题(除了全局变量真的没有意义)。
此时,此变量不再存在。在这种情况下,你很可能得到一个段错误或至少得到一些奇怪的数字(因为你用其他一些值覆盖了旧的堆栈帧)。
正如旁注:我对这个堆栈框架事物的意思。您可以在大多数编译器上尝试此代码(无需优化!)
#include <stdio.h>
int *ptr;
void f1() {
int i = 0;
ptr = &i;
}
void f2() {
int i = 1;
}
int main() {
f1();
printf("%d\n", *ptr);
f2();
printf("%d\n", *ptr);
}
如果没有优化,很可能会打印
0
1
因为从i
调用f1
和f2
时,变量main()
将具有相同的地址。
通过优化,可以优化对f2()
的调用。
仍然:这是未定义的行为,不得这样做。
答案 1 :(得分:2)
您的语法是正确的,但局部变量不再存在,因为它属于函数调用代码块的范围。要解决此问题,一个选项是将局部变量设为静态:
#include <stdio.h>
void func();
int *ptr;
int main()
{
func();
}
void func()
{
static int i = 0;
ptr = &i;
}
另一种选择是在函数调用中分配新内存,将全局指针设置为新分配内存的地址:
#include <stdio.h>
void func();
int *ptr = NULL;
int main()
{
func();
}
void func()
{
if(ptr != NULL)
free(ptr);
int *i = (int *)malloc(sizeof(int));
ptr = i;
}
答案 2 :(得分:0)
你得到的是语法正确,所写的代码在语义上是有效的(但由于永远不会使用<!-- Link to Registration Screen -->
<TextView android:id="@+id/link_to_register"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="40dip"
android:layout_marginBottom="40dip"
android:text="New to Twitter? Register here"
android:gravity="center"
android:textSize="20dip"
android:textColor="#0b84aa"/>
,所以它有点无意义。)
如果在包含超出范围的指针时访问ptr
,则会得到未定义的行为。
但是,请考虑稍大的代码片段。这里,设置ptr
的代码调用使用ptr
的函数,ptr
指向的变量仍然定义,因此使用指针没有问题。
ptr
这是合法的代码 - 尽管使用全局变量是一般应该避免的,并且完全可以避免。
示例输出:
#include <stdio.h>
void func(void);
void use_pointer(void);
int *ptr;
int main(void)
{
func(); // NB: argument not allowed with prototype!
int i = 20;
printf("%s: A %d\n", __func__, i);
ptr = &i;
use_pointer();
printf("%s: B %d\n", __func__, i);
}
void func(void)
{
int i = 0;
printf("%s: A %d\n", __func__, i);
ptr = &i;
use_pointer();
printf("%s: B %d\n", __func__, i);
}
void use_pointer(void)
{
printf("ptr = %p; *ptr = %d\n", (void *)ptr, *ptr);
*ptr = 42;
}