响应您的更新(关注sizeof(foo+1) 类型的情况:
是的,应用于array_name + int 的sizeof 等效于sizeof &(array_name[int]);,因为在这些情况下,数组会衰减为指针。同样,要从数组中获取实际值,您不要写arr_name + 1,而是写*(arr_name + 1)。
那么,考虑到脚注,sizeof 何时会产生实际的数组大小(以字节为单位)?为此,请查看标准中关于数组衰减为指针的内容:
除非它是 sizeof 运算符或一元 & 运算符的操作数,或者是用于初始化数组的字符串字面量,否则类型为 ''array of type'' 的表达式将转换为类型为 ' 的表达式'pointer to type'' 指向数组对象的初始元素,不是左值。
意思:
- 直接在数组变量上使用
sizeof (sizeof array_var)
- 取消引用指向数组的指针 (
sizeof *(&array_var)) 注意:当您将此指向数组的指针传递给另一个函数时,这也适用,但并不总是最好的方法(参见下面的示例)
- 字符串字面量(如
char foo[] = "foobar"; => sizeof("foobar"); 中的右值)
在所有其他情况下(AFAIK),数组衰减为指针,sizeof 将产生指针的大小:
- 数组算术 => 指针算术 (
sizeof (array_var +1 ))
- 将数组传递给函数(衰减为指针)
- ...
将数组传递给函数
因此,使用一元& 运算符, 可以将指向数组的指针传递给函数,但很少这样做。不过,这里有一个例子:
void pointer_to_array(char (*ptr)[]);//pointer to array type
void error_p_to_arr(char (*ptr)[]);
int main ( void )
{
char str[] = "some random string";//array of 18 bytes
printf(
"Sizeof array %zu\n",
sizeof str
);
pointer_to_array(&str);
return 0;
}
//we need to specify the exact type, including size!
//replace 18 with 10, you're fine, but use 20 and you're in trouble
void pointer_to_array(char (*ptr)[18])
{
printf(
"sizeof argument: %zu\nsizeof array %zu",
sizeof ptr,//4 or 8
sizeof *ptr//18!! YaY
);
}
//if we don't specify the array size here
void error_p_to_arr(char (*ptr)[])
{
printf(
"sizeof argument: %zu\nsizeof array %zu",
sizeof ptr,//4 or 8
sizeof *ptr//ERROR!
);
}
后者sizeof *ptr 会导致错误(“‘sizeof’对不完整类型‘char[]’的无效应用”)。因为这种传递数组的方式很容易出错(必须在任何地方定义正确的大小),所以更常见的是简单地让数组衰减,并随之传递第二个参数:
void common_usage(const char *ptr, size_t arr_len);
int main ( void )
{
char str[] = "some random string";
common_usage(str, sizeof str/sizeof *str);
return 0;
}
它看起来更干净,更常见,更容易维护。