多维数组的索引越界问题

1、我们大都知道可以使用vector或array模板作为线性数组的实现,那么对于需要二维矩阵、三维数组(或者N维数组)时应该怎么解决。

由于N维数组的基本情况中的所有问题都可以用一个二维矩阵举例说明,因此以下的讨论仅限于此,并简单的称为矩阵。

如果矩阵的大小在编译时是已知的,可以很方便的把它实现为数组的数组,这个很简单。这里,我们主要把注意力集中在当矩阵的大小是在运行时计算产生,对于这种复杂的情况,我们可以很方便的使用vector或的vector来实现。事实上,如果不同的行必须必须具有不同的长度,这也是唯一可行的方法。但是,在大多时候,所有的行应该具有相同的长度,此时使用vector的vector是一种效率不高的方法:它需要多次分配内存,这是相对较慢的操作。由于我们使用C++的一个重要原因是追求高效,因此我们尝试一种不同的方法,即只通过一次内存分配来创建一个长方形的矩阵。

示例代码:

//二维长方形矩阵
template <typename T>
class matrix
{
public:
	typedef unsigned size_type;

	matrix(size_type num_rows, size_type num_cols)
		:rows_(num_rows),cols_(num_cols),data_(num_rows*num_cols)
	{
		SCPP_TEST_ASSERT(num_rows > 0,
			"Number of rows in a matrix must be positive");
		SCPP_TEST_ASSERT(num_cols > 0,
			"Number of columns in a matrix must be positive");
	}

	matrix(size_type num_rows, size_type num_cols, const T& init_value)
		:rows_(num_rows),cols_(num_cols),data_(num_rows*num_cols,init_value)
	{
		SCPP_TEST_ASSERT(num_rows > 0,
			"Number of rows in a matrix must be positive");
		SCPP_TEST_ASSERT(num_cols > 0,
			"Number of columns in a matrix must be positive");
	}

	size_type num_rows() const { return rows_; }
	size_type num_cols() const { return cols_; }

	//访问方法:返回由行和列所指定的元素
	T& operator() (size_type row, size_type col)
	{
		return data_[index(row,col)];
	}

	const T& operator() (size_type row, size_type col) const
	{
		return data_[index(row,col)];
	}

private:
	size_type rows, cols;
	std::vector<T> data_;

	size_type insex(size_type row, size_type col) const
	{
		SCPP_TEST_ASSERT(row < rows_, "Row " <<row<<" must be less than "<<rows_);
		SCPP_TEST_ASSERT(col < cols_, "Column  " <<col<<" must be less than "<<cols_);
		return cols_* row + col;
	}
};

首先,这个类中有2个构造函数。第一个构造函数允许我们用指定的行数和列数创建一个矩阵。第二个构造函数具有一个额外的init_value参数,允许把每个元素初始化为一个指定的值(例如,把一个matrix<double>的每个元素设置为0.0)。注意,对元素的访问时通过()操作符进行的。这是因为C++的[]操作符只接受1个参数,不能接受2个参数或更多的参数。因此,为了访问多维数组,我们或者使用多个[](例如my_matrix[i][j]),或者使用1个()操作符(例如my_matrix(i,j))。

如果我们让[]操作符返回指向第i行第0个元素的T*类型的指针,就可以实现第一种方法。但是,这样就无法诊断列索引越界的问题,违背了在运行时捕捉缺陷的初衷。当然,我们可以创建一些模板类,包括一个指向一个列的智能引用,并使用第一个操作符([i])返回它的一个实例,并在第二个操作符([j])中使用边界检查。在某种程度上,这是因人的习惯。我们看不到仅仅为了保留my_matrix[i][j]的语法而采用这种复杂设计的价值,显然具有多个参数的()操作符看上去更为直观。

对索引越界的检查是在index(row,col)函数中执行的,这两个参数分别表示行数和列数。如果出现了运行时错误,就会导致一个错误处理函数被调用。

最后,在示例代码最后,提供一个matrix<T>模板的<<操作符,是为了输出矩阵:

cout<<"my matrix = \n"<<my_matrix<<endl;

但是,前提是这个矩阵不能太大,并且类型T定义了<<操作符。

总结:避免“索引越界”的规则:

  • 不要使用静态或动态分配的数组,可以改用array或者vector模板
  • 不要使用带方括号的new和delete操作符,让vector模板为多个元素分配内存
  • 使用scpp::vector代替std::vector,使用scpp::array代替静态数组,并打开安全检查
  • 对于多维数组,使用scpp::matrix,并通过()操作符访问元素,已提供索引越界检查。

多维数组的索引越界问题,布布扣,bubuko.com

时间: 2024-10-12 18:36:11

多维数组的索引越界问题的相关文章

多维数组会有一维索引吗?

前两天.net老师讲数组,发现了个方法,Array.Clear(). 里面有三个参数 Array array,int index,int length,他们分别是 array类型的相关类,清除的起始索引,清除长度. 看似好像没什么可想象的.但后来发现这个函数居然有重载,那么问题来了,既然没有重载,那么多维数组咋整啊? 大家都知道多维数组的索引肯定不止一个整数,索引数会根据维度的增加而增多的.比如一个二维int[5,5],我要想 从2,3开始清除怎么办呢?这个方法能不能用呢,结果试了下.测试数组如

关于json_encode一个二维数组,返回一个数组对象还是对象对象

$users = array( '1'=>array('id'=>1,'age'=>'1'), '2' => array('id'=>2,'age'=>'2'), 这个二维数组的索引值若果是从1开始,返回的就是对象对象 <?php $users = array( array('id'=>1,'age'=>'1'), array('id'=>2,'age'=>'2'), array('id'=>3,'age'=>'3'), arr

php中foreach循环遍历二维数组

最近在用tp3.2框架,在查询的时候用到了select(),这条语句返回的是二维数组,所以在对返回的数据做处理时,遇到了些麻烦,百度了下foreach,终于用foreach解决了数据的筛选问题 (因为不知道该怎么设置where条件,设置只显示Jdate字段中今天以后的数据,所以只能在select查询后的数据中进行筛选..基础没大佬,真的挺麻烦) 进入正题 官方文档中给了foreach的两种用法 foreach 语法结构提供了遍历数组的简单方式.foreach 仅能够应用于数组和对象,如果尝试应用

动态数组索引越界问题

1.在C++中,可以采用几种不同的方法创建一个某种类型T的对象的数组.3种常用的方法如下: #define N 10 //数组的长度N在编译时已知 T static_array[10]; int n = 20; //数组的长度n是在运行时计算的 T* dynamic_array = new T[n]; std::vector<T> vector_array; //数组的长度可以在运行时进行修改 当然,我们仍然可以使用calloc()和malloc()函数,并且这样的程序仍然能够通过编译并顺利运

php删除二维数组的空值并重新建立数字索引

<?php$arr=[0=>"p",1=>"a",2=>"b",3=>"c",4=>"",5=>"d",6=>""];$arr2=array(0=>"p",1=>"a",2=>"b",3=>"c",4=>&quo

创建二维数组(一维长度3,二维长度6),值为一维数组和二维数组索引值的积,

<!DOCTYPE HTML><html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><title>二维数组</title><script type="text/javascript">var myarr = new Array(); for (var i = 1

numpy中多维数组的绝对索引

这涉及到吧多维数组映射为一维数组. 对于3维数组,有公式: def MAP(x,y,z): return y_s * z_s * x + z_s * y + z 此公式可以推广到N维 测试代码:(两个输出相同,说明测试成功) import numpy as np x_s=4 y_s=3 z_s=9 def MAP(x,y,z): return y_s * z_s * x + z_s * y + z org=np.arange(x_s*y_s*z_s) arr=np.resize(org,[x_s

JAVA:二维数组

一.二维数组相关语法 /* 二维数组:就是元素为一维数组的一个数组. 格式1: 数据类型[][] 数组名 = new 数据类型[m][n]; m:表示这个二维数组有多少个一维数组. n:表示每一个一维数组的元素有多少个. 注意: 以下格式也可以表示二维数组 a:数据类型 数组名[][] = new 数据类型[m][n]; b:数据类型[] 数组名[] = new 数据类型[m][n]; */ class Array2Demo { public static void main(String[]

Delphi-基础(常量、集合、数组[动态数组、多维数组])

一.常量 1.常量定义:一开始定义好的值,以后在程序的运行过程中不允许改变 1 const 2 Pi : Double = 3.141592; //定义为常量 3 {常量的定义方式,可以不进行类型的声明,编译器会根据具体值决定常量的的类型} 4 Pi2 = 3.1415; 2.常量使用 枚举:常量集 type 枚举名=(标识符1,标识符2,标识符3,......) 1 type 2 {正常情况下,枚举类型的索引是从0开始} 3 EColors = (RED,GREEN,BLUE); 4 EWee