C++ 从函数返回可变长度数组
下面的函数“increment”将1添加到表示为数组的数字中C++ 从函数返回可变长度数组,c++,arrays,gcc,variable-length-array,C++,Arrays,Gcc,Variable Length Array,下面的函数“increment”将1添加到表示为数组的数字中 int* increment(int array[], int size, int *sizeLen) { int temp[size+1]; int carry = 0; carry = (array[size-1]+1)/10; temp[size] = (array[size-1]+1)%10; for(int i=size-2;i>=0;i--) {
int* increment(int array[], int size, int *sizeLen)
{
int temp[size+1];
int carry = 0;
carry = (array[size-1]+1)/10;
temp[size] = (array[size-1]+1)%10;
for(int i=size-2;i>=0;i--)
{
temp[i+1] = (array[i] + carry)%10;
carry = (array[i]+carry)/10;
}
if(carry)
{
temp[0] = 1;
*sizeLen = size+1;
return temp;
}
else
{
*sizeLen = size;
return (temp+1);
}
}
int main()
{
int array[] = {9,9,9};
int length;
int *res = increment(array, sizeof(array)/sizeof(int), &length);
for(int i=0;i<length;i++)
{
cout << res[i] << " ";
}
}
int*增量(int数组[],int大小,int*sizeLen)
{
内部温度[尺寸+1];
整数进位=0;
进位=(数组[size-1]+1)/10;
温度[size]=(数组[size-1]+1)%10;
对于(int i=size-2;i>=0;i--)
{
温度[i+1]=(数组[i]+进位)%10;
进位=(数组[i]+进位)/10;
}
如果(携带)
{
温度[0]=1;
*sizeLen=尺寸+1;
返回温度;
}
其他的
{
*sizeLen=尺寸;
返回(临时+1);
}
}
int main()
{
int数组[]={9,9,9};
整数长度;
int*res=增量(数组、sizeof(数组)/sizeof(int)和长度);
对于(int i=0;i这是未定义的行为。下次程序推送到堆栈时,数据将丢失
专业程序不要依赖于此。这是未定义的行为。下次程序推送到堆栈时,数据将丢失
专业程序不要依赖它。你是对的。temp
确实超出范围,它应该打印垃圾值
但有时它会打印正确的值。因为当当前函数结束时,不会立即清除/覆盖本地堆栈内存。您是对的。temp
确实超出范围,它应该打印垃圾值
但有时它会打印正确的值。因为当当前函数结束时,不会立即清除/覆盖本地堆栈内存。这里的键实际上是数组的存储持续时间。它具有自动存储持续时间。具有自动存储持续时间的变量的生存期在退出其作用域时结束
它完全按照您期望的那样运行,但是C中没有任何东西可以阻止您获取本地对象的地址并从函数返回它
使用该指针是未定义的行为。它可能看起来有效,但数组仍然是“死的”。这种指针通俗地称为“悬空指针”
对于C来说,上述情况是正确的。因为这是关于GCC扩展的,同样适用于大多数情况,但可能需要谨慎对待。这里的关键确实是数组的存储持续时间。它具有自动存储持续时间。具有自动存储持续时间的变量的生存期在其所在范围为exi时结束特德
它完全按照您期望的那样运行,但是C中没有任何东西可以阻止您获取本地对象的地址并从函数返回它
使用该指针是未定义的行为。它可能看起来有效,但数组仍然是“死的”。这种指针通俗地称为“悬空指针”
对于C来说,上述情况是正确的。因为这是关于GCC扩展的,所以同样适用于大多数情况,但可能需要谨慎对待。这不起作用。您将返回一个指向本地数组的指针,该数组将在函数返回时被删除(更有可能被过度写入/重新使用)
这样做的C++方法是使用<代码> STD::vector < /COD>。(假设在原来的<代码>大小<代码>和代码> SiZelEN < /代码>中引用了<代码>数组< < />代码中的元素数量,并且分别返回
这将不起作用。您正在返回一个指向本地数组的指针,该数组将在函数返回时立即被删除(更有可能被过度写入/重新使用)
这样做的C++方法是使用<代码> STD::vector < /COD>。(假设在原来的<代码>大小<代码>和代码> SiZelEN < /代码>中引用了<代码>数组< < />代码中的元素数量,并且分别返回
你所看到的是未定义的行为。C.C++的陷阱甚至不支持VLAs,你的代码基本上是使用容器和迭代器。我没有注意到标签。为什么你在VC++中使用VLA(扩展,非标准)?你的问题是关于C吗?请澄清。那些是不同的语言。谢谢大家的帮助。是的,我知道我写了C和C++代码的混合。我对程序的奇怪行为感到好奇。@老鹰-我对程序的奇怪行为感到好奇——试图弄清楚为什么你的程序表现得奇怪。这是一种巨大的时间浪费。为什么?如果你编译了同一个程序,但使用了不同的编译器选项,例如优化,那么程序的行为可能会再次与你看到的不同。试图找出未定义的行为变得毫无意义。你看到的是未定义的行为。这就是C.C++的陷阱甚至不支持VLAs,而且代码基本上是使用容器和迭代器。我没有注意到标签。为什么在VC++代码中使用VLA(扩展,非标准)?你的问题是关于C吗?请澄清。那些是不同的语言。谢谢大家的帮助。是的,我知道我写了C和C++代码的混合。我对程序的奇怪行为感到好奇。@老鹰-我对程序的奇怪行为感到好奇——试图弄清楚为什么你的程序表现得奇怪。成为一个巨大的时间浪费。为什么?如果你编译了同一个程序,但使用了不同的编译器选项,例如优化,那么这个程序的行为可能会再次与你看到的不同。现在,试图找出未定义的行为变得毫无意义。请原谅我的简短。我目前使用的是Android平板电脑。请原谅我的简短。我目前使用的是Android平板电脑。if(carry)temp.insert(1,temp.begin())有什么问题
?它涉及到将所有元素洗牌,但这并不比您实现的副本更糟。此外,如果您将进行初始化,将携带到1,然后在期间使循环成为执行,整个过程将变成std::vector result(array);
(或更好)
std::vector<int> increment(std::vector<int> const&array)
{
std::vector<int> temp(array.size());
auto a = array.rbegin();
auto b = temp.rbegin();
auto carry = (*a+1)/10;
*b = (*a+1)%10;
for(++a,++b; a!=array.rend(); ++a,++b)
{
*b = (*a+carry)%10;
carry = (*a+carry)/10;
}
if(carry) { // we must add another element into temp at the start
// that cannot be done with vector, hence we must create
// another vector. Note that this should rarely happen.
std::vector<int> result(temp.size()+1);
auto r = result.begin();
*r = 1;
std::copy(temp.begin(),temp.end(),++r);
return result;
} else
return temp;
}
std::vector<std::uint8_t> increment(std::vector<std::uint8_t> const&input)
{
std::vector<std::uint8_t> result;
result.reserve(input.size()+1);
auto a = input.begin();
auto carry = (*a+1)/10;
result.push_back((*a+1)%10);
for(++a; a!=input.end(); ++a)
{
result.push_back((*a+carry)%10);
carry = (*a+carry)/10;
}
if(carry)
result.push_back(1);
return result;
}