前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >论C++如何优雅的使用数组

论C++如何优雅的使用数组

作者头像
sunsky
发布2020-08-20 10:30:57
1.1K0
发布2020-08-20 10:30:57
举报
文章被收录于专栏:sunsky

C/C++中如果一个函数接受一个数组作为参数,那么数组将会被退化为指针,如果定义如下代码:

代码语言:c++
复制
//数组arr的大小未知。
int arrsize(int arr*) {
  cout << "element num : " << sizeof(arr) / sizeof(arr[0]) << endl; //1
}

在上面那段代码中不仅得到的数组大小是不正确的,还会出现让调用则不明白是传递int变量的地址,还是传递一个指针(数组),为了解决第二个歧义现象,我们可以定义如下:

代码语言:c++
复制
//数组arr的大小依旧未知。
int arrsize(int arr[]) {
  cout << "element num : " << sizeof(arr) / sizeof(arr[0]) << endl; //1
}

即使我们按上面那种定义,但数组的的大小我们依旧不知道,但现在编译器还会提示类似如下警告:

代码语言:text
复制
 warning: ‘sizeof’ on array function parameter ‘arr’ will return size of ‘int*’ [-Wsizeof-array-argument]

为了更好的解决上面的问题我们可以考虑使用一个引用形参,可以有如下代码:

代码语言:c++
复制
//数组arr的大小必须是12,否则会报错。
int arrsize_const_size(int (&arr)[12]) {
  cout << "element num : " << sizeof(arr) / sizeof(arr[0]) << endl;//12
}

即使我们使用引用形参解决了,在函数内部我们无法正确获取数组大小的问题,但更复杂的问题出现了,我们只能接受固定数量的大小的数组,解决这个问题,我们可以通过一种很常规的手法定义函数如下:

代码语言:c#
复制
 //指定一个数组大小n
int arrsize_n(int arr[], int n) {

}

上面虽然解决了,但我们多传递了一个参数,调用代码看起来没有前两个更加简洁了,虽然问题被很好的解决了,为了更好的解决这个问题我们可以把推断数组大小的事交个编译器,使用非类型模板参数。

代码语言:c++
复制
template<int n>
int arrsize_template_size(int (&arr)[n]) {
  cout << "element num : " << sizeof(arr) / sizeof(arr[0]) << endl;//12
  cout << "n : " << n << endl;//12
  for (int i = 0; i < n; i++) {
    cout << "arr[" << i << "] = " << arr[i] << endl;
  }
  return 0;
}

下面给出完整的测试代码:

代码语言:c++
复制
#include <iostream>

using namespace std;


//数组arr的大小未知。
int arrsize(int arr[]) {
  cout << "element num : " << sizeof(arr) / sizeof(arr[0]) << endl;//1
  return 0;
}
//数组arr的大小必须是12,否则会报错。
int arrsize_const_size(int (&arr)[12]) {
  cout << "element num : " << sizeof(arr) / sizeof(arr[0]) << endl;//12
  return 0;
}

//指定一个数组大小n
int arrsize_n(int arr[], int n) {
  return 0;
}

template<int n>
int arrsize_template_size(int (&arr)[n]) {
  cout << "element num : " << sizeof(arr) / sizeof(arr[0]) << endl;//12
  cout << "n : " << n << endl;//12
  for (int i = 0; i < n; i++) {
    cout << "arr[" << i << "] = " << arr[i] << endl;
  }
  return 0;
}

int main() {

  int arr[12] = {
    1, 2, 3, 4,
    5, 6, 7, 8,
    9, 10, 11, 12,
  };
  int arr1[16] = {
    1, 2, 3, 4,
    5, 6, 7, 8,
    9, 10, 11, 12,
    13, 14, 15, 16,
  };

  arrsize(arr);
  arrsize_const_size(arr);
  cout << "-------------------------------------" << endl;
  arrsize_template_size(arr);
  cout << "-------------------------------------" << endl;
  arrsize_template_size(arr1);
  cout << "-------------------------------------" << endl;
  return 0;
}如果array类型也是复用的话,那么就有最终版本:
代码语言:javascript
复制
template<typename T,int n>
        void print_arr_in_tpl(T (&arr)[n]){
            std::cout << "element num : " << sizeof(arr) / sizeof(arr[0]) << std::endl;//
            for(int i=0;i<n;++i){
                std::cout<<arr[i]<<std::endl;
            }
        }

哈哈, 大家拿去用吧

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017-10-22 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档