在 printf 中使用 (+ve integer) + "some string "?
Using (+ve integer) + "some string " in printf?
#include <stdio.h>
void main() {
printf(2 + "abcdefgh");
}
这段代码如何打印cdefgh
?如果我使用 2-
或 2*
或任何其他运算符,编译器会抛出错误。
在此代码中
printf(2 + "abcdefgh");
与
相同
printf(&("abcdefgh"[2]));
其中,参数用作 printf()
.
中的格式字符串
详细说明,根据 字符串文字的属性 ,引用 C11
,章节 §6.4.5/P6
In translation phase 7, a byte or code of value zero is appended to each multibyte
character sequence that results from a string literal or literals.78) The multibyte character
sequence is then used to initialize an array of static storage duration and length just
sufficient to contain the sequence. For character string literals, the array elements have
type char
, and are initialized with the individual bytes of the multibyte character
sequence. [...]
对于数组,来自章节 §6.3.2.1,
Except when it is the operand of the sizeof
operator, the _Alignof
operator, or the
unary &
operator, or is a string literal used to initialize an array, an expression that has
type ‘‘array of type’’ is converted to an expression with type ‘‘pointer to type’’ that points
to the initial element of the array object and is not an lvalue. [...]
所以,在函数调用参数的情况下,作为加法运算符的参数之一,字符串字面量实际上是将字面量中的第一个元素的地址加起来,然后是加法,这是一个指针运算,发生了。结果是指向第三个元素的递增指针(C 数组是从 0 开始的索引)。
也就是说,正如上一段所强调的,指针运算仅对加法运算有效,对乘法运算无效。
当使用诸如 "abcdefgh"
之类的字符串文字时,您实际上有一个指针指向该字符串所在的内存部分。基本上,您将指向该位置的指针传递给 printf
并指示它将指针向前移动 2 个位置,从而导致字符串从第 3 个字符开始而不是第一个
请注意,您可以使用 -
,但您需要像使用指针算术一样使用它,例如
printf("abcdefgh" - 0); // using -N where N >0 would be UB
因此,此代码有效
int main()
{
printf("abc\n" - 0);
printf(1+"def");
return 0;
}
但使用 *,/
不会(按位运算符 |,&
也无效)
#include <stdio.h>
void main() {
printf(2 + "abcdefgh");
}
这段代码如何打印cdefgh
?如果我使用 2-
或 2*
或任何其他运算符,编译器会抛出错误。
在此代码中
printf(2 + "abcdefgh");
与
相同printf(&("abcdefgh"[2]));
其中,参数用作 printf()
.
详细说明,根据 字符串文字的属性 ,引用 C11
,章节 §6.4.5/P6
In translation phase 7, a byte or code of value zero is appended to each multibyte character sequence that results from a string literal or literals.78) The multibyte character sequence is then used to initialize an array of static storage duration and length just sufficient to contain the sequence. For character string literals, the array elements have type
char
, and are initialized with the individual bytes of the multibyte character sequence. [...]
对于数组,来自章节 §6.3.2.1,
Except when it is the operand of the
sizeof
operator, the_Alignof
operator, or the unary&
operator, or is a string literal used to initialize an array, an expression that has type ‘‘array of type’’ is converted to an expression with type ‘‘pointer to type’’ that points to the initial element of the array object and is not an lvalue. [...]
所以,在函数调用参数的情况下,作为加法运算符的参数之一,字符串字面量实际上是将字面量中的第一个元素的地址加起来,然后是加法,这是一个指针运算,发生了。结果是指向第三个元素的递增指针(C 数组是从 0 开始的索引)。
也就是说,正如上一段所强调的,指针运算仅对加法运算有效,对乘法运算无效。
当使用诸如 "abcdefgh"
之类的字符串文字时,您实际上有一个指针指向该字符串所在的内存部分。基本上,您将指向该位置的指针传递给 printf
并指示它将指针向前移动 2 个位置,从而导致字符串从第 3 个字符开始而不是第一个
请注意,您可以使用 -
,但您需要像使用指针算术一样使用它,例如
printf("abcdefgh" - 0); // using -N where N >0 would be UB
因此,此代码有效
int main()
{
printf("abc\n" - 0);
printf(1+"def");
return 0;
}
但使用 *,/
不会(按位运算符 |,&
也无效)