Rus*_*sel 4 c c++ arrays pointers multidimensional-array
我理解多维数组作为指针的指针,但也许我错了?
例如,我虽然:
char * var = char var[]
char ** var = char* var[]或char var[][]
char *** var = char var[][][]或char* var[][]或 char** var[]
这是不正确的?我很困惑因为我在简单的教科书示例中看到了char*[] []演员作为char**.
我粘贴了下面的例子.任何人都可以为我清除这个吗?谢谢!
/* A simple dictionary. */
#include <stdio.h>
#include <string.h>
#include <ctype.h>
/* list of words and meanings */
char *dic[][40] = {
"atlas", "A volume of maps.",
"car", "A motorized vehicle.",
"telephone", "A communication device.",
"airplane", "A flying machine.",
"", "" /* null terminate the list */
};
int main(void)
{
char word[80], ch;
char **p;
do {
puts("\nEnter word: ");
scanf("%s", word);
p = (char **)dic;
/* find matching word and print its meaning */
do {
if(!strcmp(*p, word)) {
puts("Meaning:");
puts(*(p+1));
break;
}
if(!strcmp(*p, word)) break;
p = p + 2; /* advance through the list */
} while(*p);
if(!*p) puts("Word not in dictionary.");
printf("Another? (y/n): ");
scanf(" %c%*c", &ch);
} while(toupper(ch) != 'N');
return 0;
}
Run Code Online (Sandbox Code Playgroud)
C的规则如下:
6.3.2.1左值,数组和函数指示符
...
3除非它是sizeof运算符或一元&运算符的操作数,或者是用于初始化数组的字符串文字,否则表达式的类型为'' type''转换为类型''指向类型'的指针,指向数组对象的初始元素,而不是左值.如果数组对象具有寄存器存储类,则行为未定义.
C++的语言有点不同:
4.2数组到指针的转换[conv.array]
1类型为"NT的数组"或"T的未知数组的数组"的左值或右值可以转换为"指向T的指针"类型的右值.结果是指向数组的第一个元素的指针.
...
8.3.4数组[dcl.array]
...
7多维数组遵循一致的规则.如果E是秩i × j ×...× k的n维数组,那么出现在表达式中的E被转换为指向具有等级j ×...× k的(n -1)维数组的指针.如果*运算符,无论是显式的还是隐式的,由于下标,都应用于此指针,结果是指向的(n -1)维数组,该数组本身立即转换为指针.
所以以下都适用:
Declaration Expression Type Decays to
----------- ---------- ---- ---------
T a[N] a T [N] T *
&a T (*)[N]
*a T
a[i] T
T a[M][N] a T [M][N] T (*)[N]
&a T (*)[M][N]
*a T [N] T *
a[i] T [N] T *
&a[i] T (*)[N]
*a[i] T
a[i][j] T
T a[M][N][O] a T [M][N][O] T (*)[M][N]
&a T (*)[M][N][O]
*a T [M][N] T (*)[N]
a[i] T [M][N] T (*)[N]
&a[i] T (*)[M][N]
*a[i] T [N] T *
a[i][j] T [N] T *
&a[i][j] T (*)[N]
*a[i][j] T
a[i][j][k] T
Run Code Online (Sandbox Code Playgroud)
对于更高维的阵列,该模式应该是清晰的.
那么让我们分析你的字典:
/* list of words and meanings */
char *dic[][40] = {
"atlas", "A volume of maps.",
"car", "A motorized vehicle.",
"telephone", "A communication device.",
"airplane", "A flying machine.",
"", "" /* null terminate the list */
};
Run Code Online (Sandbox Code Playgroud)
这不会按照你想要的方式设置你的字典; 你基本上把它设置为一个包含40个指向char的1元素数组.如果你想要一组字符串对,那么声明应如下所示:
char *dic[][2] =
{
{"atlas", "A volume of maps"},
{"car", "A motorized vehicle"},
{"telephone", "A communication device"},
{"airplane" , "A flying machine"},
{NULL, NULL} // empty strings and NULLs are different things.
};
Run Code Online (Sandbox Code Playgroud)
类型dic是"指向char的指针的2元素数组的5元素数组",或char *[5][2].按照上面的规则,表达式dic应该衰减到char *(*)[2]- 指向char的2元素指针数组的指针.
搜索此字典的函数将如下所示:
char *definition(char *term, char *(*dictionary)[2]) // *NOT* char ***dictionary
{
while ((*dictionary)[0] != NULL && strcmp((*dictionary)[0], term) != 0)
dictionary++;
return (*dictionary)[1];
}
Run Code Online (Sandbox Code Playgroud)
你会从你的主要功能中调用它
char *def = definition(term, dic);
Run Code Online (Sandbox Code Playgroud)
请注意,我们必须*dictionary在函数中的表达式周围使用括号.数组下标运算符的[]优先级高于解引用运算符*,我们不想dictionary直接下标,我们要下标到dictionary 指向的数组.
我理解多维数组作为指针的指针,但也许我错了?
是的,你错了.数组和指针之间存在差异.数组可以衰减成指针,但指针不会携带有关它所指向的数组的大小或配置的状态.不要将这种自动衰减与数组和指针相同的想法混淆 - 它们不是.
A char **是指向包含字符指针的内存块的指针,字符指针本身指向字符的内存块.A char [][]是包含字符的单个内存块.
如果你有一个char **并使用它来访问它ptr[x][y],编译器会将其更改为*(*(ptr + x)+y).如果你有char [][],编译器会arr[x][y]变成*(ptr + rowLength*y + x).(注意:我在Xs和Ys的顺序上没有110%的正面,但这对于我在这里提出的点并不重要)注意,给定指针,编译器不知道任何关于大小的信息或者数组的维度,如果将指针视为多维数组,则无法确定实际地址.
char *dic[][40]是一个大小为40的数组数组,包含字符指针.因此它根本不符合您的作业.
p = (char **)dic;< - 这就是演员阵容不好的原因.编译器告诉你,你真正想做的事情dic没有任何意义.但是因为您可以将指针强制转换为任何其他指针,所以即使尝试以这种方式读取数据也会导致未定义的行为,转换也会成功.