質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Clang

Clangは、プログラミング言語 C、C++、Objective-C、Objective-C++ 向けのコンパイラである。

FreeBSD

FreeBSDは、Unix系のオープンソースのOSです。PC/AT互換機用ですが、他のプラットフォームにも移植されています。優れたネットワーク・セキュリティ・ストレージ機能で人気のOSです。ソースコードと共に無償で公開されており、多くの コミュニティによって長年に渡って開発されています。

Q&A

解決済

1回答

940閲覧

C言語 FreeBSDで理解できない処理 (intmax_t)numの後、再度型を変換する理由を知りたい。

Kchan_01

総合スコア110

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Clang

Clangは、プログラミング言語 C、C++、Objective-C、Objective-C++ 向けのコンパイラである。

FreeBSD

FreeBSDは、Unix系のオープンソースのOSです。PC/AT互換機用ですが、他のプラットフォームにも移植されています。優れたネットワーク・セキュリティ・ストレージ機能で人気のOSです。ソースコードと共に無償で公開されており、多くの コミュニティによって長年に渡って開発されています。

0グッド

0クリップ

投稿2020/11/13 16:18

編集2020/11/16 06:51

C言語を勉強しています。
printfのコードを確認していて、理解できない処理がありましたので質問させていただきます。

以下のコードの517行目のあたりのところです。
freebsd/printf.c at master · freebsd/freebsd

c

1number: 2 if (sign && (intmax_t)num < 0) { 3 neg = 1; 4 num = -(intmax_t)num; 5 }

printfで連携された数字が一度uintmax_t型の変数に代入され、それからマイナスの値をチェックするためにキャストされる部分です。

(intmax_t)num < 0
までは理解できるのですが
num = -(intmax_t)num;
は何をしているのでしょうか。
キャストしただけで元の数に変化はないと思うのですがなぜ再度キャストして代入するのでしょうか。

以下で試してみましたが、キャストで値が変更されたままということは無いようです。

c

1#include <stdio.h> 2 3int main() 4{ 5 unsigned char a = 240; 6 printf("%d\n", a); 7 printf("%d\n", (char)a); 8 printf("%d\n", a); 9 return (0); 10}
240 -16 240

よろしくお願いします。

2020/11/16 追記

質問の意図をうまく伝えられず、すみません。

negのフラグを入れると値が変わるような実装になっているのが疑問ということです。

c

1#include <stdio.h> 2 3int main() 4{ 5 int neg = 0; 6 unsigned char num; 7 8 num = 255; 9 printf("%d\n", num); 10 if ((char)num < 0) 11 { 12 neg = 1; 13 printf("%d\n", (char)num); 14 printf("%d\n", num); 15 num = -(char)num; 16 printf("%d\n", num); 17 } 18 return (0); 19}

実行結果

255 -1 255 1

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

dodox86

2020/11/13 17:28

質問の前提が間違っているかもしれません。 > キャストしただけで元の数に変化はないと思う いいえ。「num = -(intmax_t)num;」と、'-'が付いているので、キャストしただけではなく、正負の値を逆転させています。ソースコード上ではフラグ変数negと共に、さらに後の方、書式制御文字列に対応させるためのコードに影響しているので、その点を考慮すると本質問も変わってくるのではないでしょうか。
Kchan_01

2020/11/16 07:07 編集

@dodox86さん 修正依頼ありがとうございます。 むしろsignedを超えるunsignedの数値が来たときに値が変わってしまう実装になっていることに疑問を感じているので質問しました。うまく説明できず、すみません。 疑問点をコード例とともに追記しました。
Kchan_01

2020/11/16 07:52

失礼しました。理解できました。もともとの値がマイナスであっても、unsignの変数に格納されているため、それを正しい値に戻す処理だったことが理解できました。
guest

回答1

0

ベストアンサー

キャストしただけで元の数に変化はないと思うのですが

2の補数表現の場合、マイナスの方が絶対値の1大きな値まで入れられるので、単項マイナス演算子を付けて正に戻すと値域からはみ出ることがありえます。

投稿2020/11/13 23:01

maisumakun

総合スコア145183

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問