在 C/C++ 中,char* arrayName[][] 是指向指针的指针还是指向指针的指针? [英] In C/C++, is char* arrayName[][] a pointer to a pointer to a pointer OR a pointer to a pointer?

查看:44
本文介绍了在 C/C++ 中,char* arrayName[][] 是指向指针的指针还是指向指针的指针?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将多维数组理解为指向指针的指针,但也许我错了?

例如,我虽然:

char * var = char var[]

char ** var = char* var[]char var[][]

char *** var = char var[][][] or char* var[][] or char** var[]

这是错误的吗?我很困惑,因为我在一个简单的教科书示例中看到一个 char*[][] 转换为 char**.

我粘贴了下面的示例.谁能帮我解决这个问题?谢谢!

<小时>

/* 一个简单的字典.*/#include #include #include /* 单词和含义列表 */字符 *dic[][40] = {"atlas", "地图集.","汽车", "机动车辆.","电话", "通讯设备.","飞机", "飞行机器.","", ""/* null 终止列表 */};int main(void){字符字[80], ch;字符**p;做 {puts("\n输入单词:");scanf("%s", word);p = (char **)dic;/* 找到匹配的单词并打印其含义 */做 {if(!strcmp(*p, word)) {puts("意思:");看跌期权(*(p + 1));休息;}if(!strcmp(*p, word)) 中断;p = p + 2;/* 在列表中前进 */} while(*p);if(!*p) puts("单词不在字典中.");printf("另一个?(y/n):");scanf(" %c%*c", &ch);} while(toupper(ch) != 'N');返回0;}

解决方案

C如下:

<块引用>6.3.2.1 左值、数组和函数指示符
...
3 除非它是 sizeof 运算符或一元 & 运算符的操作数,或者是用于初始化数组的字符串文字,否则为类型为 ''array 的表达式of type'' 转换为类型为 ''pointer to type'' 的表达式,该表达式指向数组对象的初始元素,而不是左值.如果数组对象具有寄存器存储类,则行为未定义.

C++ 的语言有点不同:

<块引用>4.2 数组到指针的转换[conv.array]

1 N T 的数组"或T 的未知边界数组"类型的左值或右值可以转换为指向 T 的指针"类型的右值.结果是指向数组第一个元素的指针.
...
8.3.4 数组 [dcl.array]
...
7 多维数组遵循一致的规则.如果 E 是秩 i × j × ... × k 的 n 维数组,则出现在表达式中的 E 被转换为一个指向 (n−1) 维数组的指针,秩为 j × ... × k.如果 * 运算符(显式或隐式作为下标的结果)应用于此指针,则结果是指向的 (n-1) 维数组,它本身立即被转换成一个指针.

所以以下都成立:

声明表达式类型衰减为----------- ---------- ---- ---------T a[N] a T [N] T *&a T (*)[N]*在[i] TT a[M][N] a T [M][N] T (*)[N]&a T (*)[M][N]*a T [N] T *[i] T [N] T *&a[i] T (*)[N]*a[i] T[i][j] TT 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] Ta[i][j][k] T

对于高维数组,模式应该是清晰的.

让我们分析一下你的字典:

/* 单词和含义列表 */字符 *dic[][40] = {"atlas", "地图集.","汽车", "机动车辆.","电话", "通讯设备.","飞机", "飞行机器.","", ""/* null 终止列表 */};

这不会按照您想要的方式设置您的字典;您基本上已将其设置为一个包含 40 个指向 char 的指针的 1 元素数组.如果你想要一个字符串对数组,那么声明应该是这样的:

char *dic[][2] ={{地图集",地图卷"},{汽车",机动车"},{"电话", "通讯设备"},{飞机",飞行器"},{NULL, NULL}//空字符串和 NULL 是不同的东西.};

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)字典++;返回(*字典)[1];}

你会从你的主函数中调用它,比如

char *def = definition(term, dic);

请注意,我们必须在函数中的 *dictionary 表达式周围使用括号.数组下标运算符[]的优先级高于解引用运算符*,我们不想直接下标到dictionary,我们想要下标到dictionary 指向的数组中.

I understood multi-dimensional arrays as pointers to pointers, but perhaps I am wrong?

For example, I though:

char * var = char var[]

char ** var = char* var[] or char var[][]

char *** var = char var[][][] or char* var[][] or char** var[]

Is this incorrect? I was confused because I saw a char*[][] cast as a char** in a simple text book example.

I pasted the example below. Can anyone clear this up for me? Thanks!


/* 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;

}

解决方案

The rule for C is as follows:

6.3.2.1 Lvalues, arrays, and function designators
...
3 Except when it is the operand of the sizeof operator or the unary & operator, or is a string literal used to initialize an array, an expression that has type ‘‘array of type’’ is converted to an expression with type ‘‘pointer to type’’ that points to the initial element of the array object and is not an lvalue. If the array object has register storage class, the behavior is undefined.

The language for C++ is a little different:

4.2 Array-to-pointer conversion [conv.array]

1 An lvalue or rvalue of type "array of N T" or "array of unknown bound of T" can be converted to an rvalue of type "pointer to T". The result is a pointer to the first element of the array.
...
8.3.4 Arrays [dcl.array]
...
7 A consistent rule is followed for multidimensional arrays. If E is an n-dimensional array of rank i × j × ... × k, then E appearing in an expression is converted to a pointer to an (n−1)-dimensional array with rank j × ... × k. If the * operator, either explicitly or implicitly as a result of subscripting, is applied to this pointer, the result is the pointed-to (n−1)-dimensional array, which itself is immediately converted into a pointer.

So the following all hold true:

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

The pattern should be clear for higher-dimensional arrays.

So let's analyze your dictionary:

/* 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 */         
};

This isn't going to set up your dictionary the way you want; you've basically set this up as a 1-element array of 40 pointers to char. If you want an array of pairs of strings, then the declaration should look like this:

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.  
}; 

The type of dic is "5-element array of 2-element arrays of pointer to char", or char *[5][2]. Going by the rules above, the expression dic should decay to char *(*)[2] -- a pointer to a 2-element array of pointer to char.

A function to search this dictionary would then look like this:

char *definition(char *term, char *(*dictionary)[2]) // *NOT* char ***dictionary
{
  while ((*dictionary)[0] != NULL && strcmp((*dictionary)[0], term) != 0)
    dictionary++;
  return (*dictionary)[1];
}

and you would call it from your main function like

char *def = definition(term, dic);

Note that we have to use parentheses around the *dictionary expression in the function. The array subscript operator [] has higher precedence than the dereference operator *, and we don't want to subscript into dictionary directly, we want to subscript into the array that dictionary points to.

这篇关于在 C/C++ 中,char* arrayName[][] 是指向指针的指针还是指向指针的指针?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆