使用sizeof表达式时,数组会转换为指针吗?

时间:2013-09-23 05:18:13

标签: c arrays pointers gcc sizeof

我有以下来源:

/*file a2ptr.c */ 
#include <stdio.h>
#include <stddef.h>
typedef struct m_St m_St;
struct m_St
{
    size_t idx;
    size_t m_data[8];
}*x;

size_t GetSize(m_St *s)
{
    s->idx=1;
    return (sizeof((s->idx ? x : s)->m_data));
}
int main(void)
{
    m_St s = { 0 };
    printf("GetSize() returns: %zu\n", GetSize(&s));
    return 0;
}

在使用GCC 4.8.1的32位Linux上,此代码生成以下输出:

$ gcc -Wall -Werror a2ptr.c  
$ ./a.out  
GetSize() returns: 32

我的问题:
(s->idx ? x : s)->m_data是否是C中的有效表达式? 为什么GetSize()返回整个数组的大小(以字节为单位)而不是指向其第一个元素的指针的大小(例如,sizeof(size_t))?

4 个答案:

答案 0 :(得分:3)

  

(s->idx ? x : s)->m_data是C中的有效表达式吗?

是。

  

为什么GetSize()返回整个数组的大小(以字节为单位)而不是指向第一个元素的指针的大小(例如,sizeof(size_t))

阅读:

  

6.5.3.4 The sizeof operator, 1125:

     

将sizeof运算符应用于数组类型时,结果是数组中的总字节数。

根据这一点,当sizeof应用于静态数组标识符的名称(不是通过malloc分配)时,结果是整个数组的大小(以字节为单位)而不是地址。这是few exceptions to the rule that the name of an array is converted/decay to a pointer to the first element of the array之一,它可能只是因为实际的数组大小是固定的,并且在sizeof运算符求值时在编译时是已知的。所以'数组名'没有转换为指针。

要查找数组长度,请阅读:Weird behavior when printing array in C?

另请阅读:

  

<强> 1118
  sizeof运算符应用于具有函数类型或不完整类型的表达式到括号中   此类型的名称,或指定位字段的表达式   构件。

     

<强> 1119
  sizeof运算符产生其操作数的大小(以字节为单位),该操作数可以是表达式或括号的名称。   类型。

答案 1 :(得分:2)

  

使用sizeof表达式时,数组会转换为指针吗?

没有


现在在评论中看到你的问题:

  

根据ISO C99标准:§6.5.3.4sizeof运算符88)应用于参数时   声明具有数组或函数类型,sizeof运算符产生调整后的大小   (指针)类型。这个引用是否适用于我的例子?我错过了什么地方?

你错过了parameter这个词。这基本上只是另一种方式,说一个人不能真正地将数组传递给一个函数,只有指针,因为数组在传递给函数时总是会衰减成指针。您引用的条款涉及以下案例:

void foo(char arr[1000])
{
    // will print sizeof(char *), because in a function argument context,
    // (and ONLY there), T array[N] is the same as T *arrray
    printf("%zu\n", sizeof(arr));
}

现在,如果你的数组是......,那么,真实数组而不是伪装指针,那么它会衰减到指针,如果它是sizeof运算符的参数。

答案 2 :(得分:0)

size_t m_data[8];
return sizeof(m_data);   // <-- in this case same as return (sizeof(size_t) * 8);

所以如果你想返回元素的数量,你应该这样做:

size_t m_data[8];
return ( sizeof(m_data) / sizeof(size_t) );

“当使用sizeof表达式时,数组会转换为指针吗?” 。当一个数组被转换( decayed )到一个指针时,你的混淆可能是基于某种东西,称为数组衰减,并且能够使用它来检索数组的长度遗失sizeof

size_t getSize(size_t* myDecayedArray) {
    return sizeof(myDecayedArray);     // <-- same as return ( sizeof(size_t*) );
}
...
size_t m_data[8];
return getSize(m_data);                       // <-- array decayed into pointer

请参阅What is array decaying?

答案 3 :(得分:-1)

sizeof在编译时计算 - 而不是运行时。