Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ruby-on-rails-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ int(*a)[3]的解释_C++_C_Arrays_Pointers_Types - Fatal编程技术网

C++ int(*a)[3]的解释

C++ int(*a)[3]的解释,c++,c,arrays,pointers,types,C++,C,Arrays,Pointers,Types,在C语言中使用数组和指针时,人们很快就会发现它们根本不是等价的,尽管乍一看似乎是这样。我知道L值和R值的区别。尽管如此,最近我试图找出我可以与二维数组结合使用的指针类型,即 int foo[2][3]; int (*a)[3] = foo; 然而,尽管有*和[]的常规运算符优先级规则,我还是无法找出编译器是如何“理解”a的类型定义的。如果改用typedef,问题会变得简单得多: int foo[2][3]; typedef int my_t[3]; my_t *a = foo; 最后,有人能

在C语言中使用数组和指针时,人们很快就会发现它们根本不是等价的,尽管乍一看似乎是这样。我知道L值和R值的区别。尽管如此,最近我试图找出我可以与二维数组结合使用的指针类型,即

int foo[2][3];
int (*a)[3] = foo;
然而,尽管有
*
[]
的常规运算符优先级规则,我还是无法找出编译器是如何“理解”a的类型定义的。如果改用typedef,问题会变得简单得多:

int foo[2][3];
typedef int my_t[3];
my_t *a = foo;
最后,有人能回答我关于编译器如何读取术语
int(*a)[3]
的问题吗
inta[3]
很简单,
int*a[3]
也很简单。但是,为什么它不是
int*(a[3])

编辑:当然,我不是说“typecast”,而是说“typedef”(这只是一个打字错误)。

为什么“not
int*(a[3])
”是正确的(指你的最后一个问题)?
int*(a[3])
与普通的
int*a[3]
相同。大括号是多余的。这是一个指向
int
的3个指针数组,你说你知道它的意思

int(*a)[3]
是指向3个
int
数组的指针(即指向
int[3]
类型的指针)。在这种情况下,大括号很重要。您自己提供了一个正确的示例,该示例通过中间
typedef
进行等效声明

简单流行的由内而外的C声明读取规则在这种情况下非常有效。在
int*a[3]
声明中,我们必须先从
a
开始,然后向右走,即得到
a[3]
,这意味着
a
是一个由3个某物组成的数组(依此类推)。
int(*a)[3]
中的
()
改变了这一点,因此我们不能直接从
*a
开始:
a
是指向某个东西的指针。继续解码该声明,我们将得出结论,某物是一个3
int
的数组


在任何情况下,都可以找到一本关于阅读C声明的好教程,其中有很多可以在网上找到。

编译器可能比您更容易解释。一种语言定义了一组规则来定义有效表达式的组成部分,编译器使用这些规则来解释这些表达式(听起来可能很复杂,但编译器已经被详细研究过了,并且有很多标准化的算法和工具可用,您可能想了解一下)。是一个将C表达式翻译成英语的工具。源代码可以在网站上找到,因此您可以查看它。C++编程语言的书包含了编写程序的样例代码,如果我没有错的话。 至于你自己解释这些表达,我发现C++中的第1卷:

中的思考技巧是最好的。 要定义指向没有参数和返回值的函数的指针,可以说:

无效(*funcPtr)()

当你看到一个复杂的 像这样的定义,最好的方法 进攻是从中间开始 找到你的出路。“从 “中间”的意思是从中间开始 变量名,即funcPtr。 “走出困境”意味着看 向右移动到最近的项目 (本案中无任何规定;权利 括号使你停下来),然后 向左看(指针表示为 按星号),然后查看 右(空参数列表) 表示一个不接受任何条件的函数 参数),然后向左看 (void,表示函数 没有返回值)。这 右-左-右运动与 大多数声明

复习“从中间开始” (“funcPtr是一个…”),向右走 (那里什么都没有——你被警察拦住了 右括号),转到左边 查找“*”(“…指向…”的指针), 向右走,找到空的 参数列表(“…函数 不接受任何参数…),请转到 左键并找到空白(“funcPtr是一个 指向不接受任何值的函数的指针 参数并返回void”)

你可以在上免费下载这本书。让我们尝试将其应用于
int(*a)[3]

  • 从中间的名称开始,在这种情况下,A。到目前为止,它是这样写的:“a是a…”
  • 向右走,你会遇到一个右括号阻止你,所以你向左走,找到*。现在你读到了:'a是指向…'的指针'
  • 向右走,你会发现[3],意思是一个由3个元素组成的数组。表达式变成:“a是指向3的数组的指针…”
  • 最后到左边找到int,最后得到“a是指向3个int数组的指针”

  • 您可能会发现这篇文章很有帮助:

    如果有人想添加更多的资源,我已经把这个答案做成了一个社区维基(因为它只是一篇文章的链接,而不是答案)。

    首先,你的问题是“typedef”而不是“typecast”

    在C语言中,指向类型
    T
    的指针可以指向类型
    T
    的对象:

    int *pi;
    int i;
    pi = &i;
    
    以上内容很容易理解。现在,让我们把它变得更复杂一点。您似乎知道数组和指针之间的区别(即,您知道数组不是指针,但有时它们的行为与指针类似)。因此,您应该能够理解:

    int a[3];
    int *pa = a;
    
    但为了完整性起见:在赋值中,名称
    a
    相当于
    &a[0]
    ,即指向数组
    a
    的第一个元素的指针。如果您不确定这是如何工作的以及为什么工作的,那么有许多答案确切地解释了数组名称何时“衰减”到指针以及何时不衰减:

    • 我对题为
    • 当数组的名称不衰减为指针时的另一个实例,以及
    • T
      int foo[2][3];
      
      /* declare p somehow */
      p = foo[0];
      
      /* What should be the type of q? */
      q = foo;
      
      q = &foo[0];
      
      int (*q)[3];
      
      $ cdecl
      cdecl> declare p as  pointer to array 3 of int
      int (*p)[3]
      cdecl> explain int (*p)[3]
      declare p as pointer to array 3 of int
      
      int (*a)[3];
      
            a            # "a is"
          (* )           # parentheses, so precedence changes.
                         # "a pointer to"
              [3]        # "an array [3] of"
      int        ;       # "int".
      
      int *a[3];
      
           a             # "a is"
            [3]          # "an array [3] of"
          *              # can't go right, so go left.
                         # "pointer to"
      int      ;         # "int".
      
      char *(*(*a[])())()
      
                a         # "a is"
                 []       # "an array of"
               *          # "pointer to"
              (    )()    # "function taking unspecified number of parameters"
            (*        )   # "and returning a pointer to"
                       () # "function"
      char *              # "returning pointer to char"
      
      int* a[3];
      
      typedef int threeInts[3];
      threeInts* pointerToThreeInts;
      
      [/tmp]$ cdecl
      Type `help' or `?' for help
      cdecl> explain int (*a)[10];
      declare a as pointer to array 10 of int