Ste*_*mit 39 c arrays pointers terminology
几乎每个读这篇文章的人都熟悉这三个关于C的关键事实:
[]与指针一样适用于指针.这三个事实绝对是C中数组和指针处理的核心.它们甚至不是三个独立的事实; 它们是一个中心概念的相互关联的方面.如果没有对这个概念的正确理解,就不可能正确地进行相当基本的C编程.
我今天的问题很简单,这个概念的名称是什么?
我以为我是老式的,但我总是把它称为"C中数组和指针之间的等价",或简称为"数组/指针等价".但我知道你几乎不能在SO上说出这些话; 他们几乎是禁忌.
这可能看起来像一个抽象或哲学问题,所以更具体地构建它,我正在寻找的是一个简单的名词或名词短语我可以在句子中使用"是的,由于_____,数组下标可以被认为是作为指针算术的语法糖",回答,比方说,这个问题.
(但是请注意,我不是在寻找这个问题的答案,也不是为了回答"'等价'这个词有什么问题?".是的,我知道,它会误导学习者想象数组和指针是某种方式同样.当我写这个FAQ列表条目时,我确实有这种困惑.)
Lun*_*din 29
- "数组下标"运算符[]对于指针也适用于数组.
不,实际上它只适用于指针.无论何时键入[]表达式,总是会得到指向第一个元素的指针.这保证会发生,因为arr[i]必须等同于*(arr + i).前者是后者的"语法糖".
- 似乎是数组的函数参数实际上声明了一个指针.
这实际上是一种特殊情况,称为"数组调整",其中编译器隐式地将数组类型的函数参数的声明更改为指向第一个元素的指针.理由肯定是使函数与表达式的"数组衰减"兼容,但C标准使术语保持分离.
这两种情况,表达式和函数参数通常被非正式地称为"阵列衰减".虽然有时这只用于表达式而不用于函数参数.我不认为该术语存在单一,一致的用法."数组衰减"是我认为最好的,尽管C标准在任何地方都没有使用该术语.
(我不喜欢术语"等价",因为一个数组可以变成一个指针,但不是相反的方式.确实总是有无数的初学者提出了混淆的信念,比如"数组和指针是一回事".称它们为"相当于"并没有完全帮助."
zwo*_*wol 13
C标准对此没有一个单词.它在6.3.2.1p3中定义行为(1)时使用"转换"一词,在6.5.2.1p2中定义行为(2)时使用"等效",在6.7.6.3p7中定义行为(3)时使用"调整".
我是老式的,并且认为调用这个"数组/指针等价"没有任何问题,只要在上下文中你明白你正在讨论(1)发生的表达式或者(3)发生的函数声明.然而,对于那些不喜欢"等价"的人来说,一个更可口的术语可能是"数组到指针的转换",因为这会使人们最常混淆的是(1),我认为.
我会选择数组衰减的术语.这个术语与它的建议很顺利.在这种情况下,C标准没有说明这一点,是的,第一天我听到了我在标准中搜索它的术语,但我找不到它(因此对于谁创造了这个术语等有点困惑).另外一个人可以写,因为"大多数场景阵列被转换成指针"...... - 不,这不是一个单一的名词.但这不会让任何误解发生.标准本身称之为"转换".
大多数时候我试着说它很长的路然后把这个词("数组衰减")放在括号中.实际上有答案,我甚至没有提到它,只是按照标准的转换成指针的话.
我建议"数组到指针衰减"是一个合理的简写,因为"衰变"在引用类型转换时是常见的术语,在C FAQ的其他地方有先例:问题6.12:
问:由于数组引用衰减成指针,如果arr是一个数组,arr和&arr之间有什么区别?
自C++ 11以来,C++标准库命名法已经采用了包含这一术语的"衰变"的扩展技术含义: std::decay
所提到的三个概念没有单一的名称,但我认为将它们描述为暗示任何类型的"等价"是适得其反的,至少在描述"现代"C时.虽然数组衰减的结果通常表现得像指针, C99指定由数组衰减产生的指针不需要以与通过其他方式实现的指针相同的方式运行.鉴于:
char fetch_byte_at(void *p, int x) { return ((char*)p)[x]; }
struct {char arr[5][7];} s;
char test1(int x) { return s.arr[0][x]; }
char test2(int x) { return fetch_byte_at(&s, x); }
Run Code Online (Sandbox Code Playgroud)
标准没有直接指定s.arr[0]使用的指针值test1不应等于调用((char*)(void*)s)时使用的指针值的任何原因.然而,它确实同时暗示应该能够读出所有字节[暗示它应该可预测地使用最多至少34的值],同时说这仅对最多6的值有意义.fetch_byte_attest2test2sxs.arr[0][x]x
虽然标准中的任何内容都不会单独与前两个点相矛盾,但两者都不可能成立.数组衰减的结果不是指向数组第一个元素的"普通"指针,或者将[]运算符应用于数组与将其应用于指针有不同的语义.虽然目前还不清楚#1和#2中的哪一个被C99无效,但它们不再在现代C中形成任何类型的"等价".
如果您认识到传统C和"现代"C之间的区别,那么为使前者有用的事物建立术语可能是有用的.然而,这些事情超出了你提到的要点.不幸的是,我不知道这些事情的任何标准术语,并且当它不再支持所涉及的概念时,不会寻求标准提供这样的术语.