C++ 指针与数组名的区别,求助高手
//下列程序代码,A、B、C、D中哪一行代码的结果不可预知,为什么?#include<iostream>usingnamespacestd;intGetMemory(ch...
//下列程序代码,A、B、C、D中哪一行代码的结果不可预知,为什么?
#include<iostream>
using namespace std;
int GetMemory(char **pp1, char **pp2)
{
char a[] = "hello";
char *b = "world";
*pp1 = a; //----A
*pp2 = b; //----B
return 0;
}
int main()
{
char *p1, *p2;
GetMemory(&p1 , &p2 );
cout<<p1<<endl; //---C
cout<<p2<<endl; //---D
system("pause");
} 展开
#include<iostream>
using namespace std;
int GetMemory(char **pp1, char **pp2)
{
char a[] = "hello";
char *b = "world";
*pp1 = a; //----A
*pp2 = b; //----B
return 0;
}
int main()
{
char *p1, *p2;
GetMemory(&p1 , &p2 );
cout<<p1<<endl; //---C
cout<<p2<<endl; //---D
system("pause");
} 展开
展开全部
首先,第一行肯定是输出乱码,解释2个知识点你就知道了:
1.数组和指针的区别,其实对于你的问题这不是最重要的,不过既然你问道区别就说说吧:
数组名确实表示指向数组首地址的指针,但这个指针很特别,它的值(指针的值指的是指针所指的地址)不能被改写,能改写的仅仅是其指向的内容,换句话说,数组名只能指向数组的首地址,如果有数组char a[];那么如果出现a = a+1;这是编译都通不过的错误。而对于一个普通的指针是可以的,再比如有数组char a[];那么再定义一个char *p = a;然后再用p = p+1是合法的,这表示让指针p指向&a[1]。
它们的第二个区别是:每当用到数组名这个指针的时候,系统都会传入数组的信息,而普通的指针只是一个4字节的整数,例如:
char a[5];
char *p = a;//指针a和指针p都指向数组a的首地址
cout << sizeof (a) << "##" << sizeof (p) << endl;
这时的运行结果是“5##4”
2.作用域以及生存期:
被一组“{}”括起来的部分被称为一个“域”,在某个域中定义的变量称为局部变量,这个局部变量仅仅在该作用域下有效,一旦离开这个作用域,该变量就消亡;如果遇见多重作用域,外层的变量可在内层起作用,如果遇见内层与外层同名的情况,则内层的同名变量在内层覆盖外层变量。
举个例子:
void fun1()
{
int a = 1;//在fun1()中定义整型变量a值为1
}
void fun2()
{
cout << a << endl;//企图在fun2()中使用fun1()中的变量,编译出错!因为a在离开其作用域后消亡,这里会提示变量a没有被声明;
}
void fun3 ()
{
int c = 1;
cout << c << endl;//正常打印出c的值,即1;
{ //新增加作用域
int c = 2; //在fun3()的子作用域中定义重名变量c,注意,如果不是子作用域编译会报错,因为重复定义同一个变量
cout << c << endl;//这里将打印出子作用域的c,即2,这里说明了新增的c覆盖了上面的c;
} //新增加的作用域结束
cout << c << endl;//这里依然会打印出1,因为这里的c是第一个定义的c,上面新增的作用域的c已经在其作用域结束的时候消亡。
}
好了,上面的基础知识说完了,现在我们来分析你的程序,第一行出现乱码是因为在函数GetMemory()结束的时候,数组消亡了,每个元素都消亡了,所以在你打印的时候,系统找不到p1指向的值,因为已经消亡,p1成了野指针,所以出现乱码,而第二行正常是因为:虽然指针b也在函数中消亡,不过消亡的仅仅只是一个指针,其指向的内容并没有消亡,而这些内容的首地址已经在GetMemory()中赋给了你传入的指针,所以第二行正确
1.数组和指针的区别,其实对于你的问题这不是最重要的,不过既然你问道区别就说说吧:
数组名确实表示指向数组首地址的指针,但这个指针很特别,它的值(指针的值指的是指针所指的地址)不能被改写,能改写的仅仅是其指向的内容,换句话说,数组名只能指向数组的首地址,如果有数组char a[];那么如果出现a = a+1;这是编译都通不过的错误。而对于一个普通的指针是可以的,再比如有数组char a[];那么再定义一个char *p = a;然后再用p = p+1是合法的,这表示让指针p指向&a[1]。
它们的第二个区别是:每当用到数组名这个指针的时候,系统都会传入数组的信息,而普通的指针只是一个4字节的整数,例如:
char a[5];
char *p = a;//指针a和指针p都指向数组a的首地址
cout << sizeof (a) << "##" << sizeof (p) << endl;
这时的运行结果是“5##4”
2.作用域以及生存期:
被一组“{}”括起来的部分被称为一个“域”,在某个域中定义的变量称为局部变量,这个局部变量仅仅在该作用域下有效,一旦离开这个作用域,该变量就消亡;如果遇见多重作用域,外层的变量可在内层起作用,如果遇见内层与外层同名的情况,则内层的同名变量在内层覆盖外层变量。
举个例子:
void fun1()
{
int a = 1;//在fun1()中定义整型变量a值为1
}
void fun2()
{
cout << a << endl;//企图在fun2()中使用fun1()中的变量,编译出错!因为a在离开其作用域后消亡,这里会提示变量a没有被声明;
}
void fun3 ()
{
int c = 1;
cout << c << endl;//正常打印出c的值,即1;
{ //新增加作用域
int c = 2; //在fun3()的子作用域中定义重名变量c,注意,如果不是子作用域编译会报错,因为重复定义同一个变量
cout << c << endl;//这里将打印出子作用域的c,即2,这里说明了新增的c覆盖了上面的c;
} //新增加的作用域结束
cout << c << endl;//这里依然会打印出1,因为这里的c是第一个定义的c,上面新增的作用域的c已经在其作用域结束的时候消亡。
}
好了,上面的基础知识说完了,现在我们来分析你的程序,第一行出现乱码是因为在函数GetMemory()结束的时候,数组消亡了,每个元素都消亡了,所以在你打印的时候,系统找不到p1指向的值,因为已经消亡,p1成了野指针,所以出现乱码,而第二行正常是因为:虽然指针b也在函数中消亡,不过消亡的仅仅只是一个指针,其指向的内容并没有消亡,而这些内容的首地址已经在GetMemory()中赋给了你传入的指针,所以第二行正确
展开全部
A
你首先要思考下 p1 在GetMemory(&p1 , &p2 );之后里面装的是什么? 这里因该装的是地址而不是一个变量,你如果要想输出这个地址里的值那就加上‘* ’号。但输出的只是首地址的值,至于为什么3楼的第一点已经说的很详细了
你可以结合下面的程序分析下
#include <iostream>
using namespace std;
int main()
{
char p[] = "a23456";
char *a = p;
cout<<*a;
return 0;
}
你首先要思考下 p1 在GetMemory(&p1 , &p2 );之后里面装的是什么? 这里因该装的是地址而不是一个变量,你如果要想输出这个地址里的值那就加上‘* ’号。但输出的只是首地址的值,至于为什么3楼的第一点已经说的很详细了
你可以结合下面的程序分析下
#include <iostream>
using namespace std;
int main()
{
char p[] = "a23456";
char *a = p;
cout<<*a;
return 0;
}
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
2011-05-13
展开全部
c
大概输出乱码
char a[] = "hello";
定义的数组a[6]在函数返回后,不存在了,cout<<p1<<endl; 输出的内容不可预知
大概输出乱码
char a[] = "hello";
定义的数组a[6]在函数返回后,不存在了,cout<<p1<<endl; 输出的内容不可预知
更多追问追答
追问
杯具的是输出的是
hello
world
我晕了,不知道你用机子测试会是啥样?
追答
我的回答是“大概输出乱码”,能不能输出hello看系统的心情了
我用cbulider试了下,输出的是
“乱码”
world
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询