C++对数组的引用实例分析

 更新时间:2014年08月18日 10:11:43   投稿:shichen2014  
这篇文章主要介绍了C++对数组的引用实例分析,需要的朋友可以参考下

C++中所谓数组引用,即指向数组的引用;
如:

int  a[10] ;  
int  (&b)[10] = a ;

如果写成:

int  a[10] ;
int* &b = a ;

系统将会报错: cannot convert from 'int [10]' to 'int *&'。
  
或许你会说在数组名不就是指向这个数组的一个指针吗?题中a是int*类型的,b是指向int*的引用,按理应该是正确的啊,为什么会报错呢?这是因为编译器对指向数组的引用检查更加严格,需要检查数组的维数,在这里a被理解成指向10个int数组的指针int [10],对于引用也需要相应的引用类型int (&)[10],即指向10个int数组的指针的引用。

c和c++中有一个“数组降价”问题。如下所示:

#include <iostream>
void test( char arr[100] )
{
   std::cout << sizeof(arr) << std::endl ; // 输出 4
}
int main()
{
  char arr[100] = { 0 };
  std::cout << sizeof(arr) << std::endl; // 输出 100 
  test( arr );

  return 0 ;
}

这段代码的输出是:
100
4

对于同样的arr,一个输出100,另一个输出4。是因为void test( char arr[100] )中的arr被降价了。
void test( char arr[100] ) 中的arr被降阶处理了,
void test( char arr[100] ) 等同于void test( char arr[] ), 也等同于void test( char* const arr ) 如果你原意,它甚至等同于void test( char arr[10] )

编译器对数组的维数不作检查。也就是说:

void test( char arr[100] )
{
   std::cout << sizeof(arr) << std::endl;
}

被降成

void test( char* const arr )
{
   std::cout << sizeof(arr) << std::endl; // 既然是char*,当然输出4
}

这样,即然不检查数组的大小,对于需要保证数组大小的程序就会带来问题。如何解决这个问题呢?可以用c++中的对数组的引用。

看下面这段代码:

......
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 );
......

这样test就能接受100个char的数组,且只能接受大小为100的char数组。

如果:

char arr[20] = {0};
test( arr ) ;

就会报错

在C++中,对数组的引用可以直接传递数组名,因为数组的大小的信息已在形参里提供了。但是这样一来我们只能固定数组的大小来用这个函数了。用模板加数组的引用可以解决这个问题,看如下代码:

template <int sz>
void test(char (&arr)[sz])
{
  for ( int i = 0; i < sz; i++ )
......}
char a[2] = { 0 }, b[15] = { 0 };
test(a);  //ok
test(b);  //ok......

这样解决了数组长度可变的问题,但也引入了新的问题:

(1)当有多个不同的test调用时,会产生多份test代码。而传统的函数调用只有一份代,也调用的次数无关。
(2)由于这些代码都是在编译阶段生成的,它需要知道引用数组的大小。所以这样写的函数显然不能用指针变量作为函数的参数,因此不能用这个函数处理动态分配的内存区域,这样的区域的大小是在运行时确定的。

相关文章

  • OpenCV利用霍夫变换进行直线检测

    OpenCV利用霍夫变换进行直线检测

    这篇文章主要为大家详细介绍了OpenCV利用霍夫变换进行直线检测,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-12-12
  • c++ 面向对象设计五大原则

    c++ 面向对象设计五大原则

    这篇文章主要介绍了c++ 面向对象设计五大原则,帮助大家更好的理解和学习c++面向对象设计,感兴趣的朋友可以了解下
    2020-08-08
  • C++用mysql自带的头文件连接数据库

    C++用mysql自带的头文件连接数据库

    现在正做一个接口,通过不同的连接字符串操作不同的数据库。要用到mysql数据库。通过网上的一些资料和自己的摸索,大致清楚了C++连接mysql的方法。可以通过2种方法实现。第一种方法是利用ADO连接,第二种方法是利用mysql自己的api函数进行连接。今天主要来讲解下使用API
    2016-07-07
  • 使用c语言输出杨辉三角形的简单方法

    使用c语言输出杨辉三角形的简单方法

    这篇文章主要给大家介绍了关于如何使用c语言输出杨辉三角形的简单方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-03-03
  • C语言 野指针与空指针专篇解读

    C语言 野指针与空指针专篇解读

    全网最接地气的C语言野指针介绍,此处对于野指针与空指针知识点做一些简要的介绍,作者实属初学,写博客也是作者学习的一个过程,难免文章中有内容理解不到位或者有不当之处,还请朋友们不吝指正,希望大家多多给予支持,赠人玫瑰,手有余香
    2021-11-11
  • Visual Studio C++指针靠前靠后的问题全面解析

    Visual Studio C++指针靠前靠后的问题全面解析

    这篇文章主要介绍了Visual Studio C++指针靠前靠后的问题全面解析,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-04-04
  • C++内存池两种方案解析

    C++内存池两种方案解析

    这篇文章主要详情介绍了C++内存池两种方案做对比,对此感兴趣的小伙伴一起来看看吧
    2021-08-08
  • C++中虚表是什么意思(概念及示例)

    C++中虚表是什么意思(概念及示例)

    虚函数表,以及虚函数指针是实现多态性(Polymorphism)的关键机制,这篇文章主要介绍了C++中虚表是什么意思(概念及示例),需要的朋友可以参考下
    2024-03-03
  • 基于C++实现高精度计时器

    基于C++实现高精度计时器

    chrono是C++ 11中的时间库,它提供了跨平台的高精度时钟解决方案,精确到纳秒级,本文主要为大家详细介绍了如何使用chrono实现高精度计时器,感兴趣的可以了解下
    2024-02-02
  • C++文件输入输出fstream使用方法

    C++文件输入输出fstream使用方法

    C++标准库提供了<fstream>头文件,其中包含了用于文件输入输出的相关类和函数,本文将详细介绍<fstream>头文件的使用方法,包括函数原型、打开文件、读取和写入文件、以及错误处理等注意事项,感兴趣的朋友跟随小编一起看看吧
    2023-10-10

最新评论