LFMY

导航

多维数组的理解(可能导致“致命错误”)

/*

 *C语言中只有“数组的数组”,即“一维数组”,并称为“多维数组”。

 */

以char szArr[][4][3];为例

该多维数组应该这样理解:

(1)一维数组szArr[]的单元为一个char[4][3]的二维数组;(同理,szArr[][4]的单元为一个char[3]的一维数组)

(2)当“数组名单独”出现的时候,“编译器”将其解释为“指向该‘一维数组’第一个元素”的“指针”;(所以,有时候我们会以为szArr[]的单元是一个二维指针,但可惜,事实并非如此)

(3)在函数传参的时候,数组名被“编译器”解释为“指向该‘一维数组’第一个元素”的“指针”;

(4)牢记一点:指针和数组名存在根本的不同。常见的例子是:

一个文件中定义int mango[100];//数组“开辟空间的特殊声明”,数组声明,意味mango[0]将“mango对应的符号表地址”+“偏移量”,之后访问内存单元

而另一个文件中声明extern int *mango;//指针的声明,意味着mango[0]将“mango对应的符号表地址”的内容取出后+“偏移量”,之后访问内存单元

当我们在另一个文件中mango[0];来使用时会出现程序的崩溃。

 

by the way:

(1)char str[][9] = {"hello", "world", "!"};

(str+1)//str的性质是char**指针,“+1”就是移动“char*”即一个字符串的大小,但类型还是char**,可以(atr+1)[1][1];来使用

(str[2])//str[2]的性质是字符串元素“!”

(&str+1)//移动单元为char的三维数组即{“hello”, "world", "!"}的下一个单元首地址

(*(str+1))//即“world”

(*(*(str+1)+1))//即‘o’,即str[1][1],又即(str+1)[0][1]

(2)见代码:

 1     char s[][6] = {"hello", "world", "!"}; 
 2     char (*p)[6] = s;
 3     char *pS[3] = {"hello", "world", "!"};
 4     char **pP = (char**)pS;//指向s就错了
 5 
 6     printf("%c\n", s[2][0]);
 7     printf("%c\n", pS[2][0]);
 8     printf("%c\n", *(*(pS+2)));//完全同上,由编译器处理的
 9     printf("%c\n", *(*(pP+2)));//完全同pP[2][0];
10     printf("%c\n", p[2][0]);
11     printf("%c\n", *(*(p+2)));//完全同上
四种都被处理成一种形式“(*(*(a + i) + j)”
1     printf("%c\n", *(*(pP+2)));//VC上正确
2     printf("%c\n", pP[2][0]);
3     printf("%c\n", (*(pP+2))[0]);
4     printf("%c\n", *(pP[2]));
访问形式不重要

 

总结:

*见到a[i][j]的时候,a可能有四种定义方式;

*a[i][j]编译器会处理成(*(*(a+i)+j)),但是“不同的表达式”会被解释成不同的“执行方式”!!!所以,访问方式并不重要,不必在意这里。“重点”放在:小心地定义并初始化他们。

出处:《c专家编程》第4章、第9章

posted on 2014-03-21 10:58  LFMY  阅读(277)  评论(0)    收藏  举报