动态创建二维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代码的时候遇到了一个大坑,差点就耽误我交作 ...
随机推荐
- 推荐个Java代码质量检测的利器 —— FindBugs
一.下载 插件的下载地址(sourceforge):FindBugs-Eclipse插件 二.安装 Eclipse插件的安装,就不多说了. 三.使用 1.找一个Project,选中它(也可以针对某个P ...
- [转]c/c++输入函数
最全输入函数 c/c++ 一: c=getchar(); 功能:读入一个字符 说明:调用此函数时要求在程序的第一行有预编译命令:#include<stdio>,不过在做c++时 有#inc ...
- ulimit调优
1. linux的ulimit各种限制之深入分析 http://blog.sina.com.cn/s/blog_59b6af6901011ekd.html 2. Linux下修改ulimit设置的最大 ...
- laravel下的团队开发
当你的团队在开发一个大型应用时,该应用的不同部分可能以不同的速度前进.比如,设想下面的场景:一个开发热源被分配 数据层 的backend工作,而另外一个开发人员做front-end和web/contr ...
- python——no module named XX
加PYTHONPATH吧,新建一个系统环境变量,把你的目录复制进去即可
- JSAPI微信支付返回错误:fail_no permission to execute
问题描述 fail_no permission to execute 一定是授权目录出问题了,因为没有权限. 开发环境及可能造成的原因 这次的微信开发是用的Mvc4,支付的封装代码不会有问题(用过很多 ...
- I.MX6 AT24Cxx eeprom Linux i2c-gpio
/************************************************************************** * I.MX6 AT24Cxx eeprom L ...
- 【英语】Bingo口语笔记(34) - Hit系列
hit it off 合得来 hit the bottle 喝醉酒 hit the spot 正合要求,恰到好处
- 【英语】Bingo口语笔记(43) - u长短音
- android 相对布局
RelativeLayout布局 android:layout_marginTop="25dip" //顶部距离 android:gravity="left" ...