指针与数组的对比

来源:互联网 发布:淘宝直通车开通条件 编辑:程序博客网 时间:2024/05/21 10:22

指针与数组的对比


传送门:http://blog.csdn.net/csdn_lsd/article/details/78553918

  • C/C++程序中,指针和数组在不少地方可以互相替换着用,让人产生错觉,以为两者是等价的。
  • 数组要么在静态存储区被创建(全局数组),要么在栈上被创建(函数体内数组),数组名对应一块内存而不是指向,其地址和空间大小在生命周期内保持不变,只有数组的内容可以改变。
  • 指针(非常量指针)可以随时指向任意类型的内存块,它的特性是可变,所以我们常用指针来操作动态内存。

修改内容


  • char a[]=”hello”;a[0] = x;//可以
    • char a[] = {‘h’,’e’,’l’,’l’,’o’};//没有’\0’
  • char *p = “hello”;p[0] = x;//编译通过,运行崩溃

内容复制与比较


  • 不能对数组名进行直接复制与比较,若想把数组a的内容复制给数组b,不能用语句b=a;应该用标准库函数strcpy进行复制。
  • 不能用b==a比较内容是否相等,应该用strcmp
  • 语句p=a并不能把a的内容复制给指针p,而是把a的地址赋给了p。要想复制a的内容,可以先用库函数malloc为p申请一块容量为strlen(a)+1个字节的内存,再用strcpy进行字符串复制。
char a[] = "hello world";int len  = strlen(a);//不包括'\0'char *p = (char *)malloc(sizeof(char)(len+1));//为'\0'预留一个位置strcpy(p,a);

计算内存容量


  • 运算符sizeof可以计算出数组的容量(字节数)。

参数传递


  • 当数组作为函数的参数进行传递时,该数组自动退化为同类型的指针,意思是:在被掉函数中,接收的是一个地址,并没有发生值拷贝,而且原来的数组还是原来的数组。
//错误代码例子void getmemory(char *p, int num)  //这个p是临时的替身{      //p = str = null; p = (char *)malloc(sizeof(char) * num);  //null = malloc}  void test(void)  {   char *str = null;  //str为真身 getmemory(str, 100); // str 仍然为 null    strcpy(str, "hello"); // 运行错误  }   
//正确代码例子void getmemory2(char **p, int num) //送来一个地址{   *p = (char *)malloc(sizeof(char) * num);  //往地址里放货}  void test2(void)  {   char *str = null;   getmemory2(&str, 100); // 注意参数是 &str,而不是str   strcpy(str, "hello");    cout<< str << endl;   free(str);   }   

有了malloc/free为什么还要new/delete


  • malloc与free是c/c++语句的标准库函数,new/delete是c++的运算符
  • 对于非内部数据结构(类的对象),用malloc无法满足动态对象的要求。对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于malloc/free。因此c++需要一个能完成动态内存分配初始化工作的运算符new,和一个能完成清理和释放内存的运算符delete。
  • new: new内置了sizeof、类型转换和类型安全检查功能。new在创建动态对象的同时完成了初始化工作。如果对象有多个构造函数,那么new的语句也有多种形式。
class obj  {   public :  obj(void); // 无参数的构造函数  obj(int x); // 带一个参数的构造函数  …  }  void test(void)  {   obj *a = new obj;   obj *b = new obj(1); // 初值为1   …   delete a;   delete b;  } //如果用new创建对象数组,那么只能使用对象的无参构造函数obj *objects = new obj[100];//创建100个动态对象//不能写成obj *objects = new obj[100](i);//创建100个动态对象的同时赋值1
  • delete:在用delete释放对象数组时
delete []objects; // 正确的用法  delete objects; // 错误的用法 后者相当于delete objects[0],漏掉了另外99个对象。

内存耗尽怎么办


  • 对于32位以上的应用程序而言,无论怎样使用malloc与new,几乎不可能导致“内存耗尽”。我在windows 98下用visual c++编写了测试程序,见示例7。这个程序会无休止地运行下去,根本不会终止。因为32位操作系统支持“虚存”,内存用完了,自动用硬盘空间顶替。我只听到硬盘嘎吱嘎吱地响,window 98已经累得对键盘、鼠标毫无反应。

参考:http://developer.51cto.com/art/201107/272734.htm

原创粉丝点击