C指针与二维数组

来源:互联网 发布:exo金钟大网络春晚生病 编辑:程序博客网 时间:2024/05/21 15:44

1. 指针与二位数组的关系

以下面代码为例阐述指针与二位数组的关系:

int A[4][2];

A是数组名,同时也是数组首元素的地址。A的首元素本身又包含两个int的数组,因此A也是包含两个int的数组的地址。

(1) 因为A是数组首元素(A[0])的地址,所以A与&A[0]等同。A[0]本身是包含两个整数的数组,因此A[0]同其首元素(A[0][0])的地址&A[0][0]等同。A[0]是一个整数大小对象(A[0][0])的地址,而A是两个整数大小对象(A[0])的地址。

          A、&A[0]、A[0]、&A[0][0]它们都开始于同一个地址,即它们的值是相同的,但它们并不都是等同的:A与&A[0]等同,A[0]与&A[0][0]等同,但A与A[0]或&A[0][0]、&A[0]与A[0]或&A[0][0]之间并不是等同的,尽管它们的地址值是相等的。等同包括两个含义:类型相同且值相等。


(2) 对一个指针(地址)加1,会对原来的数值加上一个指针所指类型大小的数值。因此A与A[0]是不同的,A所指对象的大小是两个int(这两个int是A[0][0]和A[0][1],此时对于A来说A[0][0]和A[0][1]看作一个整体,即A[0]),而A[0]所指对象的大小是一个int(这个int是A[0][0])。因此A + 1与A[0] + 1不同。


(3) 对一个指针(地址)取值(通过*或[])得到的是该指针所指向对象的值。因此如下等式成立:

          *A = A[0] = &A[0][0]

          *A[0] = A[0][0]

          **A = *A[0] = A[0][0]

例子:

#include <stdio.h>#include <stdlib.h>int main(void){    int A[4][2];    printf("A\t = %p\nA[0]     = %p\n&A[0]    = %p\n&A[0][0] = %p\n", A, A[0], &A[0], &A[0][0]);    printf("*A\t = %p\n", *A);                                                                          printf("*A == A[0] == &A[0][0]?: %s\n", *A == A[0] && A[0] == &A[0][0] ? "true" : "false");    printf("A == A[0] ?: %s\n", A == A[0] ? "true" : "false"); //compile-time warning, distinct pointer types    printf("A + 1 == A[1] ? %s\n", A + 1 == A[1] ? "true" : "false"); //compile-time warnin, distinct pointer types    printf("*(A + 1) == A[1] ? %s\n", *(A + 1) == A[1] ? "true" : "false");            printf("A[0] + 1 == &A[0][1] ?: %s\n", A[0] + 1 == &A[0][1] ? "true":"false");    return 0;}


输出:



2. 函数和二位数组

下面的二位数组:

int B[3][4] = {{1,2,3,4}, {5, 6 , 7 ,8}, {9, 10, 11, 12}};

要向一个函数func中传递这个二位数组,如何传呢?

(1) void func(int pt[][4])

          第二维或更高维的大小一定不能省略。传递参数时:func(B)

          在func函数内部pt就代表B,可用pt[2][1]等访问数据。

(2) void func(int (* pt) [4])

          第二维或更高维的大小一定不能省略。传递参数时:func(B);

          在func函数内部pt就代表B,可用pt[2][1]等访问数据。

(3)void func(int **pt)

         此时pt是指针的指针,类型与B不同,因此不能用如pt[2][1]的方式访问数组,但地址值与B的值是相同的。对于pt来说,它唯一知道的就是地址值,没有二位数组的概念。访问B[2][1]只能用*(p + n*i + j)的形式,即*(p + 2 * 4 + 1)

         传递参数时:func((int **)B)


例子:

#include <stdio.h>void func1(int (* pt) [4]);void func2(int **pt);int main(void){    int B[3][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};    func1(B);    //func2(B);          //complie-time error, incompatible type    func2((int **)B);                                                                                                            return 0;}void func1(int (* pt) [4]){       printf("\nin func1:\n");    printf("pt[2][1] = %d\n", pt[2][1]);}void func2(int **pt){    printf("\nin func2:\n");    printf("pt[2][1] = %d\n", *(pt + 2 * 4 + 1));    printf("pt[2][1] = %d\n", pt[2][1]);    //run-time error}

当把代码中的注释删掉时,编译结果如下:



上述代码运行结果如下:


原创粉丝点击