关于局部指针变量和数组的操作返回值

来源:互联网 发布:mac os 10.13 版本下载 编辑:程序博客网 时间:2024/05/16 07:39
#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()中赋给了你传入的指针,所以第二行正确
原创粉丝点击