【问题标题】:Strange case while using the sizeof() operator in C在 C 中使用 sizeof() 运算符时的奇怪情况
【发布时间】:2011-12-03 16:12:01
【问题描述】:

我正在使用以下代码在 C/C++ 中测试 sizeof 运算符的使用:

#include <ctype.h>              /* Character types                       */
#include <stdio.h>              /* Standard buffered input/output        */
#include <stdlib.h>             /* Standard library functions            */
#include <string.h>             /* String operations                     */
#include <sys/types.h>          /* Data types                            */
#include <sys/wait.h>           /* Declarations for waiting              */
#include <unistd.h>   

void main()
{
  char a[100];
  char *des = malloc(100*sizeof(char));
  strcpy(des,"abcded\0");
  printf("%d\n",sizeof(des));
  printf("%d\n",sizeof(a));
  free(des);
}

这个程序为什么会输出:

4
100

相对于:

100
100

【问题讨论】:

  • 因为你还没有读过comp.lang.c faq ...从第6节开始:)
  • 它是int main; C 不是 Java。
  • @Jens 早在 Java 出现之前,人们就一直将 main 错误地输入为 void。这是错误的,但根本没有理由提到 Java,真的。

标签: c sizeof


【解决方案1】:

因为,尽管有很多人断言,指针和数组在 C 和 C++ 中并不是 100% 可互换的。这是其中一种差异的明显示例。

指针的大小为 4 字节(或任何特定于平台的大小),无论它可能指向多少分配的内存。

数组的大小就是数组的大小。

【讨论】:

  • 内存未“分配给 [指针]”。我在您的回答中强调这种糟糕的措辞的原因是,这种对指针的错误看法可能首先是造成 OP 问题的原因。
  • 修改了我的答案以澄清指针和分配之间的关系(或缺乏关系)。
【解决方案2】:

这个问题的答案很简单。

des 的类型是“char *”或字符的地址。因此,您使用 sizeof 向编译器提出的问题是“我需要多少内存(以字节为单位)来存储字符的地址?”编译器响应 4 因为您的程序和编译器具有 32 位(4 字节)寻址。当您在数组上使用 sizeof 时,您会问一个不同的问题,即“我需要多少内存(以字节为单位)来存储 100 个项目的字符数组?”这里的答案是 100 项 * 1 字节 = 100 字节。

【讨论】:

    【解决方案3】:

    我将稍微详细说明abelenky 的评论。您是否希望这两个 typedef 产生等效类型?

    typedef char *string;
    typedef char string[100];
    

    这两个怎么样?

    typedef struct { char *s; ... } header_t;
    typedef struct { char s[100]; ... } header_t;
    

    在这两种情况下,您的答案显然是否定的。是的,您可以编译des=a,因为a 产生一个指针,但a 实际上是一个数组。

    特别是,您还知道最后一个 typedef 没有为指针保留内存。结果,a 大致具有char * const 类型,这意味着a 是指向非常量字符的常量指针,因此a=des 给出了类型错误。我不知道该错误消息是否会抱怨数组、const 或左值。

    【讨论】:

      【解决方案4】:

      sizeof 运算符产生编号。一种类型的字节数。

      sizeof des 给出 100,因为 des 的类型是 char[100],一个 char 总是占用 1 个字节,其中有 100 个。

      sizeof a 给出 4,因为 a 的类型是 char*,并且 char 指针在您的平台上占用 4 个字节(这在 32 位平台上很常见。)

      所以,sizeof 只适用于它的操作数的类型(注意,sizeof 是一个运算符,它不是一个函数/宏)。 sizeof 不与 malloc 交互,a 指向 100 个动态分配字节的开头这一事实无关紧要。

      【讨论】:

        【解决方案5】:
        printf("%d\n",sizeof(des));
        printf("%d\n",sizeof(a));
        

        等价于:

        printf("%d\n",sizeof(char*));      //prints size of a pointer
        printf("%d\n",sizeof(char[100]));  //size of a char array of size 100
        

        换句话说,sizeof 是一个运算符,它对您传递给它的表达式的类型 进行操作。因此,当您编写sizeof(des) 时,表达式的typechar*,因此它会在您的系统上打印sizeof(char*),即4。但是对于sizeof(a),表达式的类型是char[100],因此它打印sizeof(char[100]),即100

        这里讨论了sizeof 的一个更有趣的案例:

        【讨论】:

          【解决方案6】:

          因为它返回了指针des的大小,该指针指向已分配的内存。

          【讨论】:

            【解决方案7】:

            sizeof(des) 返回指针的大小 - 在您的系统上为 4。它不会返回它指向的分配空间的大小。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2011-08-10
              • 2012-02-07
              • 1970-01-01
              • 1970-01-01
              • 2020-07-30
              • 2013-03-13
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多