【C++の相关概念】静态数组[]和动态数组new的区别

参考:
C++ 静态数组([])和动态数组(new)的区别
C++对数组的引用实例分析

存储和运行方式new

new在堆分配空间,效率较低,还需要你delete;
[]直接在栈上分配,会自动释放,效率高,但是栈空间有限。

使用sizeof运算

int a[5]; 
sizeof(&a)=4;
//int a[5];在编译阶段分配空间
//sizeof(a);同样在编译阶段执行
sizeof(a)=5*4;
sizeof(*a)=4;
//因为整个数组共占20字节
//首个元素(int型)占4字节。

//同理
int a[4][5];
sizeof(&a)=4;
sizeof(a)=4*5*4=80;
sizeof(a[0])=5*4=20;
sizeof(a[0][0])=4;

int *a=new int[4];
//int *a=new int[4];在运行分配空间
//sizeof(a);只在编译阶段执行,所以只能得到指针大小为4
sizeof(a)=sizeof(*a)=4
//因为地址位数为4字节
//int型也占4字节。

作为函数形参

数组引用会检查数组维数

//正确
int  a[10] ;  
int  (&b)[10] = a ;

//错误:cannot convert from 'int [10]' to 'int *&'。
int  a[10] ;
int* &b = a ;

数组作为参数传递会进行“数组降价”
即编译器对数组的维数不作检查

#include <iostream>
//void test( char arr[100] ) 等同于 void test( char arr[] )
//也等同于void test( char* const arr )
//所以你甚至可以往数组内传递arr[20]
void test( char arr[100] )
{
   std::cout << sizeof(arr) << std::endl ; // 输出 4
}
void main()
{
  char arr[100] = { 0 };
  std::cout << sizeof(arr) << std::endl; // 输出 100 
  test( arr );
}

避免参数传递而导致“数组降价”的方法1:

......
//使用常量引用数组,但这样数组长度就只能固定不动了
void test( const char (&arr)[100] )
{
   std::cout << sizeof(arr) << std::endl ; // 输出 100
}
......
  char arr[100] = { 0 };
  std::cout << sizeof(arr) << std::endl; // 输出 100 
  test( arr );
......

//错误!
char arr[20] = {0};
test( arr ) ;

避免参数传递而导致“数组降价”的方法2:

//虽然使用模板可以使数组长度可变,但是有以下问题:
//1.当有多个不同的test调用时,会产生多份test代码。
//  而传统的函数调用只有一份代,也调用的次数无关。
//2.不能传入动态分配的指针变量,因为模板函数在编译阶段
//  就需要确定数组的大小,从而生成代码,而指针变量
//  是在运行阶段才得以执行
template <int sz>
void test(char (&arr)[sz])
{
  for ( int i = 0; i < sz; i++ )
......}
char a[2] = { 0 }, b[15] = { 0 };
test(a);  //正确
test(b);  //正确

作为函数返回值

函数声明的静态数组不可能通过函数返回,因为生存期的问题,函数调用完其内部变量占用的内存就被释放了。如果想通过函数返回一个数组,可以在函数中用new动态创建该数组,然后返回其首地址。
其原因可以这样理解,因为[]静态数组是在栈中申请的,而函数中的局部变量也是在栈中的,而new动态数组是在堆中的分配的,所以函数返回后,栈中的东西被自动释放,而堆中的东西如果没有delete不会自动释放。

//正确
int* test(){
	int* b = new int[5];
	return b;
}

//错误
int* test(){
	int b[5];
	return b;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值