Closed6

printf

bayamasabayamasa

prinf上での16進数のprefixは0xではなく、xのみ
なぜならエスケープシーケンスが認知するのは最初の文字だけなので、
\0xとしてしまうと、最初の0が認知されてNULL文字と同等のものとみなされるから。
なのでエスケープ + xで以下に16進数が来るということを示している。
http://wisdom.sakura.ne.jp/programming/c/Cdata1.html

bayamasabayamasa

以下のようなコードが有るときにコンパイラはwarningを出し、出力結果は何もない。
(ファイルに出力するとファイルサイズが0のファイルが生成される)

#include <stdio.h>

int main()
{
	printf("\0");
	return (0);
}

これはなぜかというとprintfが第一引数を文字として扱っているからである。
文字として扱う場合、文字列の終端はNULL文字であるので、文字列の中に\0を入れても、出力結果としては何も変わらない。
ちなみにprintf("") と prinf("\0")の時の実行結果の差分をアセンブリファイルで見ると
(main.sが("")のとき、main_1.s("\0")のとき)

❯  diff main.s main_1.s 
11c11
<       leaq    L_.str(%rip), %rdi
---
>       leaq    l_.str(%rip), %rdi
21,23c21,23
<       .section        __TEXT,__cstring,cstring_literals
< L_.str:                                 ## @.str
<       .space  1
---
>       .section        __TEXT,__const
> l_.str:                                 ## @.str
>       .space  2

.strの中の.spaceが変わっている。
これは与えられた文字列に対して確保するメモリがいくつなのかを示している

bayamasabayamasa

ちなみにもし\0を文字列に含めたい場合には以下の様にするとよい

int main()
{
	printf("%c", '\0');
	return (0);
}

なんでこれだと\0が入るかの詳細な部分は不明

bayamasabayamasa

以下のような場合、出力結果は1

#include <stdio.h>

int main()
{
	printf("%d", printf("%c", (char)NULL));
	return (0);
}
❯  ./a.out 
1
bayamasabayamasa

以下のような場合、出力結果は0となる。
理由は前述の通り

int main()
{
	printf("%d", printf("%s", "\0"));
	return (0);
}
❯  ./a.out 
0
このスクラップは2021/10/15にクローズされました