因为在c ++中无法返回int[]
(或任何与此相关的数组类型),所以我有一个或两个函数返回了int*
,这使我的生活变得相当困难。
我程序的一个函数要求复制我一直在函数之间传递的数组,并以各种方式对其进行递增,然后返回该副本。我发现复制数据以使原始数组不受复制更改影响的唯一方法是一次复制每个“成员”,例如
int* foo(int* a) {
int b[2] = {a[0], a[1]};
/* do unspeakable things to b */
return b;
}
对于这种非常特殊的情况,哪一个还可以,但是我敢肯定这不是最有效的方法,尤其是对于大型数组。
我可以使用一些类型转换向导或其他方法来执行此操作吗? 更有效?
注意::我不是在问他们,这是否是一种良好做法,是否符合《日内瓦公约》,还是非常有意安全地? 。目前,我并不特别在意这些信息,如果您绝对必须说出来,我宁愿这不是您的答案的正文或开头。
另外,NOTE中T周围的字距对其他人来说是否很奇怪?
编辑:在实际使用我的“解决方案”之后,我确定自己是个白痴,应该在测试之前对它们进行测试。
答案 0 :(得分:1)
int b[2];
int * c = b;
来自cppreference implicit conversion:
数组到指针的转换
类型为“ N T的数组”的左值或右值 或“ T的未知范围的数组”可以隐式转换为 类型为“指向T的指针”的prvalue。
这意味着任何类型的数组都隐式转换为类型的指针。指针指向数组的第一个成员,因此c == &b[0]
。有趣的是,指向数组的指针也等于数组&b == &b[0]
的第一个元素的指针,但是具有不同的类型,即:
int b[2];
int * c = b; // implicit conversion from array to pointer
int (*d)[2] = &b; // &b is a pointer to an array of 2 ints
int * e = &b[0]; // pointer to the first element
功能:
int* foo(int* a) {
int b[2] = {a[0], a[1]};
/* do unspeakable things to b */
return b;
}
是非常无效,错误,令人困惑和糟糕的。 b
函数返回后}
后面的内存无效,因此该函数返回的指针无效并且无法使用。
因为您无法返回int []
int[]
是一个不确定大小的数组,您无法对其进行任何操作。请注意,内部函数参数列表int[]
被隐式转换为int*
。因此,以下内容完全相同:
void f(int a[]);
void f(int *a);
或与此相关的任何数组类型)
您可以返回std::array<int , 2>
std::array<int, 2> f() {
std::array<int, 2> ret;
return ret;
}
请注意,这是非常低效的。它需要返回2 * sizeof(int)
的数据,数据将随着大小的增加而变得更大。将指针返回到数组的第一个成员仅返回指针值,所需的空间较小。还要注意,std::array<int, 2> var = f();
将copy
返回f()
和var
之间的所有数组元素(不带复制省略),因此效率非常低。
我确定这不是最有效的方法
就速度而言,最有效的方法是显式初始化每个数组成员并返回指向数组第一个元素的指针。适当的编译器将为此生成快速指令。但是您说and then the copy returned
-您必须在数组功能中创建一个副本,因此必须在原始副本与副本之间复制所有数组成员。没有其他办法。
是否可以使用某些类型转换向导或其他方法来更有效地执行此操作?
将原始C数组扔到垃圾箱中,然后移到容器中。如果在编译时知道大小,请移至std::array<int, 2>
;如果在编译时未知大小,请移至std::vector<int>
。
std::vector<int> foo(std::vector<int> a) {
std::vector<int> b{a};
return b;
}
请注意,这里return b
没问题,因为std::vector<int>
本身存储了指向动态分配内存的指针。在new
之后分配给}
的内存不会不复存在,因此您可以返回指向它的指针。如果您的编译器支持复制省略,则该功能应该可以快速运行。更快的版本是使用引用。
void f(std::vector<int>& ret, std::vector<int> a) {
ret = a;
}
答案 1 :(得分:0)
您可以将两个int数组都输入到一个函数中,然后让该函数为您执行复制操作:
bool CopyIntArray(int* pA, int cA, int* pB, int cB)
{
if (pA == NULL || cA == 0 || pB == NULL || cB == 0)
{
return false;
}
for (int i = 0; i < cA && i < cB; i++)
{
pB[i] = pA[i];
}
return true;
}
int main()
{
int x[10] = { 0,1,2,3,4,5,6,7,8,9 };
int y[10] = { 0 };
CopyIntArray(x, 10, y, 10);
return 0;
}
顺便
int* foo(int* a) {
int b[2] = {a[0], a[1]};
/* do unspeakable things to b */
return b;
}
b超出函数范围时会被破坏,因此,使用销毁的变量作为函数输出时,您的应用很危险。