【问题标题】:Sizeof string vs sizeof string pointersizeof 字符串与 sizeof 字符串指针
【发布时间】:2021-04-21 03:06:28
【问题描述】:

在以下代码中:

char *title = "VP";
printf("Sizeof title: %zd | Sizeof *title: %zd | Strlen: %zd\n", sizeof title, sizeof *title, strlen(title));

标题大小:8 |大小 *标题:1 |强度:2

似乎sizeof title 对指向字符串的指针(对我来说是 8 个字节)进行操作,而 strlen(title) 可以预见地给了我 2 个。

为什么sizeof *title 在解引用指针时产生 1 而不是 3(字符串的字节长度)?例如,为什么它这样做而不是它会产生什么:

printf("%zd\n", sizeof("VP"));
// 3

【问题讨论】:

标签: c


【解决方案1】:

指针的大小总是指针本身的大小,而不是它所指向的大小。那是因为sizeof 主要是编译时运算符(结果由编译器评估),编译器无法知道指针在运行时可能指向什么。

sizeof *titlesizeof title[0] 相同,char 是单个 charchar 的大小为1(顺便说一下,它指定为始终1,无论实际位宽如何)。

最后是关于sizeof "VP"。在 C 中,所有文字字符串实际上都是字符的 数组,包括终止的空字符。所以文字字符串"VP"是三个字符的数组,因此它的大小是3


为了让答案更完整一点,我说sizeof 运算符是大部分 编译时。对于variable-length arrays,这当然不是真的,编译器必须插入代码以存储数组的实际大小,使其可以在运行时获取。如果数组衰减为指针,那么您所拥有的只是指针,sizeof 再次返回指针本身的大小。

还有一个关于字符串字面量数组的说明。虽然它们在技术上是-常量数组,但它们仍然无法修改。尝试修改字符串文字会导致未定义的行为。因此,文字字符串实际上是只读的。

【讨论】:

  • -- 谢谢。什么是建议的方式,您可以执行 sizeof 的运行时等效项以获得 3
  • @samuelbrody1249 一个可变长度数组,如size_t length = 3; char array[length]; strcpy(array, "VP"); 然后sizeof array 将在运行时计算。但是,一旦数组衰减为指针,sizeof 就会返回指针的大小。
  • @samuelbrody1249 所有字符串文字都是“全局的”,数组在程序的生命周期内永远不会超出范围。所以你总是可以使用指向文字字符串的指针。
  • “它们仍然无法修改。” --> 更像是“不应该尝试修改”。尝试修改 字符串文字 可能会奏效。是UB。
  • @samuelbrody1249 在某些操作系统中“签名size_t”。例如ssize_t,它在 POSIX(Linux 或 macOS 等操作系统)中定义。那么%zd 是有效的。但对于普通的 C 标准 size_t,它需要是一个无符号说明符(如 %zu)。
【解决方案2】:

title 的类型是char *,所以*title 的类型是char不是char [3]。因此,sizeof *title 等价于 sizeof (char),即 1。

title 不是字符串,它只是指向字符串的第一个元素。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-08-17
    • 2018-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-29
    相关资源
    最近更新 更多