C++中如何返回一个数组
由于数组不是一种类型,因此不能被直接返回。因此,一般我们用返回一个指向数组的指针。
然而在返回数组的时候如何分配空间。
int *f()
{
int a[2];
a[0] = 1;
}
以上方法能编译通过,但是这是错误的。且看以下代码:
#include <iostream>
using namespace std;
int* f()
{
int ch[2];
ch[0]=0;
return ch;
}
void f1()
{
int ch[2];
ch[0]=1;
}
void f2()
{
double a=10.288;
}
int main()
{
int* aa=f();
cout<<aa[0]<<endl;
f1();
cout<<aa[0]<<endl;
f2();
cout<<aa[0]<<endl;
getchar();
}
输出结果:
数组ch的首地址指针是指向栈上面的一段内存,这段内存在f函数结束后,就已经被系统忽略了,那么这个空间在程序运行的过程中,很有可能被重新分配值,因此aa[0]就可能变成任意的值,而不是我们所希望的那个数组了。
//理解。。。。
首先要理解堆栈的实现, 对于我们说的堆栈压入, 抛出操作, 并不是象我们想的那样实现的, 抛出后内容就不存在了
堆栈的操作就是通过移动栈顶指针实现的, 栈顶指针和栈底指针之间就是当前堆栈的大小
所以第一次调用函数t时, 分配了2字节的堆栈空间, 此时栈顶指针加2, 你对前1个字节赋值, 当函数结束时, 进行抛出操作, 即栈顶指针减2
但要注意, 此时系统并不会自动清空这2字节, 即他们仍然保留原来的内容.
第二次调用函数时, 仍然分配了2字节的堆栈空间, 此时栈顶指针再加2, 其实这只是巧合, 分配了和第一次调用相同的空间, 并且内容都一样.
正确的做法是用new来分配,这样的得到的数组是在堆上面分配的,当然堆到最后也要自己释放。
int *f()
{
int *a=new int[2];
a[0]=1;
return a;
}
顺便了解一下堆和栈的相关内容
下面我们定义了一个关于年月日的Date类
class Date{
private:
int year;
int month;
int day;
public:
Date():year(1900),month(1),day(1) {}
Date(int y, int m, int d):year(y),month(m),day(d) {}
~Date() {}
int GetYear() const { return year; }
int GetMonth() const { return month; }
int GetDay() const { return day; }
};
要求:是CreatePoints生成10个随机的Date,并以数组形式返回
//stochastic createpoints
Date *CreatePoints(int const count)
{
Date *my_date;
my_date = new Date[count];
time_t t;
srand((unsigned)time(&t));
for(int i=0; i<count; i++)
{
int y, m, d;
int num = 0;
y = rand() % 2000+1000;
m = rand() % 12 + 1;
switch(m)
{
case 1: case 3: case 5: case 7:
case 8: case 10: case 12:
num = 31;
break;
case 4: case 6: case 9: case 11:
num = 30;
break;
case 2:
num = 28 + (y%400?(y%100?(y%4?false:true):false):true);
break;
}
d = rand() % num + 1;
my_date[i] = Date(y, m, d);
}
cout << endl;
return my_date;
}
//几种不同的输出方式
//(1)stochastic output
Date *p;
p = CreatePoints(NUM);
for(int i=0; i<NUM-1; i++)
cout << p[i] << endl;
//(2)stochastic output(error)
Date *p;
p = CreatePoints(NUM);
for(int i=0; i<NUM-1; i++)
cout << p[i] << endl;
//for(auto &a: p)
//{
// a.print();
//}
The compiler give me an error I don’t understand.
C:/Program Files (x86)/Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include/c++/initializer_list:89:5: note: 'std::begin'
begin(initializer_list<_Tp> __ils) noexcept
^
C:/Program Files (x86)/Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include/c++/initializer_list:89:5: note: 'std::begin'
C:\Users\debug\Desktop\Date\Date.cpp:37:18: error: 'end' was not declared in this scope
for(auto &a: p)
^
C:\Users\debug\Desktop\Date\Date.cpp:37:18: note: suggested alternatives:
In file included from C:/Program Files (x86)/Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include/c++/bits/basic_string.h:42:0,
from C:/Program Files (x86)/Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include/c++/string:52,
from C:/Program Files (x86)/Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include/c++/bits/locale_classes.h:40,
from C:/Program Files (x86)/Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include/c++/bits/ios_base.h:41,
from C:/Program Files (x86)/Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include/c++/ios:42,
from C:/Program Files (x86)/Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include/c++/ostream:38,
from C:/Program Files (x86)/Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include/c++/iostream:39,
from C:\Users\debug\Desktop\Date\Date.h:13,
from C:\Users\debug\Desktop\Date\Date.cpp:10:
Range-based for loops work with arrays,but not with pointers. The issue here is that p is actually a pointer and not an array.
//(3)stochastic output
vector<Date> ivec(p, p + sizeof(p) / sizeof(Date));
for_each(ivec.begin(), ivec.end(), printElem);