cco*_*987 38 c sizeof unary-operator
在下面的代码中,功能test和test2等效的是什么?
typedef int rofl;
void test(void) {
rofl * rofl = malloc(sizeof(rofl)); // Is the final rofl here the TYPE?
}
void test2(void) {
rofl * rofl = malloc(sizeof *rofl); // Is the final rofl here the VARIABLE?
}
Run Code Online (Sandbox Code Playgroud)
换一种说法:
rofl在sizeof(rofl)正确挑选rofl 类型,因为括号?rofl在sizeof *rofl正确地挑选rofl 可变的,因为一个缺少括号?注意:这是一个看起来很愚蠢的例子,但在实践中实际上你可以使用与变量名相同的类型名称.因此问题.
M.M*_*M.M 27
在这两种情况下,最后一个rofl 是变量名称.变量名一出现就在范围内; 对于当前范围的其余部分,普通上下文(*)中的标识符始终表示变量名称.
该sizeof运营商不引入的名称查找任何特殊情况.实际上,没有语言结构会使用标识符的隐藏含义.
实际上,不要对类型和变量名使用相同的标识符.
(*)标识符有三种特殊的上下文:标签名称,结构标签和结构成员.但在所有其他上下文中,所有标识符共享一个公共名称空间:类型名称与变量名称与函数名称等没有明确的标识符名称空格.
这是一个人为的例子:
typedef int A; // "A" declared as ordinary identifier, meaning a type name
struct A { A A; }; // "A" declared as struct tag and member name -- OK as these are three different name spaces. Member type is "int"
A main() // int main() - ordinary context
{
struct A A(); // "A" declared as ordinary identifier, meaning a function name; hides line 1's A
// A C; // Would be error: ordinary A is a function now, not a typedef for int
struct A B; // OK, struct tags have separate name space
A:+A().A; // OK, labels and struct members have separate name space, calls function
goto A; // OK, label name space
}
Run Code Online (Sandbox Code Playgroud)
Vla*_*cow 13
在这个宣言中
rofl * rofl = malloc(sizeof(rofl)); // Is the final rofl here the TYPE?
Run Code Online (Sandbox Code Playgroud)
变量的名称rofl隐藏了typedef名称rofl.因此,在sizeof运算符中,使用rofl了表达式具有类型的指针int *.
这同样适用于此声明
rofl * rofl = malloc(sizeof *rofl);
Run Code Online (Sandbox Code Playgroud)
除了使用带有解除引用指针的表达式,该指针rofl具有typedef rofl类型的类型int.
似乎由于这种C语法定义而产生混淆
sizeof unary-expression
sizeof ( type-name )
Run Code Online (Sandbox Code Playgroud)
但是,unary-expression可以是括在括号中的表达式的主表达式.
来自C标准(6.5.1主表达式)
primary-expression:
( expression )
//...
Run Code Online (Sandbox Code Playgroud)
因此,例如,如果x是变量的名称,那么您可以编写
sizeof x
Run Code Online (Sandbox Code Playgroud)
要么
sizeof( x )
Run Code Online (Sandbox Code Playgroud)
为清楚起见,您可以在sizeof运算符和主表达式之间插入空格
sizeof ( x )
operator primary expression
Run Code Online (Sandbox Code Playgroud)
为了比较,考虑另一个一元运算符:一元加号.你可以写例如
+ x
Run Code Online (Sandbox Code Playgroud)
要么
+ ( x )
Run Code Online (Sandbox Code Playgroud)
现在只需将一元加号替换为另一位一元运算符sizeof.
至于隐藏名称,问题可以解析为结构,联合和枚举,因为它们的名称包括标记的关键字.
例如
typedef struct rofl { int x; } rofl;
void test(void) {
rofl * rofl = malloc(sizeof( struct rofl));
}
Run Code Online (Sandbox Code Playgroud)
在使用sizeof运算符的函数中,使用了type-name struct rofl.
而在这个功能
typedef struct rofl { int x; } rofl;
void test(void) {
rofl * rofl = malloc(sizeof( rofl));
}
Run Code Online (Sandbox Code Playgroud)
使用sizeof运算符时,使用带有变量的主表达式,该变量rofl具有类型struct rofl *.