我创建了一个函数(例如:fun())并从main函数调用它。我还在函数中创建了一个数组,我将数组的基地址返回到main函数中的整数指针如果数组在函数fun()中声明为static,则数组元素在main函数中正确显示。如果没有,则会打印一些垃圾值。但反之亦然。这就是decalring主函数中的一个数组,并通过传递基地址将其打印到另一个函数中。那么将数组声明为静态的用途是什么?对它有什么正确的解释?
答案 0 :(得分:2)
如果一个对象在一个函数中被声明为static,它本质上是一个全局的永久对象,并且每次调用该函数时都不会像其他局部变量那样重新初始化。
如果你有一个函数本地的非静态对象,并且你返回它的地址,那么当调用者对地址执行某些操作时,对象已经超出了范围,因为你已经不在了被调用的函数,以及指针所指的内存区域中有未定义的数据,无论你之前放的是什么。如果对象是静态的,那么它不会超出范围。
如果你有一个main
本地的对象,你从main
调用一个函数并传递一个指向这个对象的指针,那么就该程序而言,该对象仍然存在,因为你当你离开被调用函数的主体时,它仍然处于主函数中,并返回它,因此引用该内存区域没有问题。这与main
无关:从不同的函数尝试相同的事情。
顺便说一句,这些都与数组无关,整个讨论适用于任何类型的对象。
答案 1 :(得分:0)
如果未声明数组static
,则在离开函数时数组会“消失”。实际上,只要函数正在执行,您在函数中声明的非static
的所有变量都只存在。从函数返回后,变量被解除分配from the heap。这称为变量的“scope”,即变量存在的代码区域。
在你的情况下,你正在返回一个指向你的数组曾经存在的区域的指针,当函数执行时,但是当main
使用指针的时候,数组曾经的区域有被覆盖了。
答案 2 :(得分:0)
如果数组声明为static,那么即使在执行函数调用之后该数组仍然存活,因此您可以访问该数组的元素。
实际上,静态数组分配在内存的不同部分,而不是在函数堆栈框架中分配。所以即使函数调用结束也没关系,数组仍然存在。
答案 3 :(得分:0)
对象可以具有三种存储持续时间之一:自动,静态或动态。
具有自动存储持续时间的对象在它们被定义之后立即为它们分配存储,并且该存储仅在当前范围的持续时间内保持;一旦该范围退出,该对象就不复存在了。例如:
void foo( int x ) // storage for x is set aside here
{
int bar; // storage for bar is set aside here
if ( x > 0 )
{
int i; // storage for i is set aside here
...
} // storage for i is released here
} // storage for x and bar is released here
变量i
仅存在于if
语句的范围内; bar
和x
仅存在于函数范围内。一旦函数退出,这些变量就不再存在,并且为其他人分配的任何存储现在都可供其他人使用 1 。
具有静态存储持续时间的对象在程序启动时为它们分配了存储空间,并且该存储一直保持到程序退出为止。在文件范围(任何函数之外)或使用static
关键字声明的任何内容都具有静态存储持续时间:
void foo( int x ) // storage for x is set aside here
{
static int bar; // storage for bar was set aside at program start
...
} // storage for x is released here; storage for bar will
// be released when the program exits
这就是你看到你所做的行为的原因;当数组未声明static
时,它会在函数退出后释放,其他人可以自由覆盖它。当您声明它static
时,该存储将一直保留到程序退出,因此没有其他人可以使用它。
具有动态存储持续时间的对象使用malloc
,calloc
或realloc
手动分配,并保持到free
明确发布为止。
<小时/> 1。实际上,
x
,bar
和i
的存储通常会在函数输入处保留,并保持到函数退出,但逻辑上说你可以我希望在i
语句范围之外存在if
的任何存储空间,这意味着任何指针到i
都不会在if {{1}}之外有效言。