Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/38.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 返回静态变量会有什么不同?_C - Fatal编程技术网

C 返回静态变量会有什么不同?

C 返回静态变量会有什么不同?,c,C,为什么上面的代码打印不可预测的结果?如何使char buffer[30]静态有帮助?一个静态变量在程序的整个运行时都存在,而普通的“自动”变量只在其父作用域存在时才存在 如果您确实返回指向非静态变量的指针,这意味着调用方将获得一个对内存的引用,当被调用函数返回时,该内存不再保存它在函数中所做的操作。调用方无法有效访问该内存,这样做将调用未定义的行为。自动变量驻留在(函数调用)堆栈上。因此,当调用下一个函数时(printf,在本例中),堆栈内容会被重写。因此出现了不可预测的错误 然而,静态变量存储

为什么上面的代码打印不可预测的结果?如何使char buffer[30]静态有帮助?

一个
静态变量在程序的整个运行时都存在,而普通的“自动”变量只在其父作用域存在时才存在


如果您确实返回指向非
静态变量的指针,这意味着调用方将获得一个对内存的引用,当被调用函数返回时,该内存不再保存它在函数中所做的操作。调用方无法有效访问该内存,这样做将调用未定义的行为。

自动变量驻留在(函数调用)堆栈上。因此,当调用下一个函数时(
printf
,在本例中),堆栈内容会被重写。因此出现了不可预测的错误

然而,静态变量存储在数据段中。(就存储而言,与全局变量非常相似。)

因此,在下一次函数调用期间不会覆盖静态变量。因此,它工作良好

int main(){    
  char *s ;
  char *fun( ) ;
  s = fun( ) ;
  printf ( "%s", s ) ;
}

char *fun( ){    
  char buffer[30] ;
  strcpy ( buffer, "RAM - Rarely Adequate Memory") ;
  return ( buffer ) ;
}
该行为堆栈上的缓冲区分配空间。当函数退出时,存储将消失,并将被printf中声明的自动变量覆盖

char buffer[30];
使缓冲区从程序的数据段分配,因此在调用printf时不会被覆盖。但是,由于它只分配一次,因此每次调用
fun
都会覆盖上一个值(这对您来说不是问题,因为您正在代码中strcpy一个常量字符串。

static char buffer[30];
buffer
数组仅在函数本身的生存期内存在;一旦函数退出,由
buffer
使用的内存将可供其他线程或进程使用。这意味着在执行语句之间的时间内

char *fun( ){    
  char buffer[30] ;
  strcpy ( buffer, "RAM - Rarely Adequate Memory") ;
  return ( buffer ) ;
}
另一个线程或进程可能已覆盖
缓冲区使用的内存

如果将
缓冲区
声明为
静态
,例如

s = fun( ) ;
printf ( "%s", s ) ;
然后,
缓冲区使用的内存在程序启动时分配,并一直保持到程序终止,这意味着其他任何东西都不能覆盖它。然而,这是有代价的;
fun
不再是了。由于函数当前已编写,这不是问题,因为它为任何调用返回相同的值。但是,如果e> fun
用于在不同的情况下返回不同的字符串,如果一个调用被另一个调用中断,您可能会遇到问题

第三个选项是动态分配
缓冲区的内存:

char *fun( ){    
  static char buffer[30] ;
  strcpy ( buffer, "RAM - Rarely Adequate Memory") ;
  return ( buffer ) ;
}
这就解决了前两个问题;在函数退出后,缓冲区的内容将被保留,并且您不局限于一个静态缓冲区。但是,由于没有免费午餐,现在调用函数必须确保在完成后释放该内存:

char *fun( ){    
  char *buffer = malloc( sizeof *buffer * 30 ) ;
  if ( buffer )
    strcpy ( buffer, "RAM - Rarely Adequate Memory") ;
  return ( buffer ) ;
}

为什么这个标签是Java?@RohitJain这是Java 11的全新语法。@zavg这是一个只在main范围内可见的函数声明。可能已经很晚了,这就是为什么我在不应该看到空格的地方看到空格,而在应该看到空格的地方看不到空格的原因。这就是静态变量是什么,但为什么是它是不可预测的行为吗?你应该明确为什么它是不可预测的(即内存可以用在其他地方)
int main(){    
  char *s ;
  char *fun( ) ;
  s = fun( ) ;
  printf ( "%s", s ) ;
  free( s );
}