C语言学习笔记--数组参数和指针参数

1. 数组参数退化为指针的意义

(1)C 语言中只会以值拷贝的方式传递参数,当向函数传递数组时,将整个数组拷贝一份传入函数导致执行效率低下,C 语言以高效作是最初的设计目标,所以这种方法是不可取的。

(2)参数位于栈上,太大的数组拷贝将导致栈溢出。

(3)将数组名看做常量指针,传递的是数组的首元素地址,而不是整个数组。

2. 二维数组参数

(1)二维数组参数同样存在退化的问题:

二维数组可以看做是一维数组,其中的每个元素又是一个一维数组

(2)二维数维参数中第一维的参数可以省略

①void f(int a[5])←→void f(int a[])←→void f(int* a)

②void g(int a[5][3])←→void g(int a[][3])←→void g(int (*a)[3]);

(3)等价关系


数组参数


等效的指针参数


备注


一维数组:float a[5]


指针:float* a


相当于数组去掉第1维,然后把数组名前加上*。


指针数组:int* a[5]


指针的指针:int** a;


二维数组:char a[3][4]


数组的指针:char(*a)[4]

(4)被忽视的知识点

①C 语言中无法向一个传递任意多维数组。换一句话讲,形参 int a[][3]是合法的,但 inta[][]是非法的。

①因此,必须提供除第 1 维之外的所有其他维长度。第一维之外的维度信息用于完成指针运算。

传递与访问二维数组

#include <stdio.h>

void access(int a[][3],int row) //a[][3],形参第2维的长度必须提供
{
    int  col = sizeof(*a)/sizeof(int);

    int i = 0;
    int j = 0;

    printf("sizeof(a) = %d\n",sizeof(a)); //指针,4字节

    //a为int (*a)[3]类型,即a指向一个有3个int型元素的数组
    printf("sizeof(*a) = %d\n",sizeof(*a));//3*4 =12字节

    for(i = 0;i < row; i++)
        for(j = 0; j < col; j++)
        {
            printf("%d\n", a[i][j]);
        }

    printf("\n");
}

void access_ex(int b[][2][3],int n) //数组参数的第2、3维长度必须提供
{
    int i = 0;
    int j = 0;
    int k = 0;

    printf("sizeof(b) = %d\n",sizeof(b)); //指针,4字节

    //b为int (*b)[2][3]类型,即b指向一个有2行3列int型元素的二维数组
    printf("sizeof(*b) = %d\n",sizeof(*b));//2 * 3 * 4 = 24字节

    for(i = 0;i < n; i++)
        for(j = 0; j < 2; j++)
             for(k = 0; k < 3; k++)
             {
                 printf("%d\n", b[i][j][k]);
             }

    printf("\n");
}

int main()
{
    int a[3][3] = {{0, 1, 2},{3, 4, 5},{6, 7, 8}};
    int aa[2][2] = {0};
    int b[1][2][3] = {0};

    access(a, 3);
    //access(aa,2);//error,int(*)[2]与int (*)[3]类型不匹配

    access_ex(b, 1);
    //access_ex(aa,2);//int(*)[2]与int(*)[2][3]类型不匹配

    return 0;
}

参考资料:
www.dt4sw.com
http://www.cnblogs.com/5iedu/category/804081.html

时间: 2024-10-26 18:45:42

C语言学习笔记--数组参数和指针参数的相关文章

15-黑马程序员------C 语言学习笔记---数组和指针

黑马程序员------<a href="http://www.itheima.com" target="blank">Java培训.Android培训.iOS培训..Net培训</a>.期待与您交流! ------- 四 数组和指针 01 数组名代表数组在内存中的首地址,表示的是地址信息,因此数组名可以理解为一个指针,不过数组名是一个常量,不能改变. #include <stdio.h> int main() { char nam

C语言学习笔记--数组

1.数组的概念 (1)数组是相同类型的变量的有序集合 (2)数组在一片连续的内存空间中存储元素 (3)数组元素的个数可以显示或隐式指定 #include <stdio.h> int main() { //数组初始化 int a[5] = {1, 2};//第 1.2 个元素分别为 1.2,其余为 0 int b[] = {1, 2};//编译过程中,编译会为计算数组 b 的大小 int i=0; for (i = 0;i < 4;i++) { printf("a[%d] = %

C语言学习_数组与指针2

数组其实是一种变相的指针,数组名同时也是指针,eg: CODE == &CODE[0]; 数组的加法: #include<stdio.h> #define SIZE 4 int main(void) { shortdates[SIZE]; short* pti; shortindex; doublebills[SIZE]; double* ptf; pti= dates;//把数组地址付给指针 ptf= bills; printf("%23s  %10s\n", &

C语言学习笔记(五) 数组

数组 数组的出现就是为了解决大量同类型数据的存储和使用的问题: 数组的分类:一维数组.二维数组. 一维数组:为多个变量连续分配存储控件:所有的变量的数据类型必须相同:所有变量所占的字节大小必须相等: 例如:int a[4]; 一维数组名不代表数组中的所有元素而是代表数组中第一个元素的地址: 数组的初始化: 完全初始化: int a[4] = {1,2,3,4}; 不完全初始化: int a[4] = {1};  未被初始化的元素的值默认为0; 数组清零 int a[4] = {0}; 不初始化:

go语言学习笔记

go语言学习笔记 go语言学习笔记(初级) 最近一直在学习go语言,因此打算学习的时候能够记录 一下笔记.我这个人之前是从来没有记录笔记的习惯, 一直以来都是靠强大的记忆力去把一些要点记住. 读书的时候因为一直都是有一个很安静和很专心的环境, 因此很多事情都能记得很清楚,思考的很透彻.但是随着 年纪不断增加,也算是经历了很多的事情,加上工作有时会让人 特别烦闷,很难把心好好静下来去学习,去思考大自然的终极 奥秘,因此需要记录一些东西,这些东西一方面可以作为一种自我激励 的机制,另一方面,也算是自

R语言学习笔记

參考:W.N. Venables, D.M. Smith and the R DCT: Introduction to R -- Notes on R: A Programming Environment for Data Analysis and Graphics,2003. http://bayes.math.montana.edu/Rweb/Rnotes/R.html 前言:关于R 在R的官方教程里是这么给R下注解的:一个数据分析和图形显示的程序设计环境(A system for data

JavaScript--基于对象的脚本语言学习笔记(一)

1.两种嵌入js的方式 使用javascript前缀构建url:<a href="javascript:alert('运行JavaScript..')">运行js</a> js脚本放在<style></style>之间: <style type="text/javascript"> alert("运行JavaScript..") </script> 2.如果没有声明变量直接使

Perl语言学习笔记 day 2

1.在Perl中,子程序名与变量名属于不同的命名空间,可以使用同一个名字分别命名子程序和变量,但不建议这样使用. 2.子程序的定义是全局的,同名的子程序后边的会覆盖掉前边的定义. 3.定义子程序 sub subProgram{ #body } 4.调用子程序 &subProgram 5.所有的子程序都有返回值,默认最后一行的运算结果为返回值. 6.子程序未定义参数时,传递的参数默认传给"@_",可以通过$_[0].$_[1].....访问: 7.在子程序中创建私有变量 my($

Go语言学习笔记(四) [array、slices、map]

日期:2014年7月22日 一.array[数组] 1.定义:array 由 [n]<type> 定义,n 标示 array 的长度,而 <type> 标示希望存储的内容的类型. 例如: var arr[10] int arr[0] = 1 arr[1] = 2 数组值类型的:将一个数组赋值给 另一个数组,会复制所有的元素.另外,当向函数内传递一个数组的时候,它将获得一个数组的副本,而不是数组的指针. 2.数组的复合声明.a :=[3]int{1,2,3}或简写为a:=[...]i