zoukankan      html  css  js  c++  java
  • 常见数组指针问题

    void func1(char a[])
    {
     printf("%d",sizeof(a));
    }
    void main()
    {
     char b[55];
     func1(b);
    }

    输出为4,说明传递的参数数组自动退化为同类型的指针,这个例子中不论数组的容量为多少,sizeof(a)始终等于sizeof(char *)。

    C语言中的数组和指针总保持着'千丝万缕'的联系,这里仅针对数组作为函数实参时的情况做些说明^_^。

    C语言中的数组可分为一维数组和多维数组两类,而多维数组中又以二维数组最为常见。这里也仅针对这一维数组和二维数组作简要说明。

    看过'高质量C++编程指南'的人可能都知道书中有这样一句'注意当数组作为函数的参数进行传递时,该数组自动退化为同类型的指针',这句话针对一维数组固然是正确的,但是对于多维数组,这显然不完全正确。但是如果你说C语言中的数组默认就指一维数组,那么这也就过得去了。C语言之所以把数组形参当作指针是出于效率考虑,试想如果把一个数组全部拷贝这样势必带来性能上的损失,如果数组很大的话,这种完全拷贝的方法就是不能忍受的了。所以目前无论你在函数声明中像'void func1(char a[])'这样写,还是像'void func1(char *a)',编译器都会把它看成后者的形式,对于一维数组,显然这没什么可说的,但是对于二维数组来说,其中还有不少值得商榷的地方。

    C语言中的二维数组可以看作为'数组的数组',而且其采用'行主序',即'最右边的下标'是最先变化的。由于指针和数组的关系导致,二维数组可以广义表示为多种形式:
    (1) char a[m][n] -- 标准形式;
    (2) char *p[n] -- 指针数组形式;
    (3) char (*p)[n] -- 数组(行)指针的形式
    (4) char **p -- 指针的指针的形式

    这些形式虽然都能表示二维数组,但是它们并不等价,这也给参数原型设计带来一定的不便,不过二维数组作为参数后的转化还是有原则可循的,那就是:'数组的数组'被转换为'数组的指针',下面就逐一说说每种形式对应的函数参数原型,通过例子认真体会一番:
    (1) char a[m][n] -- void func(char (*p)[]); 二维数组退化为数组的指针,关于如何声明数组的指针,可以参见"理解C复杂声明之'优先级规则'"和"C复杂声明解析"两篇文章;
    (2) char *p[n] -- void func(char **p); 这个是一个指针数组,我们只需要取地址即可;
    (3) char (*p)[n] -- void func(char (*p)[]); 这个本身就是一个数组指针,原封不动即可;
    (4) char **p -- void func(char **p); 对于指针的指针类型,同样原封不动。

    三维以上的数组不常用,用起来也较复杂,这里不作说明。

  • 相关阅读:
    (双指针 二分) leetcode 167. Two Sum II
    (双指针) leetcode 485. Max Consecutive Ones
    (双指针) leetcode 27. Remove Element
    (String) leetcode 67. Add Binary
    (数组) leetcode 66. Plus One
    (N叉树 BFS) leetcode429. N-ary Tree Level Order Traversal
    (N叉树 递归) leetcode 590. N-ary Tree Postorder Traversal
    (N叉树 递归) leetcode589. N-ary Tree Preorder Traversal
    (N叉树 DFS 递归 BFS) leetcode 559. Maximum Depth of N-ary Tree
    (BST 递归) leetcode98. Validate Binary Search Tree
  • 原文地址:https://www.cnblogs.com/sideny/p/3314463.html
Copyright © 2011-2022 走看看