Mar*_*ler 29
编译器将转向
index[array]
Run Code Online (Sandbox Code Playgroud)
成
*(index + array)
Run Code Online (Sandbox Code Playgroud)
使用正常的语法,它将转向
array[index]
Run Code Online (Sandbox Code Playgroud)
成
*(array + index)
Run Code Online (Sandbox Code Playgroud)
因此,您会看到两个表达式都评估为相同的值.这适用于C和C++.
从C的早期开始,表达式a[i]
只是添加到i的[0]的地址(按[0]的大小按比例放大),然后取消引用.事实上,所有这些都是等价的:
a[i]
i[a]
*(a+i)
Run Code Online (Sandbox Code Playgroud)
====
我唯一关心的是实际的解引用.虽然它们都产生相同的地址,但如果类型
a
和i
不同,则可以考虑解除引用.例如:
int i = 4;
long a[9];
long x = a[i]; //get the long at memory location X.
long x = i[a]; //get the int at memory location X?
Run Code Online (Sandbox Code Playgroud)
我实际上没有测试过这种行为,但这可能是你需要注意的.如果它确实改变了被引用的内容,那么它也可能导致对象数组出现各种问题.
====
更新:
您可以安全地忽略=====
行之间的位.我已经在Cygwin下进行了短暂和长时间的测试,看起来没问题,所以我猜我的担心是没有根据的,至少在基本情况下如此.我仍然不知道更复杂的事情会发生什么,因为这不是我可能想要做的事情.
正如Matthew Wilson在Imperfect C++中讨论的那样,这可以用来强制C++中的类型安全,方法是阻止使用DIMENSION_OF()
类似于定义下标运算符的类型实例的类似宏,如:
#define DIMENSION_OF_UNSAFE(x) (sizeof(x) / sizeof((x)[0]))
#define DIMENSION_OF_SAFER(x) (sizeof(x) / sizeof(0[(x)]))
int ints[4];
DIMENSION_OF_UNSAFE(ints); // 4
DIMENSION_OF_SAFER(ints); // 4
std::vector v(4);
DIMENSION_OF_UNSAFE(v); // gives impl-defined value; v likely wrong
DIMENSION_OF_SAFER(v); // does not compile
Run Code Online (Sandbox Code Playgroud)
对于处理指针,还有更多内容,但这需要一些额外的模板智能.检查出的实施STLSOFT_NUM_ELEMENTS()
在STLSoft库,并在第14章读到这一切不完美的C++.
编辑:一些评论者建议实施不拒绝指针.它确实(以及用户定义的类型),如以下程序所示.您可以通过未注释的第16行和第18行来验证这一点.(我只是在Mac/GCC4上执行此操作,它拒绝这两种形式).
#include <stlsoft/stlsoft.h>
#include <vector>
#include <stdio.h>
int main()
{
int ar[1];
int* p = ar;
std::vector<int> v(1);
printf("ar: %lu\n", STLSOFT_NUM_ELEMENTS(ar));
// printf("p: %lu\n", STLSOFT_NUM_ELEMENTS(p));
// printf("v: %lu\n", STLSOFT_NUM_ELEMENTS(v));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
3755 次 |
最近记录: |