设有整型二维数组a[3][4]如下:
0   1   2   3
4   5   6   7
8   9  10  11 
它的定义为:
    int a[3][4]={{0,1,2,3},{4,5,6,7},{8,9,10,11}}
设数组a的首地址为1000,各下标变量的首地址及其值如图所示。

前面介绍过,C语言允许把一个二维数组分解为多个一维数组来处理。因此数组a可分解为三个一维数组,即a[0]、a[1]、a[2]。每一个一维数组又含有四个元素。

例如a[0]数组,含有a[0][0],a[0][1],a[0][2],a[0][3]四个元素。

更多的见: http://c.biancheng.net/cpp/html/79.html

数组及数组元素的地址表示如下:从二维数组的角度来看,a是二维数组名,a代表整个二维数组的首地址,也是二维数组0行的首地址,等于1000。a+1代表第一行的首地址,等于1008。如图:

int array[3][3];

array的类型既不是int **

更不是(int *a)[4]

而是int [3][3]

只是作为右值时才转换成

int (*a)[4] a是指向一个有4个元素的数组的指针,事实上这个a此时指向a[0],指向数组,就是说a里保存着数组的地址,就是1000

指针数组与数组指针

指针数组:array of pointers,即用于存储指针的数组,也就是数组元素都是指针

数组指针:a pointer to an array,即指向数组的指针

还要注意的是他们用法的区别,下面举例说明。

int* a[4]     指针数组

表示:数组a中的元素都为int型指针

元素表示:*a[i]   *(a[i])是一样的,因为[]优先级高于*

int (*a)[4]   数组指针

表示:指向数组a的指针

元素表示:(*a)[i]

#include <iostream>

using namespace std;

int main()

{

int c[4]={1,2,3,4};

int *a[4]; //指针数组

int (*b)[4]; //数组指针

b=&c;

//将数组c中元素赋给数组a

for(int i=0;i<4;i++)

{

a[i]=&c[i];

}

//输出看下结果

cout<<*a[1]<<endl; //输出2就对

cout<<(*b)[2]<<endl; //输出3就对

return 0;

}

(int *array)[N] 和int **的区别

Int ** p,就是一个指针,这个指针指向了int* 也就是一个整型数组,p是指向了整数数组的指针,p中是整数数组的地址,(int *array)[N] 和int **的区别就在于每行的元素个数固不固定

传递二维数组参数

int func(int **array, int m, int n) {

...

printf("\t%d", *(*array +i*n +j));

...

}

int main() {

  int array[3][3] = {

{1,2,3},

{4,5,6},

{7,8,9}

};

...

func(array,3,3);

 ...

}

这样传递二维数组是错的,因为类型不匹配,是因为数组实际类型是int [3][3],在作为右值时可以被转化为int (*)[3],它们都和int **不同,自然不可用。

法一 直接使用数组类型:因为数组实际类型是int [3][3]

可以用二维数组名作为实参或者形参,在被调用函数中对形参数组定义时可以指定所有维数的大小,也可以省略第一维的大小说明,如:

void Func(int array[3][10]);

void Func(int array[][10]);

二者都是合法而且等价,但是不能把第二维或者更高维的大小省略,如下面的定义是不合法的:

void Func(int array[][]);

因为从实参传递来的是数组的起始地址,在内存中按数组排列规则存放(按行存放),而并不区分行和列,如果在形参中不说明列数,则系统无法决定应为多少行多 少列,不能只指定一维而不指定第二维

法二.一维数组指针作为形参

void func2(int (*pArray)[10])

{

}

void func2_1(int (*pArray)[]) //编译通过,无法调用

{

}

int main()

{

int array[10][10];

func2(array);

}

把array[0] 数组的指针传给了func2 因为array是指向10个元素的数组的指针,(*array)就是array[0],(*array)[0] 就是array[0][0]

法三.二维数组引用作为形参

void func3(int (&pArray)[10][10])

{

}

int main()

{

int array[10][10];

func3(array);

}

以下是一维数组引用的例子

#include <iostream>

using namespace std;

void output(int (&a)[5])

{

for(int i = 0; i < 5; i++)

cout<<a[i]<<endl;

}

int main()

{

int a[5]={0};

output(a);

getchar();

return 0;

}

法四。二维数组指针作为形参

void func4(int (*pArray)[10][10])

{

}

int main()

{

int array[10][10];

func4(&array);

}

C语言二维数组作为函数参数的更多相关文章

  1. C语言二维数组作为函数的参数

    前言:今天在实现装配线调度程序时候,用到了二维数组,并将其作为函数的参数.在写程序的时候,遇到一些问题,即二维数组做函数的参数应该如何正确表示.我写程序的错误如下程序所示: #include < ...

  2. C-指针,二级指针,二维数组作为函数参数使用,C语言链表(详解)

    一级指针 int *p;            //表示定义一个int型(4字节)的指针p &p                 //表示p自身的地址位置 p                  ...

  3. C语言中将二维数组作为函数参数来传递

    c语言中经常需要通过函数传递二维数组,有三种方法可以实现,如下: 方法一, 形参给出第二维的长度. 例如: #include <stdio.h> void func(int n, char ...

  4. C语言学习笔记 (005) - 二维数组作为函数参数传递剖析

    前言 很多文章不外乎告诉你下面这几种标准的形式,你如果按照它们来用,准没错: //对于一个2行13列int元素的二维数组 //函数f的形参形式 f(int daytab[2][13]) {...} / ...

  5. C语言中如何将二维数组作为函数的参数传递

    今天写程序的时候要用到二维数组作参数传给一个函数,我发现将二维数组作参数进行传递还不是想象得那么简单里,但是最后我也解决了遇到的问题,所以这篇文章主要介绍如何处理二维数组当作参数传递的情况,希望大家不 ...

  6. C语言 二维数组(指针)动态分配和释放(转)

    C 二维数组(指针)动态分配和释放 先明确下概念: 所谓32位处理器就是一次只能处理32位,也就是4个字节的数据,而64位处理器一次就能处理64位,即8个字节的数据.如果我们将总长128位的指令分别按 ...

  7. c语言二维数组传递

    c语言二维数组传递,目前我总结三种方法,以及纠正一个不能使用的方法 /********************************* * 方法1: 第一维的长度可以不指定 * * 但必须指定第二维 ...

  8. [语法]C语言中二维数组做输入参数

    C语言中二维数组做输入参数时, 可以同时指定各维长度, 可以只指定第二维的长度, 不可以只指定第一维的长度, 不可以各维长度都不指定. 一句话总结:要指定至少指定第二维,都不指定是不行的. 具体栗子如 ...

  9. C语言 二维数组复制、清零及打印显示

    #include <stdlib.h> #include <stdio.h> #include <string.h> //二维整型数组打印显示 ],int row, ...

随机推荐

  1. 构建Maven项目

    Maven(一)如何用Eclipse创建一个Maven项目 Maven学习总结(三)——使用Maven构建项目 Eclipse创建一个Maven Web项目 [项目管理和构建]十分钟教程,eclips ...

  2. PHP中正则表达式学习及应用(三)

    正则表达式中的“模式修正符” 1.运算顺序    2.模式修正符 i 正则内容在匹配时候不区分大小写(默认是区分的) 例如: <?php $mode="/[a-z]/i"; ...

  3. HTML学习笔记(六)TCP/IP

    TCP/IP 是供已连接因特网的计算机进行通信的通信协议. 在 TCP/IP 中包含一系列用于处理数据通信的协议: TCP (传输控制协议) - 应用程序之间通信 UDP (用户数据包协议) - 应用 ...

  4. C++11 并发编程基础(一):并发、并行与C++多线程

    正文 C++11标准在标准库中为多线程提供了组件,这意味着使用C++编写与平台无关的多线程程序成为可能,而C++程序的可移植性也得到了有力的保证.另外,并发编程可提高应用的性能,这对对性能锱铢必较的C ...

  5. lightoj1064 【DP求方案】

    题意: n个相同的骰子,问你掷出>=x点数的可能性: 思路: dp[i][j]代表前 i 个骰子掷出 j 点数的方案数; 然后Σdp[n][x]-dp[n][6*n]就好了 卧槽,一开始想的是拆 ...

  6. MySQL存储引擎的区别

    一.mysql中myisam,innodb和memory三个存储引擎的区别 1.区别:1) MyISAM管理非事务表.提供高速存储和检索,以及全文搜索能力.MyISAM在所有MySQL配置里被支持,是 ...

  7. UINavigationController 的一些坑

    坑一:自定义导航栏返回键 iOS7及之后版本 手势边缘右滑返回失效 解决方案: -(void)viewDidLoad{ [super viewDidLoad]; //self 为 UINavigati ...

  8. 学习Spring Boot看这两个开源项目就够了!非得值得收藏的资源

    Spring Boot我就不做介绍了,大家都懂得它是一个多么值得我们程序员兴奋的框架. 为什么要介绍这两个开源项目呢? 1.提供了丰富的学习实践案例 2.整合了非常多优质的学习资源 不多说了,直接上链 ...

  9. web前端与后台数据交互

    1.前端请求数据URL由谁来写? 在开发中,URL主要是由后台来写的,写好了给前端开发者.如果后台在查询数据,需要借助查询条件才能查询到前端需要的数据时,这时后台会要求前端提供相关的查询参数,这里的查 ...

  10. django (三) admin后台系统

    admin后台系统 1. 安装MySQL 1,安装mysql: sudo apt install mysql-server   (安装过程中输入密码并牢记)   2,安装后进入mysql: mysql ...