在C语言中,或者说在我们平时使用的基本类型中,数组的长度都可以用 sizeof(arr)/sizeof(arr[0]) 来求得。因为sizeof运算符可以求出每个对象所占内存的字节数,并且在这些基本类型组成的数组中,每个元素所占内存空间都是相同的,因此我们可以使用 “数量 = 总价 / 单价” 这种方式来计算。

那么在C++中我们可不可以这样做呢?
请看用例:

可以看到,使用这种方式我们成功求出了strArray中元素的个数。

而我们都知道的string字符串数组中每个string都是可变长度的,按理说使用 string 创建的数组每个元素所占空间大小都是不同的,那为什么仍然可以采用这种方式求成员个数呢?

string对象存储的内容大小与其所占的空间(栈空间)是没有关系的

string类型是个模板类( using string = basic_string<char, char_traits<char>, allocator<char>>; ) ,其中最后一个模板参数指定类申请内存的方式。

一个简答的示例:最初str指向"aa…",数据部分地址在 str.data() 中,str对象地址为str本身。
重新填充数据后,原空间不足以容纳200个’z’将重新申请空间。
在输出的结果中,可以发现。str对象的地址没有改变,只有数据部分地址改变了。

因此可以说string对象存储的内容大小与其所占的空间(栈空间)是没有关系的,因为数据部分存储在堆区中(空间适配器决定),换句话说在一个string的数组中每个string字符串所占的空间相同。

参考如下示例:

string s1[] = { "1" };
string s2[] = { "1","aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" };
string s3[] = { "1","2","3" };
cout << sizeof(s1) << " " << sizeof(s1[0]) << endl;
cout << sizeof(s2) << " " << sizeof(s2[0]) << " " << sizeof(s2[1]) << endl;
cout << sizeof(s3) << " " << sizeof(s3[0]) << " " << sizeof(s3[1]) << " " << sizeof(s3[2]) << endl;
// 输出
// 28 28
// 56 28 28
// 84 28 28 28

我们可以看到,s1所占总空间为 28 字节,而它只有一个成员 “1”,所占空间即为整个数组的空间。
s2所占空间为 56 字节,而它有两个元素,每个元素都占 28 字节,整个数组所占空间为 28 * 2 。
s3所占空间为 84 字节,而它有三个元素,每个元素都占 28 字节,整个数组所占空间为 28 * 3 。

如此以来,我们便可以使用 sizeof(s) / sizeof(s[0]) 来计算string数组的长度了。

string s1[] = { "1" };
string s2[] = { "1","aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" };
string s3[] = { "1","2","3" };cout << "s1 size = " << sizeof(s1) / sizeof(s1[0]) << endl;
cout << "s2 size = " << sizeof(s2) / sizeof(s2[0]) << endl;
cout << "s3 size = " << sizeof(s3) / sizeof(s3[0]) << endl;
探究 _countof 宏函数

C/C++中定义了宏函数 _countof 用于求数组元素个数。

// stdlib.h
#ifndef _countof#define _countof __crt_countof
#endif// vcruntime.h
#ifdef __cplusplusextern "C++"{template <typename _CountofType, size_t _SizeOfArray>char (*__countof_helper(_UNALIGNED _CountofType (&_Array)[_SizeOfArray]))[_SizeOfArray];#define __crt_countof(_Array) (sizeof(*__countof_helper(_Array)) + 0)}
#else#define __crt_countof(_Array) (sizeof(_Array) / sizeof(_Array[0]))
#endif

其中在C语言中,使用的是 __crt_countof(_Array) (sizeof(_Array) / sizeof(_Array[0])) 与我们之前讨论的方法相同。

而在C++中的代码利用了C++模板的特性。
template <typename _CountofType, size_t _SizeOfArray> 这里使用了模板。_CountofType 是我们要求的数组元素的基础类型,_SizeOfArray 是数组所占内存的字节数。

我们可以类比这个宏函数的定义,写一个模板函数:

template <typename Type, size_t size>
void func(Type (&var)[size])    // 引用传参:type被解析成了元素类型,如int,而size被解析成了元素个数。这就像是使用typeid查看数组一样,
{cout << size << endl;
}// 按照模板可以解析参数类型的原理,我们可以写出一个得到数组元素个数的函数。
template <typename Type, size_t size>
inline size_t getLength(const Type (&var)[size])
{return size;
}

string [] 对象遍历

string对象自身提供了一种 s.size() 的方法(等价于length方法),用于获取字符串的长度。可以通过s[0].size()的方式获得其数组中s[0]字符串的长度。

string s[] = { "hello","world!" };
cout << s->size() << endl;       // 等价于s[0].size()
cout << s[0].size() << endl;    // 5
cout << s[1].size() << endl;    // 6

其次,如果我们想要遍历 string [] 形式数组,可以采用以下几种方式:

    string strArray[] = { "hellooooooo","happy","test","xxxx","yy" };// 法一:int size = _countof(strArray);for (int i = 0; i < size; ++i){cout << strArray[i] << " ";}cout << "\n";// 法二:for (string& str : strArray){cout << str << " ";}cout << "\n";// 法三:for (auto it = begin(strArray); it != end(strArray); ++it){cout << *(it) << " ";}cout << "\n";
使用 vector 数组代替 string [] 数组

对于vector类型,这是一种数组类型,它提供了 v.size() 方法可以获取数组长度。

vector<vector<int>> v{ {1,2,3},{4,5,6,7,8},{9,10} };
cout << v.size() << endl;       // 3
cout << v[1].size() << endl;    // 5

vector类型是一种容器适配器,其本身就是数组类型,因此类中提供了获取元素个数的方法。

而string类型同int类型,double类型一样可以作为一种基本的类型,封装到vector数组中使用。

C++ 中string数组怎么求长度(元素个数)相关推荐

  1. php在指定html元素中输出,如何从PHP中的数组输出html svg元素?

    我有svg元素的数组.我必须从列出的阵列中打印出来.我试图打印它,但它不工作.请指导我如何获取浏览器上呈现的svg元素. actualy有阵列中的其他项目我没有表现出bcoz的字符限制如何通过SVG标 ...

  2. 在表中查找数组为x的元素

    线性表(a1,a2,a3--an)中的元素递增有序且按顺序存储于计算机中,设计一算法,在表中查找数组为x的元素,若找到则将其与后继元素位置交换,找不到则插入x并依然递增有序 思路:为了加快查找速度,这 ...

  3. Java中String数组的排序

    使用Java compareToIgnoreCase 方法排序 这个方法我在上一篇文章已经说过如何使用了,也说明了它的原理 我们可以看一看:点击查看https://blog.janyork.com/i ...

  4. java中String数组的使用

    string数组的定义有三种: String arr[] = new String[10]; //创建一个长度为10的String 类型数组. String arr[] = {"张三&quo ...

  5. 在JavaScript中找到数组的最小/最大元素

    如何轻松获得JavaScript数组的min或max元素? 伪代码示例: let array = [100, 0, 50]array.min() //=> 0 array.max() //=&g ...

  6. java数组包含某个元素_java中判断数组是否包含某元素的方法

    有两种方法可以判断数组是否包含元素: 方法1, 将数组转换为list,然后使用list的contains方法来判断:Arrays.asList(...).contains(...) java.lang ...

  7. java字符串长度_Java中String字符串的最大长度?

    1.Java中的字符串String最大长度,编译期如果是javac编译就是65534.如果绕过javac编译的限制,其最大长度可以达到u2类型变达的最大值65535. Oracle JDK的编译工具J ...

  8. 统计list里面相同元素个数_Array篇easy难度之求相同元素个数

    题目描述 https://leetcode.com/problems/number-of-good-pairs/ Given an array of integers nums.A pair (i,j ...

  9. python:无序数组中寻找第K大的元素

    题目: 所谓"第(前)k大数问题"指的是在长度为n(n>=k)的乱序数组中S找出从大到小顺序的第(前)k个数的问题. 解法1:堆排序 采用元素下沉法,维护一个k大小的最小堆, ...

最新文章

  1. 解决android.permission.WRITE_APN_SETTINGS
  2. 程序员懂点经济学-股票投资
  3. python大神交流网站_学习Python必去的8个网站
  4. linux的基础知识——捕捉SIGCHLD、信号传参,中断系统调用
  5. 动动手指头, Feed 流系统亿级规模不用愁
  6. (转)C++ main函数中参数argc和argv含义及用法
  7. 刚刚做了一个菜单导航变亮的效果,共享一下吧!
  8. python input函数无法输入字符串_python input输入函数
  9. 到底是什么反射,泛型,委托,泛型
  10. rap2检测哪些接口在使用_使用四合一气体检测仪应注意哪些方面?-逸云天
  11. java 传递intent_intent传递参数
  12. 使用jsp实现成语接龙
  13. 服务器搬迁方案_服务器数据迁移方案
  14. 【Qt】Qt 开发环境安装 ( Qt 版本 5.14.2 | Qt 下载 | Qt 安装 )
  15. 针对Sql Server中进行查询操作时提示“对象名无效”
  16. unity 打开项目路径无效_怎么打开已有的unity工程文件?如何打开一个已有的unity3d游戏工程啊?...
  17. 2021年终总结——工作第四年
  18. Zeloof 自制芯片工艺
  19. 盘点40余款好用的项目管理软件
  20. 图形学扫描线填充算法

热门文章

  1. linux僵尸进程理解,Linux僵尸进程详细解析
  2. 微信自动化,可以不可以?发送关键字邀请你加入群聊
  3. 华为Mate30你会入手吗?未采用2K屏幕引争议,主要考虑4个方面
  4. Android ANR是什么?
  5. Apache Tomcat配置启动
  6. 巧用Word2003制作树状结构图(转)
  7. 如何将Adobe Photoshop CS4 汉化
  8. 2021年化工自动化控制仪表考试技巧及化工自动化控制仪表证考试
  9. java currenttimemillis 用4个字节存储
  10. 猿创征文|Android kotlin实现九宫格解锁