C言語のパズル

私たちはたくさんのC言語依存の何かを見ることができます。このような「あいまいな言語」として曖昧であなたのC言語と何か予期しないエラーで皆に伝えるために主にあります。そして、あなたはあなたのC言語を伝えるためにコードを書くためにいくつかの一見不可能を通じて決して「C言語は、非常に単純ではないと言う人」簡単なことではありません。「6倒錯ハローワールド」と「Cのソースコードめちゃめちゃどのように」私たちは自分自身の混乱のコードを書くとは思わない、あなたを伝えるために極端な方法を示し、各プログラマは、実際にコードをしました潜在的な混乱。これらの記事を通じ、私はあなたを信じているか、何をプログラムを考えることは非常にシンプルなC言語では、いくつかの理解を持っています。はい、それは容易ではない、それは以前に過小評価し、Cプログラミング言語ではないのですか?今日、我々はそれにC ++とJavaを過小評価している場合?

この記事は、「C言語のパズルは、」コードは十分に明確にする必要があり、14 C言語のパズルと解答を示しているが、私はまた、かなりの例では、私たちの毎日の仕事の取得に応えることができるかもしれないがあると信じています。これらのパズルを通じ、私はあなたがC言語についての詳細を知ることができると思います。あなたは答えが表示されない場合、私はそれぞれの謎に答えるようにしてくださいがあるかどうか分からないのですか?試してみましょう。

 

1、次のプログラムと必ずしも出力のhello-STD-うち、あなたはなぜ知らないのだろうか?

#include <stdio.h>

#include <unistd.h>

int main()

{

    while(1)

    {

        fprintf(stdout,"hello-std-out");

        fprintf(stderr,"hello-std-err");

        sleep(1);

    }

    return 0;

}

回答:stdoutとstderrは、同じデバイス記述子ではありません。stdoutがブロックデバイスで、標準エラー出力ではありません。ブロックするための装置は、以下の状況が入力される場合にのみ、1)に遭遇入力し、2)緩衝液3)フラッシュが呼び出され、一杯になります。そして、stderrはしません。

2、次の手順では、初期化を行うコンマ式を使用して、正常に見えます。残念ながら、このプロセスには問題があります。あなたは理由を知っていますか?

#include <stdio.h>



int main()

{

    int a = 1,2;

    printf("a : %d/n",a);

    return 0;

}


回答:このプログラムはコンパイルエラー(構文エラー)を受け取りますが、コンマ式は右ですが、初期化および変数宣言の意味ではなく、コンマコンマ式。この点を区別するために、手順は上記を変更するには、括弧を追加する必要があります。int A =(1,2);

3.何が次のプログラムの出力が何だろうか?

#include <stdio.h>

int main()

{

    int i=43;

    printf("%d/n",printf("%d",printf("%d",i)));

    return 0;

}


参考答え:プログラムは、出力4321は、あなたがなぜ知っているのだろうか?理由を知るために、あなたが知っておくべきことのprintfイエスの戻り値。printf関数の戻り値は、文字出力の数です。

4、次のプログラムが出力されますでしょうか?

#include <stdio.h>

int main()

{

    float a = 12.5;

    printf("%d/n", a);

    printf("%d/n", (int)a);

    printf("%d/n", *(int *)&a);

    return 0;

}


解答
プログラム出力は、以下に示されている
0
12である
1095237632
12.5fをバイナリに変換される4バイトの浮動小数点数、:理由01000001010010000000000000000000、Hexがある:0×4148万、小数である:1095237632。したがって、私たちはすべての理由を知っていると信じて第二と第三の出力。まず一つは、なぜ出力0は、我々はフロートを見て、次のように、メモリレイアウトを倍増する必要があります。

  • フロート:1符号ビット(S)、8ビットの指数(E)、23ビットの仮数(M、32の合計)
  • ダブル:1符号ビット(S)、11ビットの指数(E)、52ビットの仮数(M、64の合計)

その後、我々はまた、型が一致しないため、フロートは、二重に直接行くfloatとdoubleのバイナリメモリの12.5は完全に異なることに注意されますので、printfのを見てする必要があります。逆にする抗エンディアンのx86チップ、上位バイトと下位ワードのビットで使用されていることを忘れないでください。そう:

  • フロート版:0×4148万(メモリである:00004841)
  • 二重のバージョン:0×4029000000000000(メモリ内にある:0,000,000,000,002,940)

私たちの要件は4%Dバイトintは、二重のメモリレイアウトのために、我々は最初の4つのバイトが00であることを見ることができるので、出力は当然0です。

この例では、タイプセーフされていない、C ++はその理由として引用するCOUTがある理由であるprintfの私たちを示しています。

5は、以下の、我々は物事のクロスコンパイラを見て、次の2つのファイルは、それによってコンパイルすることができますか?あなたができるならば、結果は何ですか?

file1.c
  int arr[80];
file2.c
extern int *arr;
int main()
{
    arr[1] = 100;
    printf("%d/n", arr[1]);
    return 0;
}

参考答え:プログラムをコンパイルすることができますが、実行時エラーが。なぜ?その理由は、外部の配列を宣言するために、にextern int型*の編曲であり、彼らは試合のタイプではありませんので、と別のファイルに現実的な期待を取得することはできません。実際のポインタが得られると、その配列を指していません。注:配列へのポインタは、アレイは等しくありません。変更:[] ARRのextern int型。(参考:ISO C言語のセクション6.5.4.2)

図6は、次のプログラム出力がどのくらいであると言うてください?そして、理由を説明?(プログラムは、出力が「bが20である」しないことに注意してください)

#include <stdio.h>

int main()

{

    int a=1;

    switch(a)

    {

        int b=20;

        case 1:

            printf("b is %d/n",b);

            break;

        default:

            printf("b is %d/n",b);

            break;

    }

    return 0;

}


参考解答:スイッチの先頭に到達不能コード:コンパイル時にプログラムが、警告があるかもしれない声明。スイッチケースの文は、直接無視変数bを初期化しますので、私たちは、いない場合実際には、Bの変数が初期化され、スイッチに思いました。したがって、プログラムメモリ、ランダムな値の出力。

7.潜在的な危険は、以下の手順がどうなるかを尋ねていますか?

#include <stdio.h>

int main()

{

    char str[80];

    printf("Enter the string:");

    scanf("%s",str);

    printf("You entered:%s/n",str);

    return 0;

}


回答:この質問は非常に簡単です。この手順での潜在的な問題は、ユーザーが国境を越えた問題の配列があるだろう、長い80文字以上を入力した場合、あなたのプログラムが有用である可能とクラッシュするということです。

8、どのような次のプログラム出力していますか?

#include <stdio.h>

int main()

{

    int i;

    i = 10;

    printf("i : %d/n",i);

    printf("sizeof(i++) is: %d/n",sizeof(i++));

    printf("i : %d/n",i);

    return 0;

}


回答:あなたは、それぞれの出力を感じた場合、10,4,11が、その後は、第三に間違った間違っている、最初のものは10問題ありません、第二は4で、問題はない、なぜならこれは、4バイトの整数と32ビットマシンです。しかし、第3の出力は、なぜそれが11ではないでしょうか?驚くべきことに、10?その理由は、機能しないSIZEOFは、iがプログラム実行の前に缶であるタイプサイズ、(コンパイル時に)完全事++を求める演算子である、ということであるため、はsizeofは、(i ++で)直接置換する4 、および実行時に、あなたは私が++この式を持っていません。

9、次のプログラムの出力値が何を?

#include <stdio.h>

#include <stdlib.h>



#define SIZEOF(arr) (sizeof(arr)/sizeof(arr[0]))

#define PrintInt(expr) printf("%s:%d/n",#expr,(expr))



int main()

{

    /* The powers of 10 */

    int pot[] = {

                    0001,

                    0010,

                    0100,

                    1000

                };



    int i;

    for(i=0;i<SIZEOF(pot);i++)

        PrintInt(pot[i]);



    return 0;

}


参考答えは:あなたがPrintIntへの質問、このマクロを持っている場合さて、あなたは「見てとることができ曖昧の言語を第四の例では」。ただし、この場合の問題は、ここではない、この場合には、出力は次のようになります。1,8,64,1000、実際には非常に簡単です、C / C ++で数0で開始するために進です。

10次​​のプログラム出力はどのようなものがありますか?(絶対ではない10)

#include 

#define PrintInt(expr) printf("%s : %dn",#expr,(expr))



int main()

{

    int y = 100;

    int *p;

    p = malloc(sizeof(int));

    *p = 10;

    y = y/*p; /*dividing y by *p */;

    PrintInt(y);

    return 0;

}


参考答え:タイトル出力は100です。なぜ?問題は、Y = Y / * Pである;上、私たちはそのY /(* p)を望んでいた、しかし、我々はスペースや括弧、コメントで/ *解釈されるY / * Pの結果となっていません開始します。だから、これは全体の悪夢が始まっています。

11次の出力は何?

#include <stdio.h>

int main()

{

    int i = 6;

    if( ((++i < 7) && ( i++/6)) || (++i <= 9))

        ;



    printf("%d/n",i);

    return 0;

}

参考答え:問題は、単に抗飾らまたはテスト接頭++ ++メイン疑問試験は、&&と||の短絡評価の問題ではありません。短絡評価:(条件1 &&条件2)のために、「条件1」は、「条件2」という表現は、無視されることは、偽である場合。(1つの||条件条件2)については、「条件1」がtrueで、「条件2」の表現は、無視された場合。だから、私はあなたがこの質問への答えが何であるかを知っていると確信しています。

12、次のCプログラムでは合法ですか?その場合、出力は何ですか?

#include <stdio.h>

int main()

{

    int a=3, b = 5;



    printf(&a["Ya!Hello! how is this? %s/n"], &b["junk/super"]);



    printf(&a["WHAT%c%c%c  %c%c  %c !/n"], 1["this"],

        2["beauty"],0["tool"],0["is"],3["sensitive"],4["CCCCCC"]);



    return 0;

}

回答
本実施例は有効で、次のように、出力は次のようになります。

こんにちは!これはどのように?スーパー
Cです!

この例では、主要な代替使用法を示しています。以下の2つの用途は同じです。

「ハロー」[2]
2 [ "こんにちは"]

あなたが知っている場合:[i]は、実際に*(A + i)は*(I +をa)は、あなたが書いた場合、私は[A]に理解するにはあまりにも難しいことではありませんので。

13次のプログラム出力を何?(前提事項:こんにちは、世界を入力してください)

#include <stdio.h>

int main()

{

    char dummy[80];

    printf("Enter a string:/n");

    scanf("%[^r]",dummy);

    printf("%s/n",dummy);

    return 0;

}

回答:この例の出力は「こんにちは、臥」、「%の[^ R]」何かが窮地に立たされているのscanfです。文字がRを超える遭遇することを意味しています。

14、あなたはそれが何であるかを知って、次のプログラムでは、「5で」操作を完了するために「ビット操作」を使用しようとしますが、このプログラムにはバグがありますか?

#include <stdio.h>

#define PrintInt(expr) printf("%s : %d/n",#expr,(expr))

int FiveTimes(int a)

{

    int t;

    t = a<<2 + a;

    return t;

}



int main()

{

    int a = 1, b = 2,c = 3;

    PrintInt(FiveTimes(a));

    PrintInt(FiveTimes(b));

    PrintInt(FiveTimes(c));

    return 0;

}


答え:本問題の問題発現FiveTimesの機能は、「tが<< 2 + =ということである 。」 このビット<< 2操作、さらによりも低い優先度に、表現は「そうなっていtは<<(2 + A = )」、 私たちは私たちが望む値を取得することはありません。次のようにプログラムが修正されます。

int FiveTimes(int a)

{

    int t;

    t = (a<<2) + a;

    return t;

}


ます。https://my.oschina.net/dake/blog/196643で再現

おすすめ

転載: blog.csdn.net/weixin_34380781/article/details/91508585