char p[]="hello world";和char *p="hello world"的区别;
前者存放在栈里,后者存放在常量区
//首先 假设printf(s)等同于printf("%s",s),否则编译出错
char* getMem(void) {
charp[] = “hello world ”;
p[5] = 0x0;
returnp;
}
p是个数组,在{}里面定义是个局部变量,说明这个函数执行完毕之后局部变量销毁p这个数组中的值都没有了。
p虽然是个数组,但是单独用p这个变量,值是p这块数组的首地址,因为返回的是值传递,所以这个首地址被传到了下面的s中,
s指向这个内存,而这个内存在getMem函数调用结束后就销毁了,里面存放的不知道是什么了。所以打印的话不一定出现什么。
voidtest(void) {
char*s = 0x0;
s = getMem();
printf(s);
}
扩展:
1.char* getMem(void) {
char*p = “hello world ”;
returnp;
}
成功 helloworld字符串存放在常量区,这个地方存放的内容并不会在函数结束后销毁。
p最后依然指向这里
//************************************************************************
2.char* getMem(void) {
charp[] = “hello world ”;
p[5] = 0x0;
returnp;
}
错误 p[5]错误 常量区的数据不可以更改。
//************************************************************************
3.string getMem(void) {
string s = “hello world ”;
string &rs = s;
return rs;
}
string ss = getMem();//正确 值传递ss已经是一个新的局部变量,完全拷贝了getMem返回的临时量。
string &rs = getMem();//错误 getMem函数返回的是临时变量,也就是右值,不能用左值引用来引用
const string &crs = getMem();//正确,右值可以用const引用来引用
//************************************************************************
4.string& getMem(void) {
string s = “hello world ”;
string &rs = s;
return rs;
}
string ss = getMem();//错误,s是局部变量,返回值是个引用,本质是在临时区建立了一个引用,这个临时的引用引用了rs 也就是s,但是函数结束了,这个局部的s小时了,消失之后返回的引用还引用他,不但引用,还用它来初始话ss,那就错了。
string &rs = getMem();//错误 相当于rs是个函数内部局部变量s的引用,s已经清空,所以cout<<rs 是乱码。这个表达式成立是因为返回值是个引用,引用是个左值,不是右值,左值可以用左值引用来引用
(注:左值引用 int &lr = a; 右值引用 int &&rr = i++;)
//************************************************************************
5.string getMem(string &s) {
string &rs = s;
returnrs;
}
string s = "helloworld";
string ss = getMem(s);//正确值传递,用返回值来初始化了ss
string &rs = getMem(s);//错误,同上,右值
const string &rs = getMem(s);//正确,右值用常引用来引用,
cout<<ss;
cout<<rs;
//************************************************************************
6.string& getMem(string &s) {
string &rs = s;
returnrs;
}
string s = "helloworld";
string ss = getMem(s); 正确 相当于用 外面的s 来初始化ss 可以
string &rs = getMem(s);正确 rs指向的是s s的作用域还没有结束,
cout<<ss;
cout<<rs;