4

次の行には問題がありint (*f)(int, int) = (argv[2][0] == 'd')ます。コンパイルすると、ここでは宣言が許可されていませんと表示されます。行を最初に宣言する必要がありますが、これを行うより良い方法はありますか?

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

int encode(int ch, int key) { 
        if (islower(ch)) {
                ch = (ch-'a' + key) % 26 + 'a';
                ch += (ch < 'a') ? 26 : 0;
        }
        else if (isupper(ch)) {
                ch = (ch-'A' + key) % 26 + 'A';
                ch += (ch < 'A') ? 26 : 0;
        }
        return ch;
}

int decode(int ch, int key) { 
        return encode(ch, -key);
}

int main(int argc, char **argv) { 
        int ch;
        int key;

        if (argc < 2) {
                printf("USAGE: cipher <integer key> <encode | decode>\n");
                printf("Then, just type your text and it will automatically output the en/de crypted text! :)\n");
                return 1;
        }

        key = atoi(argv[1]);
        if (key < 1 || key > 25) {
                printf("Key is invalid, or out of range. Valid keys are integers 1 through 25.\n");
                return 1;
        }

        int (*f)(int, int) = (argv[2][0] == 'd') ? 
                decode : 
                encode;

        while (EOF != (ch=getchar()))
                putchar(f(ch, key));

        return 0;
}
4

4 に答える 4

13

C (C99 より前) では、ブロックの先頭で変数を宣言する必要があります。

コードを C99 としてコンパイルするかf、ブロックの開始時に宣言されるようにコードを変更します。

于 2012-11-28T17:36:02.577 に答える
2

行を最初に宣言する必要があります

C89では、定義はブロック内のステートメントの前に発生する必要があります。移動する場合は、行全体を移動する必要はありません(もちろん、チェックするコードargv[2]が有効になる前に行全体を移動する必要はありません)。の定義を移動するだけですf

    int ch;
    int key;
    int (*f)(int,int);

    ...

    f = (argv[2][0] == 'd') ? decode : encode;

これを行うためのより良い方法

この場合は必ずしも良いとは限りませんが、ルールはブロックの開始であり、必ずしも関数の開始ではないことに注意してください。

だから、あなたはただ書くことができます:

{
    int (*f)(int, int) = (argv[2][0] == 'd') ? 
            decode : 
            encode;

    while (EOF != (ch=getchar()))
            putchar(f(ch, key));
}
return 0;

このコーディングスタイルについては、簡単に議論することができます。一部の人々は、すべての関数がそのすべての変数を前もって定義する必要があり、変数を定義するためだけにブロックを導入することは雑然としているか、混乱していると考えています。一部の人々(特にC ++とCを使用する人々)は、各変数のスコープを可能な限り狭いコードに制限する必要があると考えています。関数の開始時にすべてを定義すると、混乱したり混乱したりします。しかし、彼らでさえ、裸のブロックを過剰と見なすかもしれません。

于 2012-11-28T17:53:23.963 に答える
2

c89/90 では、ブロックの先頭ですべての変数を宣言する必要があります

-std=c99しかし、c99 では、次のようにコードをコンパイルできます。

gcc -Wall -std=c99 test.c -o test.out

于 2012-11-28T17:38:21.550 に答える
2

NPE で指摘された部分以外にtypedef、関数タイプを作成するために使用できます。このような:

typedef void FunctionType (int, int);そして、それを(別の型として)使用して関数ポインタを作成します。

読みやすくします。

于 2012-11-28T17:38:28.903 に答える