プログラマはC言語の中のこれらの細かいところを知らないです。

10852 ワード

テーマはすべて小さい细い点だと言って、1つは细い点を绍介しますとどんなに面白くありませんか?先にみんなを陥れて更に详しく绍介するようにしましょう、へへへへ。直接7つの问题に行きましょう。あなたがいくつに対してすることができることを见てみますか?
計算式の詳細
①:

#include <stdio.h>
int main()
{
	char a = 3;
	char b = 127;
	char c = a + b;
	printf("   :%d",c);
	return 0;
}
この問題の答えはどれぐらいですか?先に後ろの答えを見ないでください。
答えは-126です。へへ、間違えましたか?焦らずに次の問題を見てください。
②:

#include <stdio.h>
int main()
{
	char a = 0xb6;
	short b = 0xb600;
	int c = 0xb6000000;
	if(a==0xb6)
		printf("a");
	if(b==0xb600)
		printf("b");
	if(c==0xb6000000)
		printf("c");
	return 0;
}
この問題の答えは何ですか?先に後ろの答えを見ないでください。
答えはcです。へへ、また間違いを答えますか?焦らないでください。後の問題を見てください。
③:

#include <stdio.h>
int main()
{
	 char c = 1;
	 printf("%u
", sizeof(c)); printf("%u
", sizeof(+c)); printf("%u
", sizeof(-c)); return 0; }
この問題の答えは何ですか?先に後ろの答えを見ないでください。
答えは4です。へへ、また間違いを答えますか?焦らないでください。後の問題を見てください。
式の詳細
①:

#include <stdio.h>
int main()
{
	 int c = 3;
	 int ret = c + --c;
	 printf("%d",ret);  
	 return 0;
}
この問題の答えは何ですか?先に後ろの答えを見ないでください。
答えは5か4です。 です。へへ、また間違いを答えますか?焦らないでください。後で見てください。
面の問題
②:

int main()
{
	 int i = 10;
	 i = i-- - --i * ( i = -3 ) * i++ + ++i;
	 printf("i = %d
", i); return 0; }
この問題の答えは何ですか?先に後ろの答えを見ないでください。
答えはたくさんあります。違うコンパイラで結果が違っています。つまり です。へへへ、まだ答えが間違っていますか?まず焦らないでください。後の問題を見てください。
③:

#include <stdio.h>
int fun()
{
     static int count = 1;
     return ++count;
}

int main()
{
     int answer;
     answer = fun() - fun() * fun();
     printf( "%d
", answer);// ? return 0; }
この問題の答えは何ですか?先に後ろの答えを見ないでください。
答えは です。へへへ、また間違いを答えますか?焦らないでください。後の問題を見てください。
④:

#include <stdio.h>
int main()
{
	 int i = 1;
	 int ret = (++i) + (++i) + (++i);
	 printf("%d
", ret); printf("%d
", i); return 0; }
これは最後の問題です。今何回正解しましたか?コメントしてください。
この問題の答えは です。
皆さんはいくつの問題に答えましたか?コメント
 1.今は上のすべての問題の設計内容を正式に説明します。
表式のシークの順序の一部は、オペレータの優先度と結合性によって決定されます。
同様に、いくつかの表式の演算数は、値を求める過程で他のタイプに変換する必要があります。
1.1暗黙的なタイプの転換(全体型の切断と向上)
何が隠蔽タイプの転換で、整体は昇格して、整体は切断しますか?
Cの整数演算は、常に によって行われる。
この精度を得るためには、表式にcharshortのタイプがあると、使用前に変換しなければならないのが整体型であり、このプロセスを と呼ぶ。
..。
大きいデータタイプが小さいデータタイプに格納されているプロセスは と呼ばれていますが、aは彼の値をa = 500に置いています。bはaを完全に保存できません。 bが発生します。
..。
この変換挙動は と呼ばれています。
1.1.1第一題の解説

#include <stdio.h>
int main()
{
	char a = 3;
	char b = 127;
	char c = a + b;
	printf("   :%d",c);
	return 0;
}
私たちはコンピュータの中のすべてが操作の補完コードであることを知っています。だからここも同じです。
その中の正数の原コードは逆コードの補数が同じです。
…負の数の補数は逆符号プラス一で、逆符号は元の符号で、記号のビット以外はすべてビットで逆に取ります。
aバイトは1バイトしかありません。彼の補完コードは (バイナリ)です。
bは1バイトだけで、彼の補数は00000011(バイナリ)です。
aプラスbは、算術操作を行い、4バイトにアップグレードする必要があります。整体アップには2つの方法があります。
  • 算術リフティング:32ビット
  • まで、一番前にシンボルのビット数を補足する。
  • 論理アップ:何でも0だけ補って、32ビットまで。
  • ほとんどの計算機は01111111で行われています。ここでは を説明します。
    a算術を上げたら です。
    b算術を上げたら00000000000000000000000000000011です。
    a+bの結果は------00000000000000000000000001111111です。
    cに保存しても、cは1バイトしかないので、カットオフが発生し、最後の8桁だけアクセスします。00000000000000000000000010000010このときcは補数コードにアクセスし、cは符号型であり、10000010はプリント表示時に元のコードを返します。この補数は !!です。
    次の文字タイプ-126の対応理解図があります。
    在这里插入图片描述
    したがって、記号の範囲は[-128,127]です。
    符号なしの範囲は[0,255]です。
    丸になったらもっと分かりやすくなります。自分で記号の有無に応じて探してください。
    在这里插入图片描述
    1.1.2第二題の解説
    
    #include <stdio.h>
    int main()
    {
    	char a = 0xb6;
    	short b = 0xb600;
    	int c = 0xb6000000;
    	if(a==0xb6)
    		printf("a");
    	if(b==0xb600)
    		printf("b");
    	if(c==0xb6000000)
    		printf("c");
    	return 0;
    }
    
    0 xb 6のバイナリは です。
    aに保存するとカットオフが発生し、00000000000000000000000010110110を得る。
    0 xb 600のバイナリは1011 0110です。
    bに保存するとカットオフが発生し、00000000 00000000 10110110 00000000を得る。
    0 xb 600 0000 10110110 00000000cに預けたほうがいいです。
    aこの時に保存したのは補数コードで、aはまた0 xb 6と比較して、演算に参加したので、また整体が10110110 00000000 00000000 00000000
    整型アップグレード後の数字は0 xb 6のバイナリと違っていますので、違います。
    bこの時に保存したのは補数コードで、bはまた0 xb 600と比較して、演算に参加したので、また型を整えて11111111 11111111 11111111 10110110整型アップグレード後の数字は0 xb 600のバイナリと違っていますので、違います。
    cこの時点で保存されているのは11111111 11111111 10110110 00000000です。注意してください。10110110 00000000 00000000 00000000は正数ですか?0xb6000000、字面定数は符号を持たない限りデフォルトintタイプです。ですから、 !!!!!の整数値はintを超えています。このときのバイナリはマイナスの補数であると考えられます。だから、cは0xb6000000と同じです。
    1.1.3番の解説
    
    #include <stdio.h>
    int main()
    {
    	 char c = 1;
    	 printf("%u
    ", sizeof(c)); printf("%u
    ", sizeof(+c)); printf("%u
    ", sizeof(-c)); return 0; }
    0xb6000000は、タイプ属性の値を測定する。sizeofのタイプはcで、一バイトしかないので、答えは1です。char+cは単一目のオペレータです。cと一緒に全体形のアップグレードが発生しました。intになりました。だから、4バイトです。答えは4バイトです。+、同じ道理は相変わらず-cです。
    1.2算術変換
    上で述べましたが、操作数がintより小さいと、整数値が上がりますが、intサイズ以上のタイプが演算に参加しますか?ここで4に触れます。
    算術変換とは?例えば、次の例:
    
    #include <stdio.h>
    int main()
    {
    	int a = -127;
    	unsigned int b =  129;
    	if(a > b)
    	{
    		printf("a   b");
    	}
    	return 0;
    }
    結果は を印刷します。
    これは算術変換です。つまり同じタイプの演算を満たす必要があります。unsigned intはintより高いです。だから、aの値はデフォルトで符号なしです。aはbより大きくなります。
    算術の向上方向:
    在这里插入图片描述
    1.3オペレータの属性
    複雑な表現の求め方には三つの影響がある。
    オペレータの優先度操作子の結合性は、シーク順序を制御するかどうか。
    1.3.1優先度は何ですか?
    まず何を計算するかを決めます。例えば、a bd = a + b*cより優先度が高いので、*を先に計算して+を計算します。
    1.3.2何が結合性ですか?
    同じ優先度であり、どの方向から計算するかを決定します。例えばb*cは、連続する+のため、優先度がすでに使われていないので、このとき結合性です。d = a * b * cの結合性は左から右までです。つまり、*を計算してから*を計算します。
    1.1.3何が価値を求める順序ですか?
    つまり、どちらを計算しますか?c言語のオペレータが求める順序を持っているのはわずかです。例えば、a*b*cはいったいどういう意味ですか?
    例えば、aは0に等しい、bは2に等しい、cは3に等しい、||, && , !、dの値は最後に0であるが、演算時にaに行くだけで終わってしまう、 は偽に出会うと偽になるので、後の真偽はもう関係なく、aは0で、偽である。
    以下の二つの値を求める順序についての練習があります。
    
    #include <stdio.h>
    int main()
    {
        int i = 0,a=0,b=2,c =3,d=4;
        i = a++ && ++b && d++;
        printf("a = %d
    b = %d
    c = %d
    d = %d
    ", a, b, c, d); return 0; }
    答えはd = a && b && cです。理由:aは後置+で、a=0の値を先に使って、最初から休暇があって、後はもう実行しません。しかし、aはやはり追加されました。後置加算は&&です。
    
    #include <stdio.h>
    int main()
    {
        int i = 0,a=0,b=2,c =3,d=4;
        i = ++a || ++b || d++;
        printf("a = %d
    b = %d
    c = %d
    d = %d
    ", a, b, c, d); return 0; }
    1 2 3 4、前置++で、aは1になりました。 は本当に会ったら終わります。後の真偽はもう気にしません。だから、aだけ変わりました。
    ここにオペレータ属性の表があります。
    在这里插入图片描述
    その中で優先度は上から下へ徐々に低下します。
    1.3.4第四題の解説
    
    #include <stdio.h>
    int main()
    {
    	 int c = 3;
    	 int ret = c + --c;
    	 printf("%d",ret);  
    	 return 0;
    }
    1 2 3 4には2つの操作記号があります。まず||を見て、ret = c + --cの優先度が より高いので、先にCcを計算することにしましたが、--号の左のcはいつ準備されましたか?c言語はコンパイル言語であることを知っています。コードを作成してからマシン言語にコンパイルして実行する必要があります。コンパイルする時、+番の左の値は+の前にコンパイルされましたか?それとも+の後にコンパイルすればいいですか?これは不確実です
  • はvsコンパイラの下で答えは4で、彼は--cの後でc
  • を用意しました。
  • gccコンパイラで答えは5です。彼は--cの前にc
  • を用意しました。
    だから:これは問題コードです。これからはこのようなごみコードを書かないでください。
    1.3.5第五題の解説
    
    int main()
    {
    	 int i = 10;
    	 i = i-- - --i * ( i = -3 ) * i++ + ++i;
    	 printf("i = %d
    ", i); return 0; }
    これは同じことです。優先度は分かりますが、結合性の中の操作数はいつ準備されますか?不明です。異なるコンパイラで操作した結果を見てください。
    在这里插入图片描述
    同じごみコードです。
    1.1.6第六題の解説
    
    #include <stdio.h>
    int fun()
    {
         static int count = 1;
         return ++count;
    }
    
    int main()
    {
         int answer;
         answer = fun() - fun() * fun();
         printf( "%d
    ", answer);// ? return 0; }
    --c関数の呼び出し記号の優先度が一番高いですが、ここには三つがあります。どれを先に呼び出しますか?これはまた確定しませんでした
  • vsコンパイラは左から右に順番に呼び出します。結果は-10です。
  • です。
  • ですが、他のコンパイラは?みんなでgccを試してみてください。codeblocks、Devc++とは違いがあります。
    1.3.7第7題の解説
    それに、この問題の前に、ブロガーはいくつかの大学を批判しなければならないのに、なぜですか?学校がみんなに--c号を教える時、このタイプでみんなを試験するのが一番好きですか?ここで明確にお伝えしますが、これは全く時間の無駄です!!!このコードはまったく意味がないから!!()
    
    #include <stdio.h>
    int main()
    {
    	 int i = 1;
    	 int ret = (++i) + (++i) + (++i);
    	 printf("%d
    ", ret); printf("%d
    ", i); return 0; }
    まず、++括弧の優先度が一番高いですが、どれを先に計算しますか?
    第二に、一つの の変化は他のものに影響しますか?ここも不確定です。第四問と私達が話したコンパイルの前に()は一体いつ準備しますか?確実ではないです。!
    vsコンパイラの値は12 gccコンパイラの値は10 4です。
    異なるコンパイラの値が違っていて、結果が違っています。このコードはコードと呼ばれません。!!
    ですから、これからこの問題を直接飛ばしてみても意味がありません。
    まとめ:一体型の向上とカットオフは何かが分かりました。算術変換はどの操作符の属性を知っていますか?今後はこのようなごみコードを書くことができません。
    以上はプログラマはC言語の中のこの小さい細部の詳しい内容を知らないので、C言語の細かいところについての資料は他の関連記事に注目してください。