0

この質問を見て、関数の途中で変数を宣言するとエラーが発生することに気付きましたが、main()変数を動的に作成してもエラーは発生しないと思いました。これは、実行時にいつでもどこでも実行できるためです。 (私の知る限りでは)。

しかし、私はまだ得る:

error C2065: 'i' : undeclared identifier
error C2065: 'z' : undeclared identifier
error C2065: 'intArr' : undeclared identifier

私のコード:

int main()
{
  ..... 
  .....
  ..... 

  printf("Type the array size:\t");
  int *z = (int *)malloc(sizeof(int));
  scanf("%d", z);
  int *intArr = (int *)malloc((*z) * sizeof(int));

  int *i = (int *)malloc(sizeof(int));

  for (*i = 0; *i < *z; ((*i)++))
  {
      printf("Type a number\t");
      scanf("%d", (intArr+(*i)));
  }

  printArr(intArr);
}

void printArr(int *arr)
{
    int i; 
    for (i = 0; i < (sizeof(arr) / sizeof(*arr)); ++i)
        printf("%d ", *(arr+i));
}
4

1 に答える 1

1

(@Blood が彼の回答を削除した理由はわかりません。本質的には正しかったのです。)

gcc を使用してプログラムをコンパイルすると、エラーなしでコンパイルされます。追加しなければなりませんでした

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

.....上に移動し、3行を削除します。

Microsoft の Visual C++ 2010 Express を使用して同じプログラムをコンパイルすると、多数のエラーが発生します。それらのいくつかは、宣言されていない識別子について不満を言っていますが、それは構文エラーの一般的な副作用です。コンパイラがソース ファイルを解析できない場合、回復しようとするときに「混乱」する可能性があります。最も関連性の高いエラーは次のとおりです。

syntax error : missing ';' before 'type'

10行目:

printf("Type the array size:\t");     // line 9
int *z = (int *)malloc(sizeof(int));  // line 10

問題は、C 標準の 1989/1990 バージョンでは、ブロック内で宣言とステートメントを混在させることが許可されていないことです。すべての宣言が最初に表示され、その後にすべてのステートメントが続く必要があります。1999 年の C 標準ではそれが変更されましたが、Microsoft の C コンパイラは 1990 年以降の C 標準のサポートを非常に制限しています (そして、それを変更する意図はないと述べています)。(これは C++ の機能でもあるため、将来のバージョンでは宣言とステートメントの混合が許可される可能性があると思います。)

(エラー メッセージの形式から、Microsoft コンパイラを使用していると推測します。)

Microsoft コンパイラの制限を満たすようにコードを再配置できます。場合によっては、次のように変更する必要があるかもしれません

int *var = initial_value;

int *var;
// ...
var = initial_value;

あなたの質問に関係のない別の提案:

C では、 の結果をキャストしないでくださいmalloc()。このmalloc()関数は type の値を返します。これは、オブジェクトへの任意のポインタ型に暗黙的void*に変換できます。(C++ にはこの暗黙的な変換はありませんが、とにかく C++ で使用するべきではありません。)malloc()

これではなく:

int *z = (int *)malloc(sizeof(int));
...
int *intArr = (int *)malloc((*z) * sizeof(int));

あなたはこれを書くことができます:

int *z = malloc(sizeof *z);
...
int *intArr = malloc(*z * sizeof *intArr);

不要なキャストを削除すると、特定のエラーを回避できます。たとえば、一部のコンパイラでは、 required を忘れた場合、キャストによって必要なエラー メッセージがマスクされる場合があります#include <stdlib.h>。またはに適用sizeofすると、サイズを明示的に指定するのではなく、ポインターの型が変更された場合に呼び出しを変更する必要がなくなります。たとえば、次のように記述します。*z*intArr

double *p = malloc(sizeof (int)); // incorrect

間違ったサイズを割り当てていますが、コンパイラはそれについて警告しません。

また、 を使用して単一のint値を割り当てている場合は、およびポインターでmalloc()行っているように、不要な作業を行っています。の使用を練習することが目的でない限り、変数を作成して、呼び出しをドロップすることもできます。アドレスをに渡すだけです。つまり、次のように変更できます。izmalloc()iz intmalloc()scanf

int *z = (int *)malloc(sizeof(int));
...
scanf("%d", z);

これに:

int z;
...
scanf("%d", &z);

もう 1 点: あなたのプログラムにはエラー チェックがありません。malloc()割り当てるのに十分なメモリがない場合、失敗する可能性があります。これが発生すると、null ポインター ( NULL) が返されます。入力エラーscanf()がある場合、または. スキャンに成功したアイテムの数を返します。そのようになったことを確認する必要があります (この場合、成功すると 1 が返されます)。このような単純なプログラムの場合、エラー メッセージを表示してプログラムを中止します。hellointscanf()

fprintf(stderr, "Call to ... failed\n");
exit(EXIT_FAILURE);

おそらく十分です。

于 2012-09-30T22:16:39.657 に答える