数组与指针

 

 

数组与指针是内存管理的关键,也是C/C++中较难掌握的的地方。现在对其进行一些分析与总结。

 

 一。内存分配方式有四种:


        1.从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的
          整个运行期间都存在。例如全局变量,static 变量,即使是局部static变量(即函数内部定义的static变量)。

          如:

          const char *func()

          {

               static char res[256]={0};

               ...

               return res;  // this is correct.

          }


        2.在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函
         数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集
         中,效率很高,但是分配的内存容量有限。

          const char *func()

          {

               char res[256]={0};

               ...

               return res;  // this is wrong.

          }

 


       3.从堆上分配,亦称动态内存分配。程序在运行的时候用malloc 或new 申请任意多
          少的内存,程序员自己负责在何时用free 或delete 释放内存。动态内存的生存期
          由我们决定,使用非常灵活,但问题也最多。堆内存的释放必须用free或delete显式释放,

         否则要等到程序结束后由操作系统负责收回。

         const char *func()

          {

               char* res=new char[256];

               ...

               return res;  // this is correct.

          }

 

      4.文字常量区。常量就放在这里,即使是局部定义的常量也放在文字常量区,内容不可以被更改,如常量字符串,一直到程序结束后才由系统释放。例如:

                const int* func(void)
                {
                    const int x=2;
                    return &x;
               }


              const int *y=func();

              cout<<*y<<endl;// result is 2.

 

 

二。数组与指针的特点分析:
        数组的特点分析:

        1.数组长度必须在编译时确定;

        2.数组长度不可变;

        3.数组存在于栈中,只在定义它的语句块内存在;

        4.数组名表示数组第一个元素的地址(它也是指针,也是迭代器,但只能作为右值),但是用sizeof操作符计算其大小是该数组所占的字节数,而不是数组名本身的字节数,唯一的例外是当数组作为函数的参数传递时,数组名自动退化为同类型的指针。例如:

           int a[10];

           cout<<sizeof(a)<<endl;// result is 40

           void func(int  a[10])

           {

               cout<<sizeof(a)<<endl;//result is 4

           }

           动态分配数组返回的指针的特点分析:

           1.数组长度在编译时不需要知道;

           2.一旦分配,数组长度不可变;

           3.存在堆中,除非显示地释放,它一直存在,即使程序已经结束;

           4.无数组名,只有返回的指针。该指针跟一般指针完全一样,如用sizeof 操作符计算其大小,得到是该指针所占内存(32位系统中,指针占4位),而不是其指向的数组所占的内存。如:

            int a[10];

            int *p=a;

           cout<<sizeof(p)<<endl;// result is 4

            p=new int[10];

            cout<<sizeof(p)<<endl;// result is 4

 

          一般指针的特点分析:

          C/C++中无法知道指针所指内容的内存容量,而只能知道指针本身所占的内存。

          sizeof( 指针名)永远为4(在32位系统中),而不管指针指向的是不是数组,指向的内存在堆内还是在栈内。

 

三。C-风格字符串:

        1.C风格字符串:

           以空字符null结束的字符数组即为C风格字符串。

        2.字符串字面值:

            (1)类型:const char*,即不可更改的字符串。

            (2)存储位置及生命期:存储在文字常量区,一直到程序的结束。

            (3)与数组关系:可以初始化(const char 或char型)数组,实质就是拷贝初始化,因此初始化后数组与文字常量区中的该字符串字面值无关了。

                      如:char a[]="hello world";

                              a[0]='s';// ok

                      又如:

                      char *GetString(void)
                      {
                          char p[] = "hello world";
                          return p; // 编译器将提出警告
                      }

                     char *str = NULL;
                      str = GetString(); // str 的内容是垃圾,注意函数返回后,str不为NULL,但其指向的栈内存已经被释放了。

                    

 

            (4)与指针关系:可以初始化或赋值给const char* 或char* 类型的指针,此指针指向的是文字常量区中的字面值常量的地址,因此不可以通过该指针修改其内容,

                      而且其内容和地址知道程序结束均不变。

                     如:char *p="hello world";

                              p[0]='s';// error

                    char *GetString(void)
                      {
                          char *p = "hello world";
                          return p;                      

                      }

                     char *str = NULL;
                      str = GetString(); // str 的内容是"hello world", 但注意str指向的是文字常量区里字面值的指针。

 

        3.C风格字符串的标准库函数:

            标准库strting.h里的以str开头的函数均是C风格字符串的标准函数。

            这些函数要求C风格字符串:以NULL结尾的字符数组,接受char型数组名或char*型指针。

        4. strlen与sizeof 的区别:

           (1)strlen 只接受char* 型指针或char型数组名,而sizeof 接受任何类型的对象或任何类型名;

           (2)strlen对char* 指针和char型数组名是完全一样的,而sizeof 对指针和数组名是不一样的:对指针结果为4,对数组名结果是该数组所占的内存空间;

           (3)strlen计算C风格字符串的长度,不包括最后的null字符,而sizeof对char型数组名计算的长度包括最后的Null字符。

 

 

 

  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值