C++的二维数组(全)

40 篇文章 0 订阅

首先需要理解int a; int *a; int **a; int (*a)[10]; int *a[10];int (*a)(int);各自的含义,并学会区分

a) int a; 表示一个内存空间,这个内存空间用来存放一个整数(int)

b) int *a; 表示一个内存空间,这个内存空间用来存放一个指针,这个指针指向a)那样的内存空间

c) int **a; 表示一个内存空间,这个内存空间用来存放一个指针,这个指针指向b)那样的内存空间

d) int (*a)[10]; 表示一个内存空间,这个内存空间用来存放一个指针,这个指针指向一个长度为10、类型为int的数组

e) int *a[10]; 表示一个长度为10 、类型为int*的数组

f) int (*a)(int); 表示一个内存空间,这个内存空间用来存放一个指针,这个指针指向一个函数,这个函数有一个类型为int的参数,并且参数的返回值为int

注意int **a与int (*a)[N]的使用

int (*a)[N]和int **a在用法上的区别在于,++、+=1之后的结果不一样。

我们可以看如下代码:

int a[3][4];
int **p1 = a; // error
int (*p2)[4] = a; // ok

问题出在类型的对应上,而不是内容上。a的类型为& a[0]即一个指向长为4的数组的地址,所以可以赋值给int ()[4]类型(指向长为4的数组的指针)。而不能赋值给int *类型(指向指针的指针)。

数组作为形参

int a[2];

a代表的其实并不是数组的地址,而是数组第一个元素的地址,即& a[0];

int args[][2] = {{1, 2}, {3, 4}, {5, 6}};
// 下面4个输出都相同
cout<<&args<<endl;
cout<<args<<endl;
cout<<&args[0]<<endl;
cout<<&args[0][0]<<endl;
int c[3][4][5];
  1. c 的类型等价于int (*)[4][5] | c+1指的是c+sizeof(int)*4*5 ((c) [3][4][5])
  2. *c (等价于c[0])的类型等价于int (*)[5] | *c+1指的是*c+sizeof(int)*5 ((c[0]) [4][5])
  3. **c (等价于c[0][0])的类型等价于int *| **c+1指的是**c+sizeof(int*) ((c[0][0]) [5])

例子:

// 形参:指向2维数组的地址
# define N 2
void subfun(int subargs[][N], int m){}

int main(){ 
    int args[][2] = {{1, 2}, {3, 4}, {5, 6}};
    subfun(args, 3);

}
// 形参:指向2维数组的指针
# define N 2
void subfun(int (*subargs)[N], int m){}

int main(){
    int args[][N] = {{1, 2}, {3, 4}, {5, 6}};
    subfun(args, 3); // args相当于& args[0]
}

利用vector:

// 形参:2维vector的引用
void show_vector(vector<vector<int> > &vecTest) {

}

对比下列情况进行思考:

// 形参:指针的指针
void subfun(int **subargs, int m, int n){}

int main{
    int *a[3];
    int args[][2] = {{1, 2}, {3, 4}, {5, 6}};
    // subfun(3, args)会报错,问题出在类型上,而不是内容上
    for(int i=0;i<3;i++)
        a[i] = args[i]; // 等价于 a[i] = & args[i][0]
    subfun(a, 3, 2);
}

动态申请二维数组

传统方法:

// m*n
int main(){
    int **p = new int*[m];
    for(int i=0;i<n;i++)
        p[i] = new int[n];

    for(int i=0;i<n;i++)
        delete []p[i];
    delete []p;
}

利用vector:

// m*n
#include <vector>
int main(){
    // 初始化全为0
    vector<vector<int> > p(m, vector<int>(n));
}

二维数组初始化

传统:

// 1 2
// 3 4
// 5 6
int args[][2] = {{1, 2}, {3, 4}, {5, 6}};
// 0 0
// 0 0
// 0 0
// memset应用于非单字节类型,只能赋值为0或-1
#include<string.h>
int args[3][2];
memset(args, 0, sizeof(args));
// 1 1
// 1 1
// 1 1
// 目的是达不成的,因为memset是按字节赋值的, 而一个int占4个字节,这样每个int的4个字节都设为1了
#include<string.h>
int args[3][2];
memset(args, 1, sizeof(args));

利用vector:

// 1维vector
int main(){
    int test[] = {1, 2, 3};
    // test的前3个元素都赋给testV
    vector<int> testV(test, test+3); // 1, 2, 3

    // test的第1个元素(从0算起)到第2个元素都赋给testW,长度为2 == (test+3) - (test+1)
    vector<int> testW(test+1, test+3); // 2, 3

    // 内容拷贝构造
    vector<int> testFake(testV); // 1, 2, 3
    // 从第0个开始拷贝到第1个,长度为2
    vector<int> subTestFake(testV.begin(), testV.begin()+2); // 1, 2

    // 长度为l的vector,并初始化为0
    vector<int> zeroV(l);

    // 长度为l的vector,并初始化为1
    vector<int> zeroV(l, 1);    


}
// 2维vector
int main(){
    // m x n,初始化为0
    vector<vector<int> > w0(m, vector<int>(n));
    // m x n, 初始化为1
    vector<vector<int> > w1(m, vector<int>(n, 1));

    // 利用数组进行初始化
    int args[][2] = {{1, 2}, {3, 4}, {5, 6}};
    vector<vector<int> > wA(3, vector<int>(2));
    for(int i=0;i<3;i++)
        for(int j=0;j<2;j++)
            wA[i][j] = args[i][j];
}
// 1
// 3 3
// 5 5 5
int main(){
    vector<vector<int> > test;
    for(int i=1;i<=3;i++)
        test.push_back(vector<int>(i, 2*i-1));
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值