动态创建二维vector数组 C和C++ 及指针与引用的区别
二维vector
vector<vector <int> > ivec(m ,vector<int>(n)); //m*n的二维vector
动态创建m*n的二维vector
方法一:
vector<vector <int> > ivec;
ivec.resize(m);
for(int i=0;i<m;i++) ivec[i].resize(n);
方法二:
vector<vector <int> > ivec;
ivec.resize(m,vector<int>(n));
动态创建二维数组a[m][n]
C语言版:
#include<malloc.h>
int **a=(int **)malloc(m*sizeof(int *));
for(int i=0;i<m;i++)
a[i]=(int *)malloc(n*sizeof(int));
C++版:
int **a=new int*[m];
for(int i=0;i<m;i++) a[i]=new int[n];
初始化二维数组
vector<vector <int> > ivec(m ,vector<int>(n,0)); //m*n的二维vector,所有元素为0
C++中用new动态创建二维数组的格式一般是这样:
TYPE (*p)[N] = new TYPE [][N];
其中,TYPE是某种类型,N是二维数组的列数。采用这种格式,列数必须指出,而行数无需指定。在这里,p的类型是TYPE*[N],即是指向一个有N列元素数组的指针。
还有一种方法,可以不指定数组的列数:
int **p;
p = new int*[]; //注意,int*[10]表示一个有10个元素的指针数组
for (int i = ; i != ; ++i)
{
p[i] = new int[];
}
这里是将p作为一个指向指针的指针,它指向一个包含10个元素的指针数组,并且每个元素指向一个有5个元素的数组,这样就构建了一个10行5列的数组。 当数组使用完毕,释放空间的代码是:
for(int i = ; i != ; i++)
{
delete[] p[i];
}
delete[] p;
处理二维数组,可以用降维或是二维法。
降维法是用一位数组来接受二维数组,将二维元素的首地址&a[][]作为参数,传递给函数,函数用int *接受。
二维法就直接用二维数组来接受,但是需要指定列数。 如要想创建一个[m][n]的二维数组。
下面为通过动态创建一个指针数组的方法来动态创建二维数组的方法。
C版本:
double **data;
data = (double **)malloc(m*sizeof(double *));
for(int j=;j<m;j++)
{
data[j] = (double*)malloc(n*sizeof(double)); //这个指针数组的每个指针元素又指向一个数组。
} for (int i=;i<m;i++)
{
for (int j=;j<n;j++)
{
data[i][j]=i*n+j;//初始化数组元素
}
}
for (i=;i<m;i++)
{
free(data[i]); //先撤销指针元素所指向的数组
}
free(data); C++版本:
double **data;
data = new double*[m]; //设置行 或直接double **data=new double*[m]; 一个指针指向一个指针数组。
for(int j=;j<m;j++)
{
data[j] = new double[n]; //这个指针数组的每个指针元素又指向一个数组。
}
for (int i=;i<m;i++)
{
for (int j=;j<n;j++)
{
data[i][j]=i*n+j;//初始化数组元素
}
}
for (i=;i<m;i++)
{
delete[] data[i]; //先撤销指针元素所指向的数组
}
delete[] data; 这种方法是通过先动态创建一个指针数组,然后为指针数组的每个元素再动态指向一个数组的办法来完成的。其创建过程与销毁过程两样重要。
在销毁的过程,先销毁指针数组每个元素指向的数组,然后再销毁这个指针数组。
.使用数组指针,分配一个指针数组,将其首地址保存在b中,然后再为指针数组的每个元素分配一个数组 int **b=new int*[row]; //分配一个指针数组,将其首地址保存在b中
for(i=;i<row;i++) //为指针数组的每个元素分配一个数组
b[i]=new int[col]; 该方法定义的动态二维数组的释放需先释放指针数组的每个元素指向的数组,然后再释放该指针数组:
for(i=;i<row;i++)
{
delete [col]b[i];
b[i]=NULL;
}
delete [row]b;
b=NULL;
int _tmain(int argc, _TCHAR* argv[])
{
int row,column;
cin>>row>>column; //方法一
//申请空间
int ** a = new int *[row];
for(int i = ;i < row;i++)
a[i] = new int[column]; //使用空间
for(int j = ;j < row;j++)
for(int k = ;k< column;k++)
a[j][k] = rand()%; for(int j = ;j < row;j++)
{
cout<<endl;
for(int k = ;k< column;k++)
{
a[j][k] = rand()%;
cout<<a[j][k]<<" ";
}
} //释放空间
for(int i = ;i < row;i++)
{
delete a[i];
a[i] = NULL;
}
delete [row]a;
a = NULL; return ; } 用vector
int _tmain(int argc, _TCHAR* argv[])
{
int row,column;
cin>>row>>column; //方法二
//申请空间
vector<vector<int> > a(row,vector<int>(column)); //使用空间
for(int j = ;j < row;j++)
for(int k = ;k< column;k++)
a[j][k] = rand()%; for(int j = ;j < row;j++)
{
cout<<endl;
for(int k = ;k< column;k++)
{
a[j][k] = rand()%;
cout<<a[j][k]<<" ";
}
} return ; }
首先,要认识到在任何情况下都不能用指向空值的引用。一个引用必须总是指向某些对象。因此如果你使用一个变量并让它指向一个对象,但是该变量在某些时候也可能不指向任何对象,这时你应该把变量声明为指针,因为这样你可以赋空值给该变量。相反,如果变量肯定指向一个对象,例如你的设计不允许变量为空,这时你就可以把变量声明为引用。
char *pc = 0; // 设置指针为空值 char& rc = *pc; // 让引用指向空值 |
这是非常有害的,毫无疑问。结果将是不确定的(编译器能产生一些输出,导致任何事情都有可能发生),应该躲开写出这样代码的人除非他们同意改正错误。如果你担心这样的代码会出现在你的软件里,那么你最好完全避免使用引用,要不然就去让更优秀的程序员去做。我们以后将忽略一个引用指向空值的可能性。
因为引用肯定会指向一个对象,在C里,引用应被初始化。
string& rs; // 错误,引用必须被初始化 string s("xyzzy"); string& rs = s; // 正确,rs指向s |
指针没有这样的限制。
string *ps; // 未初始化的指针 // 合法但危险 |
不存在指向空值的引用这个事实意味着使用引用的代码效率比使用指针的要高。因为在使用引用之前不需要测试它的合法性。
void printDouble(const double& rd) { cout << rd; // 不需要测试rd,它 } // 肯定指向一个double值 |
相反,指针则应该总是被测试,防止其为空:
void printDouble(const double *pd) { if (pd) { // 检查是否为NULL cout << *pd; } } |
指针与引用的另一个重要的不同是指针可以被重新赋值以指向另一个不同的对象。但是引用则总是指向在初始化时被指定的对象,以后不能改变。
string s1("Nancy"); string s2("Clancy"); string& rs = s1; // rs 引用 s1 string *ps = &s1; // ps 指向 s1 rs = s2; // rs 仍旧引用s1, // 但是 s1的值现在是 // "Clancy" ps = &s2; // ps 现在指向 s2; // s1 没有改变 |
总的来说,在以下情况下你应该使用指针,一是你考虑到存在不指向任何对象的可能(在这种情况下,你能够设置指针为空),二是你需要能够在不同的时刻指向不同的对象(在这种情况下,你能改变指针的指向)。如果总是指向一个对象并且一旦指向一个对象后就不会改变指向,那么你应该使用引用。
还有一种情况,就是当你重载某个操作符时,你应该使用引用。最普通的例子是操作符[]。这个操作符典型的用法是返回一个目标对象,其能被赋值。
vector v(10); // 建立整形向量(vector),大小为10; // 向量是一个在标准C库中的一个模板 v[5] = 10; // 这个被赋值的目标对象就是操作符[]返回的值 |
如果操作符[]返回一个指针,那么后一个语句就得这样写:
*v[5] = 10; |
但是这样会使得v看上去象是一个向量指针。因此你会选择让操作符返回一个引用。
当你知道你必须指向一个对象并且不想改变其指向时,或者在重载操作符并为防止不必要的语义误解时,你不应该使用指针。而在除此之外的其他情况下,则应使用指针。
动态创建二维vector数组 C和C++ 及指针与引用的区别的更多相关文章
- C语言 动态创建二维数组
/*C语言 如何动态创建二维数组 转化为一维数组申请数组,创建和释放都比较简单 */ #include <stdlib.h> #include <stdio.h> #inclu ...
- 【转】C++动态创建二维数组,二维数组指针
原作者博客:蒋国宝的IT技术博客 今天完成一道题目需要自己用指针创建一个二维的数组,不得不承认指针的确是恶心. int **result; ; ; result = new int*[row]; ; ...
- nodejs 动态创建二维码
<!--弹出二维码--> <div class="qrcode"> <div> <p id="saoma">扫描 ...
- C语言动态生成二维数组
# 动态创建二维数组示例 #include "stdlib.h" #include "stdio.h" #include <malloc.h> in ...
- 如何在C++中动态建立二维数组(转)
http://blog.sina.com.cn/s/blog_7c073a8d0100qp1w.html http://blog.163.com/wujiaxing009@126/blog/stati ...
- 转:用STL中的vector动态开辟二维数组
用STL中的vector动态开辟二维数组 源代码:#include <iostream>#include <vector>using namespace std;int mai ...
- c++中创建二维数组的几种方法
一.用new申请内存空间 int **dp=new int*[n];//动态申请二维数组nxm ;i<n;++i){ dp[i]=new int[m]; } 二.用malloc申请内存空间 ; ...
- C++中动态申请二维数组并释放方法
C/C++中动态开辟一维.二维数组是非常常用的,以前没记住,做题时怎么也想不起来,现在好好整理一下. C++中有三种方法来动态申请多维数组 (1)C中的malloc/free (2)C++中的new/ ...
- Python创建二维数组(关于list的一个小坑)
0.目录 1.遇到的问题 2.创建二维数组的办法 3.1 直接创建法 3.2 列表生成式法 3.3 使用模块numpy创建 1.遇到的问题 今天写Python代码的时候遇到了一个大坑,差点就耽误我交作 ...
随机推荐
- 【Cocos2d实例教程一】xcode5下Cocos2d环境的搭建
(转载请注明出处:http://blog.csdn.net/buptgshengod) 第一步,现在要安装集成环境xcode5,安装xcode5需要系统至少是os x 10.8.5. 第二步,下载co ...
- Android构建boot.img(一):root目录与ramdisk.img的生成
以TCC88XX为例,当在Android顶层源码目录使用make编译完成后,会生成这样一个目录: out/target/product/tcc8800,该目录内部有我们需要的boot.img和syst ...
- android之Itent.ACTION_PICK Intent.ACTION_GET_CONTENT妙用
你是不是很多时候,想从弹出的电话本姓名列表中中查找到某个人,然后再获取该人的详细信息呢? 你是不是想选择从弹出的列表中选择一张图片,然后将其进行进一步的操作呢? 如果,你想,那你是不是很像知道,我们应 ...
- core--线程同步(内核模式)
什么是内核?windows操作系统为了更好的管理进程,线程,创建了很多数据结构,这些数据结构运行在windows的底层,并不开放给开发人员:所以开发人员称这些结构为内核,但是为了开发人员能够使用,wi ...
- HDU 4513 吉哥系列故事——完美队形II
变形的Manacher算法,在扩展的时候要加入限制条件,满足题目中说的从左到中间身高不减. 其他地方倒是没有什么改动.. //#define LOCAL #include <iostream&g ...
- Web程序员最常用的11款PHP框架
PHP框架是Web程序员和开发人员最为有用的工具. PHP框架可以帮助用户更快地开发项目. 今天我将为开发人员带来几款最好的PHP框架,希望能对你有用. 1.Agavi Agavi是一款强大的,可扩展 ...
- jstl表达式
JSTL标签库 1.什么是JSTL JSTL是apache对EL表达式的拓展(也就是说JSTL依赖EL),JSTL是标签语言!JSTL标签使用以来非常方便, 它与JSP动作标签一样,只不过它不是JSP ...
- cocos2d-x使用python脚本创建项目的简单方法
本文有CC原创,转载请注明地址:http://blog.csdn.net/oktears/article/details/13297003 在cocos2d-x2.1.4以上的版本中,取消了使用vs模 ...
- Java 循环语句之多重循环
循环体中包含循环语句的结构称为多重循环.三种循环语句可以自身嵌套,也可以相互嵌套,最常见的就是二重循环.在二重循环中,外层循环每执行一次,内层循环要执行一圈. 如下所示: 例如:使用 * 打印长方形: ...
- aspose.word 在书签处插入符号
doc.Range.Bookmarks["CBJYQQDFS110"].Text = ""; Aspose.Words.DocumentBuilder buil ...