C语言二维数组作为函数参数
设有整型二维数组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语言二维数组作为函数参数的更多相关文章
- C语言二维数组作为函数的参数
前言:今天在实现装配线调度程序时候,用到了二维数组,并将其作为函数的参数.在写程序的时候,遇到一些问题,即二维数组做函数的参数应该如何正确表示.我写程序的错误如下程序所示: #include < ...
- C-指针,二级指针,二维数组作为函数参数使用,C语言链表(详解)
一级指针 int *p; //表示定义一个int型(4字节)的指针p &p //表示p自身的地址位置 p ...
- C语言中将二维数组作为函数参数来传递
c语言中经常需要通过函数传递二维数组,有三种方法可以实现,如下: 方法一, 形参给出第二维的长度. 例如: #include <stdio.h> void func(int n, char ...
- C语言学习笔记 (005) - 二维数组作为函数参数传递剖析
前言 很多文章不外乎告诉你下面这几种标准的形式,你如果按照它们来用,准没错: //对于一个2行13列int元素的二维数组 //函数f的形参形式 f(int daytab[2][13]) {...} / ...
- C语言中如何将二维数组作为函数的参数传递
今天写程序的时候要用到二维数组作参数传给一个函数,我发现将二维数组作参数进行传递还不是想象得那么简单里,但是最后我也解决了遇到的问题,所以这篇文章主要介绍如何处理二维数组当作参数传递的情况,希望大家不 ...
- C语言 二维数组(指针)动态分配和释放(转)
C 二维数组(指针)动态分配和释放 先明确下概念: 所谓32位处理器就是一次只能处理32位,也就是4个字节的数据,而64位处理器一次就能处理64位,即8个字节的数据.如果我们将总长128位的指令分别按 ...
- c语言二维数组传递
c语言二维数组传递,目前我总结三种方法,以及纠正一个不能使用的方法 /********************************* * 方法1: 第一维的长度可以不指定 * * 但必须指定第二维 ...
- [语法]C语言中二维数组做输入参数
C语言中二维数组做输入参数时, 可以同时指定各维长度, 可以只指定第二维的长度, 不可以只指定第一维的长度, 不可以各维长度都不指定. 一句话总结:要指定至少指定第二维,都不指定是不行的. 具体栗子如 ...
- C语言 二维数组复制、清零及打印显示
#include <stdlib.h> #include <stdio.h> #include <string.h> //二维整型数组打印显示 ],int row, ...
随机推荐
- c++友元函数友元类
友元函数和友元类的需要: 类具有封装和信息隐藏的特性.只有类的成员函数才能访问类的私有成员,程序中的其他函数是无法访问私有成员的.非成员函数可以访问类中的公有成员,但是如果将数据成员都定义为公有的,这 ...
- 4-3逻辑非运算符及案例 & 4-4
创建类 LoginDemo3 这里取反 !(n%3==0) package com.imooc.operator; import java.util.Scanner; public class Log ...
- Spring Boot 学习系列(09)—自定义Bean的顺序加载
此文已由作者易国强授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. Bean 的顺序加载 有些场景中,我们希望编写的Bean能够按照指定的顺序进行加载.比如,有UserServ ...
- HTML基本标签元素
HTML: 超文本标记语言(HyperText Mark-up Language ) 1.作用:写网页结构 2.HTML不区分大小写,建议小写 3.文件后缀 .html 或者 .ht ...
- VC++11 编译中的一些问题的解决办法
1. vc++ 的编译器的错误往往定位在错误的那一处,但是那一处可能在库的底层,而我们知道库,一般都不会错. 这时候应该好好看看我们自己的头文件是否正确,有可能头文件中的一些错误引发了连锁反应. 2 ...
- [Xcode 实际操作]八、网络与多线程-(20)时间控件Timer定时功能
目录:[Swift]Xcode实际操作 本文将演示时间控件Timer定时功能的使用. 在项目导航区,打开视图控制器的代码文件[ViewController.swift] import UIKit cl ...
- golang开发:(二)安装 Golang
当然了我们的安装都是在vagrant里面安装,vagrant ssh.不用虚拟机了,本机安装当然也可以. Mac 安装 访问下载地址,下载 go1.12.5.darwin-amd64.pkg,双击下载 ...
- XHTML学习笔记 Part2:核心元素
1. <html>元素 <html xmlns="http://www.w3.org/1999/xhtml"> 仅有两个元素是<html>的直接 ...
- 阿里mavne中央仓库
https://www.cnblogs.com/ae6623/p/4416256.html 待整理
- 初次接触Service笔记
Service是后台的运行的小程序,分两种一种是StarService()另外一种是bindService(),这种可调用Service中的方法和返回结果等操作而StarService不能 他的生命周 ...