• 締切済み

沢山の変数を扱う時、うまく出来ません・・。

変数が沢山ある時、エラーが起こったかどうかは どうやって判断したらいいんでしょうか。 今50個位変数名があるとします。 今は端おって5つにします。 int a,b,d; char c,e a = (int *) calloc(500,sizeof(int)); b = (int *) calloc(200,sizeof(int)); c = (char *)calloc(700,sizeof(char)); d = (int *) calloc(400,sizeof(int)); e = (char *)calloc(100,sizeof(char)); if(a==NULL || b==NULL || c==NULL || d==NULL || e==NULL)   printf("エラー発生\n"); こうやって50個もif文の中にいれたら大変ですよね。 変数名も長いですし。うまく1つでもエラーが起きたら全体がエラーになるように出来ませんかね? 自分としてはこういう風に考えたんですけど int sum=1; a = (int *) calloc(500,sizeof(int)); sum*=a; b = (int *) calloc(200,sizeof(int)); sum*=b; c = (char *)calloc(700,sizeof(char)); sum*=c; d = (int *) calloc(400,sizeof(int)); sum*=d; e = (char *)calloc(100,sizeof(char)); sum*=e; if(sum==0)   printf("エラー発生\n"); コレくらいしかないですかね?

みんなの回答

  • Trick--o--
  • ベストアンサー率20% (413/2034)
回答No.5

おっとすまん。 define作ってる意味がねーなw fpo1関係のコードとout_define.txtは忘れてくれw

  • Trick--o--
  • ベストアンサー率20% (413/2034)
回答No.4

以下のプログラムで、その辺のコードの自動生成が出来る。 エラー処理の部分は適当に変える必要があると思うが。 tVarData[]の中身を増やしたり変えたりすれば、変数名/変数型/サイズを変えられる。 #include <stdio.h> typedef struct _VarData_t { char szName[80]; char szType[80]; int nSize; } VarData_t; const VarData_t tVarData[] = { {"a","int",500}, {"b","int",200}, {"c","char",700}, {"d","int",400}, {"e","char",100}, {"END","END",-1} }; int main(void) { int i = 0,j; FILE *fpo1; FILE *fpo2; fpo1 = fopen("out_define.txt","w"); fpo2 = fopen("out_code.txt","w"); while(1){ if(tVarData[i].nSize < 0) { break; } fprintf(fpo1, "#define SIZE_%s (%d)\n", tVarData[i].szName, tVarData[i].nSize); fprintf(fpo2, "%s = (%s *)calloc(%d, sizeof(%s));\n", tVarData[i].szName, tVarData[i].szType, tVarData[i].nSize, tVarData[i].szType); fprintf(fpo2, "if(%s == NULL) {\n", tVarData[i].szName); for(j=0;j<i;j++) { fprintf(fpo2, "\tfree(%s);\n", tVarData[j].szName); } fprintf(fpo2, "\tprintf(\"変数 %s でエラーが発生しました。\");\n\treturn 0;\n}\n", tVarData[i].szName); i++; } fclose(fpo1); fclose(fpo2); return 0; } 生成されたコードの一部 ---out_define.txt--- #define SIZE_c (700) #define SIZE_d (400) --- ---out_code.txt--- c = (char *)calloc(700, sizeof(char)); if(c == NULL) { free(a); free(b); printf("変数 c でエラーが発生しました。"); return 0; } d = (int *)calloc(400, sizeof(int)); if(d == NULL) { free(a); free(b); free(c); printf("変数 d でエラーが発生しました。"); return 0; } ---

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.3

もしエラー処理をまともにやりたいのであれば、 int *a = NULL; int *b = NULL; char *c = NULL; ... if ((a = calloc(500, sizeof(int))) == NULL) goto error; if ((b = calloc(200, sizeof(int))) == NULL) goto error; if ((c = calloc(700, sizeof(chat))) == NULL) goto error; ... error: free(a); free(b); free(c); ... printf("エラー発生\n"); のように、最低限割付け済みのものを解放してやる必要があります。

  • R32C
  • ベストアンサー率39% (115/290)
回答No.2

一個づつ地道にやるほうがバグは少ないと思いますが、 コードを減らしたい時は以下のような方法もありますね。 全部callocしてからではなく、エラーになった時点でエラー処理 するべきでしょうね。(#1さんと同じ) #include<stdlib.h> #include<stdio.h> int *a,*b,*d; char *c,*e; typedef struct { void **valhdl; /* 取得するポインタ */ size_t counts; /* 取得個数 */ int len; /* 一個の長さ */ } T_callc; const T_callc t_callc[] = { {(void**)&a,500,sizeof(int)}, {(void**)&b,200,sizeof(int)}, {(void**)&c,700,sizeof(char)}, {(void**)&d,400,sizeof(int)}, {(void**)&e,100,sizeof(char)}, {0 ,0 ,0} }; int main(void) { const T_callc *p; p = t_callc; while(p->valhdl) { if ((*(p->valhdl) = calloc(p->counts,p->len)) == NULL) { printf("エラー発生\n"); break; } p++; } return 0; }

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.1

立て続けに50個も動的に割付けるのがどんな状況かよくわかりませんが... > if(a==NULL || b==NULL || c==NULL || d==NULL || e==NULL) >   printf("エラー発生\n"); エラーを検出した際、適切なエラー処理を行って、元の状態に復帰させる必要などはあるのでしょうか? そうではなく、単に異常終了させればよいのであれば、 void *calloc_and_check(size_t n, size_t size) {  void *p = calloc(n, size);  if (p == 0) abort();  return p; } といった関数を作って、 void *a = calloc_and_check(500, sizeof(int)); void *b = calloc_and_check(200, sizeof(int)); ... のようにすればよいと思います。 普通は、50個も立て続けに動的割付けしなくても済む方法を探す方がよいでしょう。

関連するQ&A

  • char型+char型ってint型? if(char型==int型)?

    C言語の「汎整数拡張(インテグラルプロモーション)」というものに関するものだと思います。 char型とchar型を加えた結果は、char型でしょうか。それともint型でしょうか。 (下のプログラムの printf("sizeof(a[0]+a[1])は%d\n", sizeof(a[0]+a[1])); /* char型+char型 */ という部分の結果は4なので、int型と考えるべきなのかな。) 私は、char型とint型の加算の結果はint型だと思っていましたが、 char型とchar型の加算の結果はやはりchar型だと思っていました。 (それが間違えているのでしょうか。) if(a[0]==i) /* char型とint型の比較(?) */ の部分では、左辺はchar型、右辺はint型ですが、このように型の違う変数を比較しても文法上構わないのでしょうか。 (私は、「比較は必ず型の同じもの同士でしかできない」と思っていました。) 左辺はchar型のように見えて、じつはint型ですか。 #include <stdio.h> int main(void) { char a[4]; int i=77; printf("sizeof(int)は%d\n", sizeof(int)); printf("sizeof(char)は%d\n", sizeof(char)); printf("sizeof('M')は%d\n", sizeof('M')); printf("sizeof(a[0])は%d\n", sizeof(a[0])); a[0]='M'; a[1]=7+6; a[2]=a[0]+a[1]; printf("sizeof(a[0]+a[1])は%d\n", sizeof(a[0]+a[1])); /* char型+char型 */ printf("sizeof(+a[0])=%d\n", sizeof(+a[0])); if(a[0]==i) /* char型とint型の比較(?) */ puts("a[0]==i"); else puts("a[0]!=i"); return(0); } ちなみにワーニングもエラーもなんにもでません。

  • 多元配列について(ANSI C)

    動的多元配列で、 Voidポインタに、多種の型がぶら下がった多元配列を作り、 読み書きをしたいのですがどのようにしたらよろしいでしょうか。 具体的には、 x[0][1]は、intで「2」が入っている x[0][4]は、intで「9」が入っている x[1][2]は、charでしかも文字列の配列で「goo」が入っている x[1][5]は、charでしかも文字列の配列で「教えて」が入っている x[0]は、int型の配列。X[1]は、文字列型の配列。 というようなものです。 一応ソースは作ってみたのですが、int型では問題なくいくのですが、 文字列は、コンパイルはできますが、実行すると予期せぬことが起きます。 #include <stdio.h> #include <stdlib.h> #include <string.h> int main (void) {      void **topPointa;      int * iDataInput;      int * iDataOutput ;      char * chDataInput;      char * chDataInput2;      char * chDataOutput1 ;      // ポインタアドレス用のメモリ確保      topPointa = (void *) calloc (10 , sizeof(void *));      if(topPointa == NULL) {           printf("メモリが確保できません\n");           exit(-1);      }      //int配列のメモリ確保      iDataInput = (int * ) calloc (10 , sizeof(int));      if(iDataInput == NULL) {           printf("メモリが確保できません\n");           exit(-1);      }      iDataInput[0] = 3 ;      iDataInput[1] = 4 ;      topPointa[0] = (void * ) &iDataInput;      //int配列の取り出し      iDataOutput = *(int *) topPointa[0];      printf( "int: %d\n", iDataOutput[0] );      printf( "int: %d\n", iDataOutput[1] );      //char配列 のメモリ確保      chDataInput = (char * ) calloc (10 , sizeof(char *));      if(chDataInput == NULL) {           printf("メモリが確保できません\n");           exit(-1);      }      chDataInput2 = (char * ) calloc (10 , sizeof(char));      if(chDataInput2 == NULL) {           printf("メモリが確保できません\n");           exit(-1);       }      strcpy(chDataInput2 , "hoe");      chDataInput[0] = &chDataInput2;      topPointa[1] = (void * ) &chDataInput;      //char配列の取り出し      chDataOutput1 = *(char *) topPointa[1];      printf( "char: %S\n", chDataOutput1[0] );      free(iDataInput);      free(chDataInput);      free(chDataInput2);      return 0; } 言語は、C言語ANCI Cでお願いします。 以上。よろしくお願いします。

  • 変数の扱える範囲

    C言語で、整数型変数の扱える範囲を確認するために 以下のような処理をしているのですが、どうもうまくいきません。 変数に入りうる最大値の値を、2進数の計算ではなく プログラム内で正しく扱われているか確認する方法はないでしょうか? ご存知の方、教えてください<(_ _)> 宜しくお願いいたします。 **********************************************  unsigned long long I; unsigned long A; unsigned int B; unsigned short C; printf("I:%d A:%d byte B:%d byte C:%d byte \n"    ,sizeof(I),sizeof(A),sizeof(B),sizeof(C)); A = B = C = 0; for(I = 0; I <= 4294967295; I++){ A++;B++;C++; if(I>= 4294967290 && I<= 4294967295)    printf("I:%d A:%d B:%d C:%d\n",I,A,B,C); }

  • 文字列を分解して特定の項目を別の変数に

    文字列を分解して特定の項目を別の変数に入れたいのですが、条件式を満たさないので別の変数に入れれません 下にソースを書くのですが age の項目だけ別の変数に入れたいのです どのようにすれば入れれますか? #include <stdio.h> #include <string.h> char *nameset[12],*valueset[12]; char *nameset3[12],*valueset3[12]; void main(void){ int c=0; int i=0,cn=0,dn=0; char *tm=NULL; char *han; char *a="name=miku&age=15&like=momo"; int b=strlen(a); nameset[0]=a; while((a[++i]!=NULL)&&(i<b)){ /* 項目の分解 */ if(a[i]=='='){ a[i]=NULL; if(c!=1){ valueset[cn]=a+i+1; cn++; } else{ valueset3[dn]=a+i+1; dn++; c=0; } } /* データ項目で分解 */ else if(a[i]=='&'){ a[i]=NULL; han=a+i+1; if(strcmp(han,"age")==0){ nameset3[dn]=han; c=1; } else{ nameset[cn]=han; } } } printf("%s\n", nameset[0]); printf("%s\n", valueset[0]); printf("%s\n", nameset[1]); printf("%s\n", valueset[1]); printf("%s\n", nameset[2]); printf("%s\n\n", valueset[2]); printf("%s\n", nameset3[0]); printf("%s\n", valueset3[0]); }

  • ポインタに ~0を入れること

    見かけたCのプログラムで、 ポインタに~0を代入するものを見ました。 そのプログラムをそのまま載せるのはわかりにくいので、 代わりに以下のプログラムを作って実行しました。 #include <stdio.h> int main(void) { char *pa[3]; int i; pa[0]=0; pa[1]=~0; pa[2]="Hello"; printf("sizeof(char*)=%d\n", sizeof(char*)); for(i=0; i<=2; i++) { if(pa[i]==NULL) printf("pa[%d] はNULLです。\n", i); if(pa[i]==(char*)0xFFFFFFFF) printf("pa[%d]は全ビット1です。\n", i); if(pa[i]==~0) printf("pa[%d]は~0です。\n", i); } return 0; } 結果 sizeof(char*)=4 pa[0] はNULLです。 pa[1]は全ビット1です。 pa[1]は~0です。 このプログラムはコンパイル時にエラーも警告も出ず、 動作も意図したとおりです。 pa[1]に入っている ~0 は、int型の定数なのでしょうか。 それならば、 pa[1]=~0; という代入や if(pa[i]==~0) という比較は 左辺はchar*型で右辺はconst int型であって型が異なりますが、 問題ないのでしょうか。 ~0は0の否定なので、全ビットは1なのでしょうけど、 int型(の定数)だと思います。 ~0というのは何か特別な値なのでしょうか。 ポインタに~0を入れるというのは、意味があるのでしょうか。 (例えば、「ポインタに0を入れるということは、ヌルポインタであって、ポインタとして無効なんですよ」のようなこと。)

  • メモリ確保エラー時の効率的な書き方

    mallocなどで複数の変数に対してメモリを確保する場合があると思います.例えば3つの変数の場合, char *a, *b, *c; a = (char *)malloc(100); if(a==NULL){ /* メモリ確保できなかったとき */ return (-1); } b = (char *)malloc(100); if(b==NULL){ free(a); return (-1); } c = (char *)malloc(100); if(c==NULL){ free(a); free(b); return (-1); } 変数が多くなるにつれて後から確保する変数のエラー処理(すでに確保したメモリのfree)が増えてしまうので,何か良い方法(コードが短くなるような)はないでしょうか?

  • ガウスのの単純消去法のプログラムです。

    ガウスのの単純消去法のプログラムです。 前進消去の第k段階が終わった段階でaij,biが表示されるようにしたいんですがどうすればいいでしょうか↓ よろしくお願いします。 #include<stdio.h> #include<stdlib.h> #include<math.h> #define ERROR -1 #define EPS 1.0e-15 int gausssimp(double *, double *, double *, int); int main(void) { double *a,*b,*x,val; char s[32]; int i,j,n,result; printf("Input size n="); gets(s); sscanf(s,"%d",&n); if((a=(double *)calloc(n*n,sizeof(double)) ) == NULL){ fprintf(stderr,"Memory allocation error\n"); exit(-1); } if((b=(double *)calloc(n,sizeof(double))) == NULL){ fprintf(stderr,"Memory allocation error\n"); exit(-1); } if((x=(double *)calloc(n,sizeof(double))) == NULL){ fprintf(stderr,"Memory allocation error\n"); exit(-1); } /* A,b の成分を入力 */ printf("----- A -----\n"); for(i=0; i<n; i++){ for(j=0; j<n; j++){ printf("a(%2d,%2d)=",i+1,j+1); gets(s); sscanf(s,"%lf",&val); a[n*i+j]=val; } } printf("\n----- b -----\n"); for(i=0; i<n; i++){ printf("b(%2d)=",i+1); gets(s); sscanf(s,"%lf",&val); b[i]=val; } /* Gaussの単純消去法による求解 */ result = gausssimp(x,a,b,n); /* 解の表示 */ if(result == ERROR){ printf("ERROR occurs. pivot 0\n"); } else { printf("\n----- solution -----\n"); for(i=0; i<n; i++){ printf("x(%2d)=%.8e\n",i+1, x[i]); } } free(a); free(b); free(x); return 0; } int gausssimp(double *x, double *a, double *b, int n) { int i,j,k; double tmp,p,sum; /* step 1: 前進消去 */ /**** 追加 ****/ /* 前進消去の各段階を終えるごとに,式がどのように変化しているかわかるように表示する */ /**************/ for(k=0; k<n-1;k++){ if(a[n*k+k] == 0.0) { /* ピボットの値が0.割り算でエラーが起きる.*/ return ERROR; } else { /* k+1番目以降の式から x[k] の項を消去 */ for(i=k+1; i<n; i++){ p=a[n*i+k]/a[n*k+k]; for(j=0; j<n; j++){ a[n*i+j]=a[n*i+j]-p*a[n*k+j]; } b[i]=b[i]-p*b[k]; printf("a[%d %d]=%d b[%d]=%d",i,j,a[n*i+j]-p*a[n*k+j],i,b[i]-p*a[n*k+j]); ↑これではできませんでした。。。 } /**********************************/ } printf("k=%d\n",k); } /* step 2: 後退代入 */ for(k=n-1; k>=0; k--){ if(fabs(a[n*k+k]) < EPS) return(ERROR); sum=0.0; for(j=k+1; j<n; j++) sum+=a[n*k+j]*x[j]; x[k]=(b[k] - sum)/a[k*n+k]; } return 0; }

  • C言語 どこがコンパイルエラーか解りません。

    いつも大変お世話になっております。 標記の件。 どこがエラーなのか解りません。 2時間くらい、にらめっこが続いています。 どこがエラーなのか教えて下さい。 ご回答のほどよろしくお願い申し上げます。 コード #include <stdio.h> int a = 0; void func(void) { int c = 2; printf("func関数では変数aとcが使えます。¥n”); printf("変数aの値は%dです。\n",a); /*printf("変数bの値は%dです。\n",b);*/ printf("変数cの値は%dです。\n",c); } int main(void) { int b = 1; printf("main関数では変数aとbが使えます。\n"); printf("変数aの値は%dです。\n", a); printf("変数bの値は%dです。\n", b); /*printf("変数cの値は%dです。\n", c); */ func(); return 0; } コンパイルエラー printf("func関数では変数aとcが使えます。¥n”); ^ text10.c:9:8: error: missing terminating " character printf("func関数では変数aとcが使えます。¥n”); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ text10.c:10:34: error: expected ')' before ';' token printf("変数aの値は%dです。\n",a); ^ text10.c:10:1: warning: passing argument 1 of 'printf' makes pointer from integer without a cast [-Wint-conversion] printf("変数aの値は%dです。\n",a); ^~~~~~ In file included from text10.c:1:0: c:\mingw\include\stdio.h:454:38: note: expected 'const char *' but argument is of type 'int' _CRTIMP __cdecl __MINGW_NOTHROW int printf (const char *, ...); ^~~~~~ text10.c:13:1: error: expected ';' before '}' token } どうかよろしくお願いいたします。

  • C言語の変数について

    C言語の変数について教えていただきたいです。 C言語で下記のような設定をした場合、変数A、Bに設定する値にはバイト数制限 はないのでしょうか? バイト数制限がなくなる場合、なぜそうなるのかを教えていただきたいです。 よろしくお願いします。 #include <stdio.h> void test( char **B); int main( int argc, char *argv[] ) { char *A = NULL; char *B = NULL; A = argv[1]; test( B ); return 0; } void test( char **B ) { strcpy(B, "ABCD"); return 0; }

  • 関数に配列を渡した場合にサイズが

    C言語初心者です。 以下のように関数に配列を渡した場合、サイズが変わってしまうのは何故でしょうか。 #include "stdafx.h" void fanc(char [3]); int _tmain(int argc, _TCHAR* argv[]) { char a[] = {'a','b','c'}; printf("%d\n",sizeof(a)); // aのサイズ 3 fanc(a); return 0; } void fanc(char b[]){ printf("%d\n",sizeof(b)); // bのサイズ 4 }

専門家に質問してみよう