找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

2123

积分

0

好友

281

主题
发表于 1 小时前 | 查看: 2| 回复: 0

在C语言中,sizeof 是一个操作符(operator),而不是函数。它的作用是计算数据类型或者表达式所占用的内存字节数。通常有两种使用形式:
(1)sizeof(类型说明符)
(2)sizeof 表达式
我们一般更常用第一种带括号的形式。

它的返回值类型是 size_t,这个类型在头文件 stddef.h 中定义。其本质是一个依赖于编译系统的无符号整数,通常在32位环境下类似这样定义:

typedef unsigned int size_t;

在深入学习之前,我们先确定一下当前编译环境中,C语言基本数据类型的字节大小。以下是一个简单的测试程序,请注意,本文示例的运行环境均为32位。

#include <stdio.h>

int main(void)
{
  printf("sizeof(char)  = %u\n", sizeof(char));
  printf("sizeof(short) = %u\n", sizeof(short));
  printf("sizeof(int)   = %u\n", sizeof(int));
  printf("sizeof(long)  = %u\n", sizeof(long));
  printf("sizeof(float) = %u\n", sizeof(float));
  printf("sizeof(double)= %u\n", sizeof(double));

  return 0;
}

程序运行的输出结果如下:
C语言基本数据类型字节大小测试结果

从结果可以看到,在典型的32位环境中,char 占1字节,short 占2字节,intlongfloat 均占4字节,double 占8字节。这些基础知识是理解后续内容的前提。

一个看似简单却极易出错的例子

sizeof 的基础概念听起来很简单,对吧?那么,下面这段代码的输出结果,你能准确预测出几个呢?😏

#include <stdio.h>

int main(void)
{
  char *s = "hello";

  printf("sizeof(char) = %u\n", sizeof(char));
  printf("sizeof(char*)= %u\n", sizeof(char*));
  printf("sizeof('a')  = %u\n", sizeof('a'));
  printf("sizeof(*s+0) = %u\n", sizeof(*s+0));
  printf("sizeof(*s)   = %u\n", sizeof(*s));
  printf("sizeof(s)    = %u\n", sizeof(s));

  return 0;
}

实际的运行结果是:
sizeof操作符在不同表达式下的输出结果

怎么样,有没有被其中几个结果“惊喜”到?没懵的话算我输 😑。
一脸懵逼表情图

结果逐条分析

别急,我们来逐一拆解这些结果背后的原理。理解这些细节,对于掌握 C 语言的底层内存管理和编译行为至关重要。

  1. sizeof(char) = 1
    这个最直接,C 语言标准规定 char 类型的大小为 1 字节。

  2. *`sizeof(char) = 4** 这里计算的是指针本身的大小。在 32 位环境中,无论是什么类型的指针(charint等),其大小通常都是 4 字节,因为它存储的是一个 32 位的地址。这与unsigned int` 的字节长度是一致的。

  3. sizeof(‘a’) = 4
    这是第一个容易让人困惑的点。为什么一个字符常量占了 4 字节?
    在 C 语言中,字符常量(如 ’a’)的类型实际上是 int,而不是 char。因此 sizeof(‘a’) 计算的是 int 类型的大小,在 32 位环境下自然是 4 字节。你可以把它理解为字符 ’a’ 对应的 ASCII 码值(十进制 97)作为一个整数存储。
    需要注意的陷阱:如果你这样定义 char ch = ‘a’;,那么 sizeof(ch) 的值就是 1,因为 ch 是一个明确声明为 char 类型的变量。所以,上下文环境决定了 sizeof 的计算对象。

  4. sizeof(*s+0) = 4*
    表达式 `
    s取到的是字符串”hello”的第一个字符’h’。然后’h’ + 0` 进行了算术运算。这里涉及到了 C 语言的
    隐式类型转换*(或称“整型提升”)。当 char 类型参与算术运算时,它会首先被转换为 int 类型。因此,整个表达式 `s+0的结果类型是intsizeof` 计算其大小得到 4。

    C 语言中类型转换的规则可以总结为下图(图片来源网络),它清晰地展示了不同数据类型混合运算时的转换方向:
    C语言数据类型自动转换规则示意图
    图注:注意,float 类型与除 double 外的类型运算后,结果仍为 float

  5. *`sizeof(s) = 1** 这与第 3 点形成对比。这里的s是一个char类型的值(字符’h’)。sizeof计算的是这个char类型值本身的大小,所以是 1。关键点在于,这里的s` 没有参与任何会引发类型转换的运算。

  6. sizeof(s) = 4
    这里的 s 就是我们定义的变量,它是一个 char* 类型的指针。因此,和第二条一样,计算的是指针变量本身的大小,在 32 位环境下为 4 字节。

总结与思考

通过这个精心设计的例子,我们可以更深刻地理解 sizeof 操作符:

  • sizeof 是操作符,不是函数,它在编译时就完成计算。
  • 计算字符常量(如 ’a’)时,其类型是 int
  • charshort 等小于 int 的类型参与表达式运算时,会发生整型提升,这会直接影响 sizeof 的结果。
  • 计算指针时,sizeof 得到的是指针变量本身存储地址所需的内存大小,与它指向的数据类型和内容无关。
  • 同样一个字符,在不同的上下文(是独立常量,还是变量值,亦或是表达式的一部分)中,sizeof 的结果可能天差地别。

掌握这些细微之处,不仅能帮助你在笔试面试中应对此类刁钻问题,更能让你在编写涉及底层内存操作、数据对齐或平台移植的代码时,做到心中有数,避免潜在的 Bug。希望这篇解析能帮你把 sizeof 弄得明明白白。如果在实践中遇到其他有趣的问题,欢迎到云栈社区与更多开发者一起交流探讨。




上一篇:开源资助平台 thanks.dev 机制解析:依赖树如何决定谁获得资金
下一篇:深入解析:C语言for循环在ARM裸机环境下的汇编实现与栈操作
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-3-17 06:49 , Processed in 0.462699 second(s), 41 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表