【发布时间】:2018-12-21 09:59:51
【问题描述】:
现在我正在学习 C 和 C++ 的来龙去脉。我知道当您在函数内创建一个数组时,它会存储在该函数的堆栈框架中。您可以返回数组的基地址,它实际上是指向该数组中第一个元素的指针。返回的指针值被存储到 EAX/RAX 寄存器中,然后来自寄存器的值被移动到调用函数的本地指针变量中。问题是当函数返回时,该函数的堆栈帧会从被调用的堆栈中弹出,并且在该函数的堆栈帧内声明的任何数据都会过期。指针现在指向一个无效的内存位置。
我希望能够从被调用函数中按值返回数组,而不是按指针。该数组必须在函数内部创建并存储在堆栈中。我想按值返回一个数组,就像返回一个在被调用函数中声明的 int 一样。
int f() {
int a = 5;
return a; // returned by value
}
int main() {
int b = f();
return 0;
}
这里的 int 值被移动到 EAX/RAX 寄存器中,所以它是一个副本。被调用函数的堆栈帧从调用堆栈中清除,但没有问题,因为返回值现在存储在寄存器中,就在将其复制到 int b 之前。
我知道在 C++ 中我可以在被调用函数中创建一个向量,然后按值返回它。但是我不想使用这种更高级别的抽象来支持学习一种“hacky”的方式来做到这一点。稍后我会回到向量。
好吧,我意识到可以从函数中按值返回结构对象。所以我按值返回数组的解决方案非常简单:把它放在一个结构体中,然后按值返回那个结构体!
struct String {
char array[20];
};
struct String f() {
struct String myString;
strcpy(myString.array, "Hello World");
return myString; // Is this returned by value?
}
int main() {
struct String word = f();
printf("%s\n", word.array);
}
如果我正确理解代码,请澄清。该结构对象在被调用函数的堆栈帧中创建,“Hello World”被复制到其中包含的数组中,然后呢?
struct String word 是一个左值,f() 返回一个 rvlaue。当一个结构被分配给另一个结构时,它的所有数据成员都会被一一复制。
在结构体从被调用函数按值返回之后和分配给main()函数内的结构体之前之间会发生什么? EAX/RAX 寄存器是返回值的目的地。它是 64 位还是 32 位,具体取决于您使用的是 64 位还是 32 位计算机。您究竟如何将结构对象放入寄存器中?我想这个数组可能不仅是 20 个字节,而且是 100 个字节!结构是否从函数中逐个复制到寄存器中?或者它是一次从堆栈上的一个内存位置按值复制到另一个内存位置?以及在被调用函数内部创建的原始结构对象会发生什么?这些都是我想知道答案的问题。
另外,关于从函数中按值返回向量。 C++ 中的向量是类,类类似于结构。你能回答这个问题,当你从一个函数中按值返回一个向量时会发生什么?当您将类/结构对象传递给函数作为参数时会发生什么?
我可以想象按值传递如何处理小数据类型。我什至不知道它如何处理复杂的数据类型和数据结构。
【问题讨论】:
-
这是一个问题还是几个问题?请务必提出一个具体问题。
-
本来想问一个问题的,结果太走神了!
-
请做一个。
-
C is not C++ is not C,只选择一种语言
-
这里有很多事情要做。您想知道是否可以在 C 中返回结构吗?在 C++ 中你想知道在 C 中执行它的汇编代码是什么吗?在 C++ 中?在特定的编译器中?想知道参数是如何复制的吗?锄头 C++ 向量被复制?缩小范围。
标签: c++ c arrays struct parameter-passing