2011-08-01 10 views
0

私はCコードをいくつか持っていますが、何が起こっているのかよく分かりません。このコードで何が起こっているのかわからない

#include <stdio.h> 
#include <stdlib.h> 
#define DIM1 7 
#define DIM2 5 
#define RES_SIZE 1000 

typedef double stackElementT; 

typedef struct { 
    stackElementT *contents; 
    int maxSize; 
    int top; 
    int min2; 
} stackT; 

void StackInit(stackT *stackP, int maxSize) { 
    stackElementT *newContents; 
    newContents = (stackElementT *)malloc(sizeof(stackElementT)*maxSize); 
    if (newContents == NULL) { 
     fprintf(stderr, "Not enough memory.\n"); 
     exit(1); 
    } 

    stackP->contents = newContents; 
    stackP->maxSize = maxSize; 
    stackP->top = -1; 
} 

void StackDestroy(stackT *stackP) { 
    free(stackP->contents); 
    stackP->contents = NULL; 
    stackP->maxSize = 0; 
    stackP->top = -1; 
} 

int StackIsEmpty(stackT *stackP) { return stackP->top < 0; } 

int StackIsFull(stackT *stackP) { return stackP->top >= stackP->maxSize-1; } 

void StackPush(stackT *stackP, stackElementT element) { 
    if(StackIsFull(stackP)) { 
     fprintf(stderr, "Can't push element: stack is full.\n"); 
     exit(1); 
    } 
    stackP->contents[++stackP->top] = element; 
} 

stackElementT StackPop(stackT *stackP) { 
    if(StackIsEmpty(stackP)) { 
     fprintf(stderr, "Can't pop element: stack is empty.\n"); 
     exit(1); 
    } 
    return stackP->contents[stackP->top--]; 
} 
int shell(char* s1, int arg) { 
    printf("> "); 
    scanf("%s %d%*c", &s1, &arg); 
    return arg; 
} 

int main() { 
    char cmds[DIM1][DIM2] = {{"push"}, {"pop"}, {"add"}, {"ifeq"}, {"jump"}, {"print"}, {"dup"}}; 
    char* s1; int arg; 
    arg = shell(s1, arg); 
    printf("%s\n", &s1); 
} 

入力:push 4。 「プッシュ」ではなくJ+を印刷しますが、通常は4を出力します。

また、コンパイルにこれらの警告を与える:

stack.c: In function ‘shell’: 
stack.c:60: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘char **’ 
stack.c: In function ‘main’: 
stack.c:71: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘char **’ 
stack.c:65: warning: unused variable ‘cmds’ 
stack.c:69: warning: ‘arg’ is used uninitialized in this function 

誰かが説明していただけますか?

+0

いいえ、上に小さなスタック実装がありますが、誰もそれを見たくないと思いました。 – tekknolagi

+1

ありがとう、それに取り組んで... –

+0

このコードには意図がありますか、実行時にロジックフローが何であるかを尋ねていますか?私はmain()で呼び出されているスタックコードから何も表示されないので、スキャンして印刷するだけです。 – donnyton

答えて

3

%s書式指定子を使用する場合は、文字列の先頭を指すポインタの値が必要です。 Cでは、このタイプはchar *です。

mainの場合、変数s1のタイプはchar *です。したがって、s1printfに有効なパラメータであるので、このラインが有効である:

printf("%s\n", s1); 

s1の前に&不在に留意されたいです。あなたのコードでは、s1のアドレスを持つ&を使用しました。その結果はchar **となります。これはのタイプが正しくないタイプなので、ではありません。&を使用してください。

実際には、printfは可変引数の関数なので、引数がどの型かを実際には判別できません。書式文字列で指定された型に従って、引数があればそれを使用します。

同じことはscanfですが、落とし穴があります:ユーザー入力のために十分なメモリが割り当てられていることを確認する必要があります。そうしないと、予想外の結果でバッファオーバーフローが発生します。これとは別に、printfscanfは完全に相補的です。

Anyhooは、未使用のcmds変数(提供されたコードでは不要です)を除いて、コンパイラの警告を処理します。また、argsの部分があります。実際には、shellの内部で宣言され、その値がshellの内部でさえ使われていないので、パラメータとして渡されません。

残りのコードの内容はわかりません。あなたのmain関数がshellでのみ呼び出すと考えると余計です。

+0

このヒントをありがとうございます。しかし、アンパサンド( '&')を削除すると、実行時に同じ入力でセグメンテーションが発生します。 – tekknolagi

+2

私が言及したように、 'char *'バッファ*自分自身を割り当てる必要があります。 's1'を' char * s1 =(char *)malloc(50); 'のように宣言してください。これにより、50文字分の入力が可能になります。あるいは、配列 'char s1 [50];'を使用するだけです。いずれにしても、入力が必要なときはいつでも、入力が格納される適切なバッファがあることを確認する必要があります。 –

+1

これは、テキストを格納するために予約されたメモリを指すポインタを初期化していないためです実際にあなたはそのような記憶を予約していません。 –

関連する問題