C C++数组……需要帮助理解代码

3

能否请您解释一下这段代码?它对我来说有点困惑。 "a"是一个双精度数组吗?我认为它只是一个整数,但在cout语句中它被用作双精度数组。而且在for循环条件中,它说a<3[b]/3-3,这对我来说毫无意义,但是代码可以编译和运行。我只是难以理解它,它在语法上似乎不正确。

int a,b[]={3,6,5,24};
char c[]="This code is really easy?";
for(a=0;a<3[b]/3-3;a++)
{
cout<<a[b][c];
}

11
写那段代码的人应该被解雇......这恰恰是编写代码时要避免的情况。 - Reed Copsey
@Reed:我怀疑这是故意的。看起来像是一个测试学生通过语法的能力的作业... - dmckee --- ex-moderator kitten
3
话虽如此,从技术上讲,它也存在漏洞,因为它将要访问b[4](因为a在小于5的情况下进行迭代),但该索引不存在。 - Reed Copsey
1
这显然不是C语言,除非在这段代码之外定义了一个cout整数。 - dreamlax
8
“我看到 cout 被向左移动了 'Hello world' 次,然后停在那里。”(这是必须引用的一句话) - Alok Singhal
显示剩余2条评论
9个回答

7

数组访问器几乎是指针算术的语法糖。 a[b] 等效于 b[a] 等效于 *(a+b)

尽管如此,使用 index[array] 而不是 array[index] 是非常可怕的,你永远不应该使用它。


3
我想这是我第一次见到有人解释为什么a[b]和b[a]是等价的……现在指出来后似乎显而易见了,但是看到它写成*(a+b)后,经过多年的C编程,那种语法终于变得清晰明了。 - Tanzelax
1
@Tanzelax - 这种等价性在许多C语言文本中都有提到(并且应该在任何好的文本中都有)。这是“[]”运算符的定义。它既出现在Harbison&Steele中,也出现在C标准中(除了Plauger的“标准C库”之外,这两者几乎是我现在所参考的唯一的C语言文本 - 不幸的是,C ++仍然需要大量的文本)。 - Michael Burr
2
@Anon:有一个情况我会使用 index[array] 的形式——在宏中获取数组元素的数量。使用 index[array] 形式可以防止表达式意外地在 C++ 类中工作,该类重载了 '[]' 运算符(诚然,这是非常专业化的用法)。 - Michael Burr
这有助于例如数组大小宏,在这个答案中可以看到:https://dev59.com/2nI-5IYBdhLWcg3w8dYQ#1598827 - Georg Fritzsche
@Michael:是的,我也看到过 a[b] = *(a+b)(就像你说的,在几乎所有的 C 语言教材中都有),还有 a[b] = b[a],但出于某种原因,这两个部分就是没有联系起来。 - Tanzelax
显示剩余2条评论

6

哇,这真的很奇妙。这并不是真正的二维数组,它之所以起作用是因为c是一个数组,在C语言中有一个标识符可以处理这个。

b[3]

和这个一样

3[b]

所以这段代码转换成了一个循环,它增加了while a < (24/3-3),因为3[b]b[3]相同,而b[3]为24。然后它使用a[b](与b[a]相同)作为数组c的索引。

所以,未混淆的代码是:

int a;
int b[] = {3,5,6,24}
char c[] = "This code is really easy?";
for (a = 0; a < 5; a++)
{
    cout << c[b[a]];
}

由于 b[4] 不存在,所以输出应该为字符串 c 的第3、5、6和24个字符或

sco?

接着是一些随机字符或崩溃。


我明白了。我不知道3[b]和b[3]是一样的...好的,现在我懂了它是如何工作的。非常感谢大家。 - user69514
换句话说,在C语言中,数组下标是可交换的。请注意,这并非所有C++变体(例如Visual C++)都适用。 - Demi

2
int a,b[]={3,6,5,24};

声明了两个变量,一个整型变量a和一个整型数组b。
char c[]="This code is really easy?";

声明一个包含给定字符串的字符数组。
for(a=0;a<3[b]/3-3;a++)

遍历范围[0..4]:

  • 3[b]是另一种表示b[3]的方式,即24。
  • 24 / 3 = 8
  • 8 - 3 = 5

cout << a[b][c];

这将输出以下结果:

  • a[b] 相当于 b[a],这将是 b[0..4]
  • b[0..4][c] 是另一种说法,即 c[b[0..4]]

不是 c[0..4],应该是 c[b[0..4]]。 - Reed Copsey

2

不,第一条语句中声明了两个变量:int aint b[]

a[b][c]只是说 c[b[a]]的一种巧妙的方式,这是因为数组的语法:b[0]0[b] 是等价的。


0

代码中有一个简单的技巧。a[3]在C编译器中与3[a]完全相同。

了解了这一点,您的代码可以转化为更有意义的形式:

int a,b[]={3,6,5,24};
char c[]="This code is really easy?";
for(a=0;a<b[3]/3-3;a++)
{
cout<<c[b[a]];
}

0

好的 - 首先,让我们来解决for循环。

当你写b[3]时,这相当于*(b+3)*(b+3)也等同于*(3+b),可以写成3[b]。这基本上可以被重写为更易理解的形式:

for(a=0; a < ((b[3]/3) - 3); a++) 

由于b[3]是一个常量值(24),你可以将其视为:

for(a=0; a < ((24/3) - 3); a++) 

或者

for(a=0; a < (8 - 3); a++) 

最后:

for(a=0; a < 5; a++) 

在您的情况下,这将使a从0到4迭代。然后,您输出a[b][c],它可以重写为c[b[a]]。
但是,我不明白这样编译和运行是否正确,因为它正在访问c[b[4]] - 而b只有4个元素。按照现在的写法,这是有缺陷的。

0

a<3[b]/3-3 等同于写成

a < b[3]/3-3

而且 a[b] 和 b[a] 是一样的,因为 a 是一个整数 所以 b[a] 是 {3,6,5,24} 中的一个项目

这意味着 a[b][c] 就是 b[a][c] 它可以是 c[{3,6,5,24}] 中的任何一个


0

在C语言中,foo[bar]会被“展开”为*(foo + bar)。因此,a[b]实际上与b[a]相同(因为加法是可交换的),意味着数组b的第a个元素。而a[b][c]c[b[a]]相同,即c中的第i个字符,其中i是b的第a个元素。


0

首先:'a'未初始化。我们假设它被初始化为0。

'3[b]/3-3'等于5。循环将使用'a'从0到4。('3[b]'是'b[3]')

在a==4步骤中,'a[b]'(因此是'b[a]')将超出界限('b'的界限为0..3),因此它具有未定义的行为。在我的电脑上,有时会输出“Segmentation fault”,有时不会。直到那一点,它输出:“soc?”


我的错。我过去习惯于在循环中声明和初始化变量,或者尽可能晚地进行初始化,所以这个问题跑到了我的脑海之外。 :-) - Notinlist

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接