• ベストアンサー

define で 配列

#defineで配列を定義したいのですがこのようなことは可能でしょうか? ヘッダファイル(test.h)で #define MAX (2) int A[MAX]={20,30}; ソースファイルで #include <stdio.h> #include "test.h" int main(){ int i; for(i=0;i<MAX;i++){ printf("A[%d]=%d\n",i,A[i]); } return 0; } とやれば出来るのですが、このヘッダファイルを複数のソースで参照すると 多重定義であるとおこられてしまいます。 #defineで #define A[MAX] {20,30} のように配列を定義する方法は存在するのでしょうか? どなたか良い方法を御存じの方、ご教授お願いします。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.4

#define でではなく、共通して使う配列(なり変数)をただひとつのヘッダファイルで定義する方法でしょうか。 既に回答がありますが、同じ実体を持つ変数を複数の箇所(同じヘッダファイルを include する複数の箇所である場合も)で宣言する場合、 ・実体を宣言する部分には単純な宣言が ・それ以外の部分には(実体が他にあるということを明示するために) extern が必要です。 これを解決するテクニックのひとつに以下のようなものがあります。 test.h 内で #if defined(_GLOBAL_HERE) #defien GLOBAL #define DEF(x) = x #else #defien GLOBAL extern #define DEF(x) #endif #define MAX 2 GLOBAL int A[MAX] DEF({2, 3}); メインのソースファイル内で ソースファイルで #include <stdio.h> #define _GLOBAL_HERE #include "test.h" int main(){ int i; for(i=0;i<MAX;i++){ printf("A[%d]=%d\n",i,A[i]); } return 0; } それ以外のソースファイル内で (メインのソースファイル内以外の場所では、_GLOBAL_HERE を定義しない) #include <stdio.h> #include "test.h" int foo(){ .... こんな感じです。

runjump
質問者

お礼

ていねいに有難うございます。 extern でなく GLOBALで定義する方法もあるのですね べんきょうになります。

その他の回答 (3)

  • te20
  • ベストアンサー率35% (14/40)
回答No.3

#defineは単なる文字列の置き換えなので、これを使って配列の定義はできません。また、includeは単にファイルを展開するだけなので、test.hを読み込んだそれぞれのファイルで同じ名前のA[]を定義するので、多重定義になります。 で、やりたいことは次のどちらでしょうか? 1.A[]という配列をプログラム全体で一つ宣言して、それぞれのファイルの関数からアクセスしたい(配列Aはプログラム全体で1つ)。この場合は、 /* test.h */ #define MAX (2) extern int A[]; /* main.c */ #include <stdio.h> #include "test.h" int A [MAX]; 2. test.hをインクルードしたそれぞれのファイルごとに配列Aを宣言したい(配列Aはファイルごとに別々) /* test.h */ #define MAX (2) static int A[MAX]; でいかがでしょうか。

runjump
質問者

お礼

ご回答ありがとうございます。 やりたいのは1でした。 まだextern static 等の使いわけが理解できていなかったようです。 これを期にべんきょうしなおします。 有難うございました。

  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.2

#defineで定義してどのように使うのでしょう? まさか #define MAX (2) #define A[MAX] { 20,30 } とどこかで定義して int foo() {   int nSum = 0;   // ここでコンパイルエラー ・・・ 変数名の未定義   // または nSumが期待した期待ではない物になる ... 50以外   nSum = A[0] + A[1];   return nSum; } といった使い方なんてしませんよね ・・・ #defineは プリプロセス段階で置換されてしまいますよ

runjump
質問者

お礼

有難うございます。 ご指摘の通り最初これで失敗しました。 #define の限界に気づきました。 C++ではdefineを使わない方がいいとされてるらしいですが、ここら辺のことも関係して来ているのでしょうか?

回答No.1
runjump
質問者

お礼

ありがとうございます。 よくみかけていたのですが何となくやりすごしていました。 このようにつかうのですね。勉強になりました

関連するQ&A

  • できているとは、思うのですが。ポインタの配列を

    コンパイラではちゃんと動いてます。 1 2 3 0 1 2 3 という具合です。 気になるのは、printarrayの部分が正しいのか、ちょっと悩んでいます 問題としては main関数では0の値を読み込むまで最大99(MAX-1)個の値を配列 xに読み込んでいる。引数のポインタからの値を、値が0になるまで すべて1行に1つづつ画面に出力する関数printarray()を作成し、 プログラムを完成せよ。 引数はアドレスとして受け取る事。(配列としてでなく) フォーマットは、 "%d¥n" とする。(余計な出力はしない事。) (0は出力しない。) main内部を変更してはならない。 以下がソースです。 ご指摘よろしくお願いします。 #include <stdio.h> #define MAX 5 void printarray(int *); int main() { int x[MAX], i; int *p; x[MAX-1] = 0; for (i = 0, p = x; i < MAX-1; ++i, ++p) { scanf("%d", p); if (*p == 0) { break; } } printarray(x); return 0; } void printarray(int *a) { int i,*p; for(i = 0, p = a; i < MAX-1; ++i,++p) { if(*p == 0){ // continue; break; }else{ printf("%d\n", *(a+i)); } } }

  • 関数に配列を渡すときの質問です

    関数に配列を渡したいんですがこのソースが問題ないか見てください。 #include<stdio.h> #define N 10 #define M 20 int sig(int X[],int x); main() { int a[N],b[M],i,x,y; for(i=0 ; i<N ; i++){ a[i]=i; } for(i=0 ; i<M ; i++){ b[i]=i; } x=sig(a,N); y=sig(b,M); } int sig(int Z[],int x){ int i,k; k=0; for(i=0 ; i<x ; i++){ k=k+Z[i]; } return k; } ソースは以上です。 1つのソースの中でa[N]とb[M]のように違う数の 配列があるんですが、その配列全部(0~N-1、0~M-1)とかを足してくれる(シグマ)関数を作りたいんですが、Z[]と配列の数を指定しなくてもちゃんと動いてくれるんでしょうか?関数のほうの int x で配列の数を指定するようにしています。 自分でテストした限りではちゃんと動いているようなんですが、間違ってるようなら指摘お願いします。

  • C言語の配列について

    配列を20 定義し値を入力して合計値を出したいのですがどうすればよいのでしょうか 下のソースでエラーはおこりませんでした 何がちがうのでしょうか #include <stdio.h> int main() { int a[20]={}; int i, sum; printf("整数を入力してください:"); scanf("%d",&a); printf("\n"); for (i = 0; i < 10; i++) { sum += a[i]; } printf("sum= %d\n", sum); return 0; }

  • C言語でヘッダファイルを自作する

    C言語で#defineを用いてヘッダファイルを作成したのですが、 作成したコンパイルするときにヘッダファイルがオープンできません。 参考にしている資料があるのですが、そこに書かれているサンプルプログラムを 丸ごとコピーして作ったプログラムも同様にヘッダファイルがオープンできない というエラーが出るので、ヘッダファイルを定義する方法そのものが間違っていると 思うのですが、どこが間違っているのでしょうか? よろしければ正しい記述方法もお教えください。 #include <stdio.h> #if !defined SAMPLE_H #define SAMPLE_H wa(int a, int b) { return a+b; } #endif #include "sample.h" int main(){ printf("%d\n",wa(40,70)); return 0; } ヘッダファイルの定義の方法は他にもあるとは思いますが、 今回は#defineを用いた方法でお願いします。

  • テキストファイルの内容を2次元配列に格納したい

    課題で用意されたテキストファイルを読み込み、空白を区切りとする文字列の単位で配列に格納したいのですが、やりかたがわかりません。 ソースプログラムですが #include<stdio.h> #include<string.h> #include<ctype.h> #define MAX 1000 int TextSplit(char *fname, char (*SpStr)[50]); int main(void) { int i, n; char fname[MAX], SpStr[MAX][50]; int Split; FILE *fp; printf("input File =>"); scanf("%s", fname); Split = TextSplit(fname, SpStr); printf("\n %d[文字列数] \n", Split); return 0; } int TextSplit(char *fname, char (*SpStr)[50]) { int i, j, k; char Readstr[MAX]; FILE *fp; fp = fopen(fname, "r"); if(fp == NULL) { printf("ファイルオープン失敗"); return 1; } i = 0; while(fscanf(fp, "%s", SpStr) != EOF) { i++; } fclose(fp); return i; } 以上のソースプログラムですが、内容は「空白で区切る文字列の単位の総数を表示する」ものになっています。 今日の20時までに終わらせないといけないので、ご教授お願いします。 使ってるソフトはMicrosoft Visual Studioです。

  • ヘッダーの多重定義での疑問です。

     Cで開発をしているのですが、ヘッダーファイルでの定義ではたとえば、int a と か double hoge とか定義して、そのヘッダーファイルを複数の cファイルが読み込むと多重定義になりますよね? hoge.h int a; // 多重定義 このヘッダーを複数の.cファイルに読み込む しかし、自分のプロジェクトだと、ヘッダーファイルにint aとかdouble hogeとか 定義してもエラーにならないんです。 ただし、int b = 10;のように代入すると多重エラー また、試しに新しくプロジェクトを作ってヘッダーで定義すると多重定義でエラーでした。

  • 2次元配列への標準入力

    初めまして。 私は今C言語のプログラミングを勉強しています。 2次元配列へ文字列の標準入力を行い、それをプリントさせるという問題を考えています。(配列の行の要素はMAXに達しなくても空行が入力されたら 終了させたい。) 下のようなプログラムを書きましたが、空行を入力してプリントする際に 文字が崩れてしまって上手く表示されませんでした。 初歩的で恐縮ですが、どのように改善したら良いか、 教えて頂けたら嬉しいです。 #include <stdio.h> #include <ctype.h> #define MAX 10 int main(){ char array[MAX][MAX]; int i; for(i = 0; i < 10; i++){ fgets(array[i],sizeof(char)*MAX,stdin); if(array[i][0] == '\n') break; } for(i = 0; i < 10; i++){ printf("%s", array[i]); } return 0; }

  • C言語のヘッダファイルの使い方

    ヘッダファイルの使い方について質問です。 ソースファイルA、ソースファイルBで共有して使用したい変数がある場合、 Aでは「int a」と宣言し、Bでは「extern int a」と宣言すれば 同じ変数を共有出来ると認識しています。 それをヘッダファイルへ記述しておきたい場合にはどのように 宣言しておけば良いのでしょうか? ヘッダファイルに「int a」と宣言した場合は両方のソースファイルで includeした時に多重定義でエラーとなります。 では「extern int a」と宣言しておいて、両方のソースファイルで includeするのが正しいのでしょうか? 初歩的な質問で申し訳ないですが、有識者の方、教えてください。

  • 分割コンパイルの#defineについて

    分割コンパイルで ファイル1 #include <stdio.h> #define number 10 char string[number]; int main(void){ string[0]='a'; string[1]='b'; file_to(); return 0; } ファイル2 #include <stdio.h> #define number 10 extern char string[number]; void file_to(void){ /***何かの処理をする*****/ } って感じなんですけども、配列string の中身の値をdefineによって指定しているのですが、片方のdefineの値を変更する時、もう一つのdefineも手動で変更しています。関係するファイル数が多くなってくると大変なので、どれかのdefineの値を変化させたら自動的に他のdefineの値も変更するプログラムの組み方はありませんか? 質問がわかりにくいかも知れませんがよろしくお願いします。

  • #defineで定義されている変数を展開する方法について。

    ・#defineで定義されている「a」が展開された形でソースを生成したいのですが、なにか良い方法はないでしょうか? 【変換前プログラム】 #include <stdio.h> #define a tbl.nest.m1 /* メンバの名称変更 */ int main(int argc,char *argv[]) { /* テーブル定義 */ struct tbl_ { int k1; struct nest_ { int m1; }nest; }tbl; tbl.k1 = 0; a = 1; fprintf(stderr,"k1[%d] m1[%d]\n",tbl.k1,a); return(0); } 【変換後プログラム】 #include <stdio.h> //#define a tbl.nest.m1 /* メンバの名称変更 */ int main(int argc,char *argv[]) { /* テーブル定義 */ struct tbl_ { int k1; struct nest_ { int m1; }nest; }tbl; tbl.k1 = 0; // a = 1; tbl.nest.m1 = 1; // fprintf(stderr,"k1[%d] m1[%d]\n",tbl.k1,a); fprintf(stderr,"k1[%d] m1[%d]\n",tbl.k1,tbl.nest.m1); return(0); } ※プリプロセッサで(cl.exe /E *.c)試してはみたものの、いまいち理解できません。

専門家に質問してみよう