c语言 - 在 printf 中使用 (+ve 整数) + "some string "?


#include <stdio.h>
void main() {
printf(2 + "abcdefgh");
}

此代码如何打印cdefgh?如果我使用2-2*或任何其他运算符,编译器会抛出错误。

当使用字符串文本(如"abcdefgh"(时,您实际上有一个指向此字符串所在的内存部分的指针。基本上,您将指向该位置的指针传递给printf并指示它将指针向前移动 2 个位置,从而产生从第 3 个字符而不是第一个字符开始的字符串

请注意,您可以使用-但您需要像使用指针算术一样使用它,例如

printf("abcdefgh" - 0); // using -N where N >0 would be UB

所以,这个代码是有效的

int main()
{
printf("abcn" - 0);
printf(1+"def");
return 0;
}

但是使用*,/不会(按位运算符|,&也将无效(

在此代码中

printf(2 + "abcdefgh");

printf(&("abcdefgh"[2]));

其中,参数用作printf()中的格式字符串。

为了详细说明,从字符串文字的属性中,引用C11,第 §6.4.5/P6 章

在转换阶段 7 中,值为零的字节或代码附加到每个多字节 由一个或多个字符串文本生成的字符序列。78(多字节字符 然后使用序列来初始化静态存储持续时间和长度的数组 足以包含序列。对于字符串文本,数组元素具有 键入char,并使用多字节字符的各个字节进行初始化 序列。[...]

对于数组,来自第 §6.3.2.1 章,

除非它是sizeof运算符、_Alignof运算符或 一元&运算符,或者是用于初始化数组的字符串文本,该表达式具有 类型"类型数组"转换为类型为"指向类型的指针"的表达式,该表达式指向 到数组对象的初始元素,并且不是左值。[...]

因此,在函数调用参数的情况下,作为加法运算符的参数之一,字符串文字实际上向下移动到文字中第一个元素的地址,然后,加法(指针算术(发生。结果以递增的指针表示,该指针指向第三个元素(C 数组是从 0 开始的索引(。

也就是说,正如上一段所强调的,指针算术仅对法运算有效,而对乘法运算符无效。

最新更新