第四章:数组、vector与字符串(二)

本文详细介绍了C++中数组的基本操作,包括使用sizeof和std::size计算数组元素个数,以及通过begin和end迭代数组元素。同时,讲解了C风格字符串的特性及常用函数,如strlen和strcmp。还深入探讨了多维数组的初始化、索引和遍历,并指出多维数组可以隐式转换为指针。最后提到了数组与指针在多维情况下的交互和遍历方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

数组

其他操作

与数组相关的还有一些其他的操作

  • 求数组中元素的个数

    1. sizeof
      int a [3];
      sizeof(a)/sizeof(int);				// 使用sizeof数组没有退化成指针,获取到的是数组所占用的内存大小
      
    2. std::size
      int a[3];
      std::size(a)// 直接获取数组内元素的个数
      
    3. (c)end - (c)begin
      int a[3];
      std::cend(a) - std::cbegin(a);		// 直接获取数组内元素的个数
      

    以上所有的求数组元素个数的操作都只能针对数组操作,不能针对指针或者不完整类型的数组

    前两种方法数组尺寸是编译期获取的,而最后一个方法是在运行期获取的,所以不推荐使用最后一种方法。而前两种方法中sizeof方法需要针对特定类型做除法,不易于修改,所以三种方法中最推荐使用std::size

  • 遍历数组中的元素

    1. 基于元素个数
      int a[4] = {2,3,5,7};
      size_t index = 0;
      while(index < std::size(a)){
      	std::cout << a[index] << std::endl;
      	index = index + 1;
      }
      
    2. 基于(c)begin(c)end
      int a[4] = {2,3,5,7};
      auto ptr = std::cbegin(a);
      while(ptr != std::cend(a)){
      	std::cout << *ptr << std::endl;
      	ptr = ptr + 1;
      }
      
    3. 基于范围的for循环
      int a[4] = {2,3,5,7};
      for(int x:a){
      	std::cout << x << std::endl;
      }
      

C字符串

C风格的字符串本质上也是一个数组,比如

char str[] = "Hello";		// 类型为char[6]

末尾加\0主要是为了在运行期使用指针形式对字符串操作时获取字符串的长度

C语言额外提供了一些函数来支持C风格字符串的相关操作

  • strlen:求字符串长度
    char str[] = "Hello";
    strlen(str);				// 定义在cstring头文件中
    
  • strcmp:判断字符串是否相等
  • 其他操作

以上所有的操作都需要末尾的\0的支持,所以在声明C风格字符串的时候建议使用字符串来初始化而不是使用字符列表

多维数组

多维数组的本质是数组的数组,比如

int a[3][4];			// 数组中包含3个元素,每个元素的类型是一个int[4]的数组

多维数组的初始化方式有以下几种

  • 缺省初始化
  • 单层大括号初始化
    int x[3][4] = {1,2,3,4,5};	//	按照行主序,按顺序填充,省下的为0
    
  • 多层大括号初始化
    int x[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}}// 对每一行单独进行一个大括号初始化,方式与单维数组相同
    
  • 自动推导初始化
    int x[][3] = {1,2,3,4};			//类型为int[2][3]
    

    注意必须给定后面维的大小,只能省略第一维的大小

我们可以对多维数组进行索引和遍历

  • 使用多个中括号进行索引
  • 使用多重循环来遍历
    int x[3][4] = {1,2,3,4,5};
    for(auto &p:x){
    	for(auto q:p){
    		std::cout << q << std::endl;
    	}
    }
    

    第一个循环必须带&符号,因为如果不带的话p的类型就不是int[4]而是int*了,我们就没有办法对他使用基于范围的for循环了

数组可以隐式转换为指针,多维数组同样可以隐式转换为指针,但是只有最高维会进行转换,其他维度的信息会被保留,比如

int x[3][4];
auto ptr = x;				// 类型为int (*) [4]

我们可以使用类型别名来简化多维数组指针的声明,比如

using A = int[4];

int x[3][4];
A * ptr = x;

A x1[3];		// 类型为int[3][4]而不是int[4][3]

同样,指针也可以被用来遍历多维数组,比如

int x[3][4];
auto ptr = std::begin(x);
while(ptr != std::end(x)){
	auto ptr2 = std::begin(*ptr);
	while(ptr2 != std::end(*ptr)){
		std::cout << *ptr2 << std::endl;
		ptr2 = ptr2 + 1;
	}
	ptr = ptr + 1;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值