从函数返回char*和char []有什么区别?

Tob*_*obs 66 c string pointers

为什么第一个函数返回字符串"Hello,World",但第二个函数不返回任何内容.我认为两个函数的返回值都是未定义的,因为它们返回的数据超出了范围.

#include <stdio.h>
// This successfully returns "Hello, World"
char* function1()
{
    char* string = "Hello, World!";
    return string;
}
// This returns nothing
char* function2()
{
    char string[] = "Hello, World!";
    return string; 
}

int main()
{
    char* foo1 = function1();
    printf("%s\n", foo1); // Prints "Hello, World"
    printf("------------\n");
    char* foo2 = function2(); // Prints nothing
    printf("%s\n", foo2);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

眠りネ*_*ネロク 67

第二个函数什么都不返回

string第二个函数中的数组:

char string[] = "Hello, World!";
Run Code Online (Sandbox Code Playgroud)

自动存储时间.控制流从函数返回后不存在.

string在第一个功能:

char* string = "Hello, World!";
Run Code Online (Sandbox Code Playgroud)

指向文字字符串,具有静态存储持续时间.这意味着,从函数返回后,字符串仍然存在.您从函数返回的是指向此文字字符串的指针.

  • 我认为这可以使用一些澄清.在这两种情况下,字符串"Hello,world!";`具有静态存储持续时间.在第一种情况下,我们创建一个名为`string`的自动数组,并将静态字符串复制到自动数组中.在第二种情况下,我们创建一个名为`string`的自动指针,它指向静态存储区域. (28认同)
  • 在这种情况下,字符串文字(例如"Hello,world!"`)具有静态存储.由于历史原因,字符串文字有点奇怪.将它们存储在`char*`而不是`const char*`中是唯一合法的,以便与`const`之前编写的代码向后兼容.但是当你尝试通过非`constst`指针修改字符串时,这会导致错误.将它声明为`const char*const`会更好,因为它是一个永不修改的指向不可修改内存的指针. (2认同)

Som*_*ude 26

您需要了解字符串的第一件事是字符串文字实际上是一个只读字符数组,其生命周期为完整程序.这意味着它们永远不会超出范围,它们将始终存在于整个程序的执行过程中.

第一个函数(function1)做的是返回指向这样一个数组的第一个元素的指针.

第二个函数(function2)的东西有点不同.这里变量string是函数中的局部变量.因此,一旦函数返回,它将超出范围并停止存在.使用此函数,您将返回指向该数组的第一个元素的指针,但该指针将立即变为无效,因为它将指向不再存在的内容.取消引用它(将其传递给它时会发生printf)将导致未定义的行为.

  • 详细说明:在`function2`中,还存在一个只读字符串,该函数退出后将继续存在.但是你没有返回指向它的指针.发生的是您将该字符串中的数据复制到局部变量,然后返回指向*that*的指针.所以字符串仍然存在于某个地方,而不是指针指向的位置. (5认同)
  • @ComicSansMS可能没有只读字符串.编译器倾向于优化这样的分配,移动少数而不是复制字符串. (2认同)

Pau*_*ith 7

在C语言或其他基于堆栈的语言中编码时要记住的一件非常重要的事情是,当函数返回时,它(及其所有本地存储)都消失了.这意味着如果你希望其他人能够看到你的方法的结果很难,你必须把它放在你的方法停止后仍然存在的地方,这样做意味着你需要了解C存储东西的方式和方式.

您可能已经知道数组如何在C中运行.它只是一个内存地址,它以对象的大小递增,您可能也知道C不进行边界检查,所以如果要访问十的第11个元素元素数组,没有人会阻止你,只要你不尝试写任何东西,没有伤害.您可能不知道的是C将这个想法扩展到它使用函数和变量的方式.函数只是堆栈上的内存区域,按需加载,其变量的存储只是偏离该位置.你的函数返回一个指向局部变量的指针,特别是堆栈上一个位置的地址,该位置包含'Hello World \n\0'的'H',但是当你调用另一个函数(print方法)时,该内存是通过print方法重用以完成所需的操作.你可以很容易地看到这一点(不要在生产代码中这样做!!!)

char* foo2 = function2(); // Prints nothing
ch = foo2[0];  // Do not do this in live code!
printf("%s\n", foo2);  // stack used by foo2 now used by print()
printf("ch is %c\n", ch);  // will have the value 'H'!
Run Code Online (Sandbox Code Playgroud)


hac*_*cks 5

我认为两个函数的返回值都是未定义的,因为它们返回的数据超出了范围.

不,情况并非如此.

在函数中,function1您将返回指向字符串文字的指针.返回指向字符串文字的指针很好,因为字符串文字具有静态存储持续时间.但是自动局部变量并非如此.

在函数中function2,数组string是一个自动局部变量和语句

return string; 
Run Code Online (Sandbox Code Playgroud)

返回指向自动局部变量的指针.函数返回后,该变量string将不再存在.取消引用返回的指针将导致未定义的行为.

  • @让 - FrançoisFabre; 是.除了声誉之外,这是你从社区获得的奖励,同时为社区做出贡献:) (3认同)

归档时间:

查看次数:

4729 次

最近记录:

8 年,1 月 前