• 締切済み

外部シンボル未解決

学習のため勉強していますが test3.obj : error LNK2001: 外部シンボル ""int * g_array" (?g_array@@3PAHA)" は未解決です。 となります。リンクエラーだと解りましたが、どこに問題があるのかわかりません。 ソースは以下のとおりです。よろしくお願いします。 【stdafx.h】 #include "targetver.h" #include <tchar.h> #ifndef _TEST4_H_ #define _TEST4_H_ #include <stdio.h> #include <stdlib.h> #include <time.h> const int MAXARRAY = 30; extern int g_array[MAXARRAY]; void printArray(); #endif #include "stdafx.h" 【test3.h】 int _tmain(int argc, _TCHAR* argv[]) { //配列の初期化 srand((unsigned int)time(NULL)); for(int i = 0; i < MAXARRAY; i++) { g_array[i] = rand() % 1000; } printArray(); return 0; } 【test4.h】 #include "stdafx.h" void printArray() { for(int y = 0; y < MAXARRAY/10; y++) { for(int x = 0; x < 10; x++) { int i = y * 10 + x; printf("%3d ", g_array[i]); } printf("\n"); } }

みんなの回答

  • chie65535
  • ベストアンサー率43% (8519/19367)
回答No.3

「extern」は「どこか別のオブジェクトに居ます」と言う宣言です。なので変数は定義されません。 なのでtest3もtest4も「g_arrayはどこか別のオブジェクトに居ます」としてコンパイルされ、変数はどこにも定義されません。 従って「外部シンボル ""int * g_array" (?g_array@@3PAHA)" は未解決です」と言う事になります。 同一のヘッダで「変数の実体の定義」と「変数が外部にある宣言」を同時に行う場合は、以下のようにします。 【globalvar.h】 #ifndef _GLOBALVAR_H_ #define _GLOBALVAR_H_ #ifdef ___MAIN___ #ifdef EXTERN #undef EXTERN #endif #define EXTERN #else #define EXTERN extern #endif const int MAXARRAY = 30; EXTERN int g_array[MAXARRAY]; #endif 【test3.h】 #include "globalvar.h" #ifndef _TEST3_H_ #define _TEST3_H_ 略 #endif 【test4.h】 #include "globalvar.h" #ifndef _TEST4_H_ #define _TEST4_H_ 略 #endif 【test3.c】 #define ___MAIN___ #include "test3.h" #include "stdafx.h" int _tmain(int argc, _TCHAR* argv[]) { 以下略 【test4.c】 #undef ___MAIN___ #include "test4.h" #include "stdafx.h" void printArray() { 以下略 ここで重要なのが「メインでのみ___MAIN___が定義されている」と言うことです。 これによりtest3.cでは EXTERN int g_array[MAXARRAY]; は int g_array[MAXARRAY]; と解釈され「変数の定義」となります。また、test4.cでは EXTERN int g_array[MAXARRAY]; は extern int g_array[MAXARRAY]; と解釈され「変数の外部参照宣言」となります。

  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.2

本題とは別の話で、ヘッダーファイルには関数の実体を書かないのが一般的です。

mfurukaw
質問者

お礼

ありがとうございました。 確かにtest3.hとtest3.c、test4.hとtest4.cを間違えていました。 済みませんでした。

回答No.1

変数g_arrayを定義する必要があります。 externっていうのは「別の(オブジェクト)ファイルでもこの型でこの名前の変数(シンボル)を使います」という宣言で、定義ではありません。 リンクされるファイルのどこかで定義されている必要があります。 また、#include は他のファイルをその場所にそのまんま入れるということを行うだけなので、#include されたものは別のオブジェクトファイルではありません。 ・・・という以上が理屈です。端的に解決方法を述べれば、test3かtest4かどちらかに変数g_arrayの定義を入れてやればOKのはずです。

関連するQ&A

  • 外部シンボルが未解決

    本に載っていたソースなんですが,外部シンボル 'drand48()' が未解決(C:\NYU.OBJ が参照)というエラーが出てなかなかコンパイルできません。drand48という関数はstdlib.hに含まれていると思うのですが,何故だか分かりません。どなたか分かる方,是非ともお力をお貸しください。 環境はbcc55です。元のソースはC++Builder4で作られたそうです。字数の関係ですべて載せることができませんが,よろしくお願いします! #include <stdio.h> #include <math.h> #include <string.h> #include <locale.h> #include <stdlib.h> #define Iunits 14 #define Hunits 200 #define Ounits 2 #define Rlow -0.30 #define Rhigh 0.30 #define A 1.4 #define B 0.3 #define fout(x) ( 1 / (1 + exp( -(x) ) )) #define urand() ( drand48() * (Rhigh - Rlow) + Rlow ) ~中略 void initialize()/*各ユニットに乱数で重みを振り当てる*/ { int i,j; for (i = 0; i < Hunits; i++){ for (j = 0; j < Iunits; j++){ wih[i][j] = urand(); } shikiih[i] = urand(); } for (i = 0; i < Ounits; i++){ for (j = 0; j < Hunits; j++){ who[i][j] = urand(); } shikiio[i] = urand(); } } ~少略

  • プログラミングの課題で困ってます。

    正弦関数x=sintのグラフを■で描きなさい(31行程度で)。数値xに対する■の数はウインド各行に表示される しきれる範囲内で任意に定めてよい。 という課題が出ました。よくわからなくて困っています。 下記に書いてるプログラミングを参考に答えを教えていただきたいと思い、質問させていただきました。よろしくお願いします。 また、下記を参考にしなくてもよいです。 プログラミングはvisual C++ 2008を使ってます。 #include "stdafx.h" #include<stdio.h> #include<math.h> int _tmain(int argc, _TCHAR* argv[]) { double x[100]; int i , j; for(i=0; i<31; i++){ x[i]=sin(0.1*i); } // for(j=0; j<31; j++){ // printf("%lf\n",y[j]); // } for(i=0; i<31; i++){ for(j=0; j<x[i]*20; j++){ printf("■"); } printf("\n"); } return 0; }

  • n個の要素を持つ配列xをシェルソートで昇順に整列

    穴埋め問題ですが、for文の j -= k の考えで立ち止まります。 #include <stdio.h> #define swap(X, Y) 【 1 】 ← X ^= Y, Y ^= X, X ^= Y void shell(int x[ ], int n); void main() {     int x[12] = {23, 67, 54, 82, 13, 28, 55, 61, 50, 32, 29, 44};     int n = 12, i ;     printf("配列(整列前)x => ");     for( i = 0; i < n - 1; i++ )         printf("%d, ",x[ i ]);     printf("%d\n",x[ i ]);       shell(x, n);     printf("配列(整列後)x => ");     for( i = 0; i < n - 1; i++ )         printf("%d, ",x[ i ]);     printf("%d\n",x[ i ]); } void shell(int x[ ], int n) {     int i, j, k = n ;     while( 【 2 】 ){ ← k > 0         【 3 】 ← k /= 2;         for( i = 0; 【 4 】; i++)             for( j = i; 【 5 】; j -= k)               swap(x[j], x[j + k]);     } } 【 1 】【 2 】は自信があるのですが【 3 】はあまり自信がないです。 【 4 】と【 5 】はどうすれば出来ますか教えてください。お願いします。

  • N王妃とタイム計算の融合

    先輩方にご協力をお願いしたく書き込みさせていただきます。 #include <stdio.h> #define FREE 0 #define BUSY 1 #define N 8 int q_pos[N+1]; int colum[N+1]; int r_up[2*N]; int r_dw[2*N]; void disp(void) { int y,x; static count = 0; printf("\n解 %d\n", ++count); for(y=1;y<=N; y++){ for(x=1;x<=N; x++){ if (q_pos[y] == x)printf("○"); else printf("×"); } printf("\n"); } } void eight_queens(int y) { int x; for (x=1; x<=N; x++){ if(colum[x]==FREE && r_up[y+x-1]==FREE && r_dw[y-x+N]==FREE){ q_pos[y]=x; if (y>=N) disp(); else{ colum[x]=BUSY; r_up[y+x-1]= r_dw[y-x+N]=BUSY; eight_queens(y+1); colum[x]=FREE; r_up[y+x-1]= r_dw[y-x+N]=FREE; } } } } int main(void) { int i; for(i=1;i<=N; i++) colum[i]=FREE; for(i=1;i<2*N;i++) r_up[i]= r_dw[i]=FREE; eight_queens(1); return 0; } こちらのプログラムに #include<stdio.h> #include<stdlib.h> #include<time.h> void sleep(clock_t wait); void main(void) { int i,j,n; time_t start,finish; double duration,v; printf("繰り返し回数は>"); scanf("%d",&n); time(&start); v=1.01; for(i=0; i<n; i++) { if(((i+1)% 10)==0) { fprintf(stdout,"."); fflush(stdout); } for(j=0; j<n; j++) { v *=1.0001; } } printf("\n"); time(&finish); duration=difftime(finish,start); printf("計算にかかった時間は約%6.2f 秒です \n", duration); } のプログラムを合体させ、1つのプログラムを完成させたいのですが、どのような配列にしたらいいのか教えて欲しいです>< アルゴリズムとしては、チェスのN王妃のプログラムから解を導きだすと同時に、そのプログラムを起動してから終わりまでのタイムを計算するプログラムを挿入すると言う内容です。 プログラムは8クイーンなのですが 4から12の解を導き、違いを探すことが主な課題です; ですので、プログラムを起動して、解を導きだすまでの時間を測定するので、計算に要する時間だけで十分と思われます。。。 ようは上のプログラムに、下のプログラムをおりまぜて、1つのプログラムにし、起動したら解とタイムが同時に測定できるようにしたいです>< いまだに困っております><

  • Cの九九を表示するプログラムについて

    九九の表示を変えたいんですけど #include <stdio.h> int main(void) { int x,y; for (x = 1;x <= 9;x++) { for (y = 1;y <= 9;y++) { printf(" %2d ", x * y); } printf("\n"); } return 0; } これを実行すると 1 2 3 4 5 6 7 8 9 2 4 6 8 10 12 14 16 18 . . 9 . . . . . . . 81 となるのですが、これを 1 * 1 1 * 2 1 * 3 . . . 1 * 9 1 * 2 . . 1 * 9 . . . . . 9 * 9 と表示させたいのですがどなたか知恵を貸していただきませんでしょうか?

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

    コンパイラではちゃんと動いてます。 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)); } } }

  • RPGゲームの簡単なプログラムを打ってみたんですがうまく表示されません

    RPGゲームの簡単な初歩的なサンプルプログラムを自分で打ってみたんですが、思った通りに表示されません。 以下のソースのどこかおかしいとこありますでしょうか。 #include<stdio.h> #include<windows.h> #define MAP_SIZE_Y 10 #define MAP_SIZE_X 10 int x = 4,y = 5; int j,i; int map[100][100] = { {1,1,1,1,1,1,1}, {1,0,0,3,0,0,1}, {1,0,0,0,0,0,1}, {1,0,2,0,2,0,1}, {1,0,0,0,0,0,1}, {1,1,1,1,1,1,1}, }; void DrawMap(){ for(j = 0; i < MAP_SIZE_Y; j++){ for(i = 0; i < MAP_SIZE_X; i++){ if(j == y && i == x){ printf("勇"); }else{ switch ( map[j][i]){ case 1: printf("■"); break; case 2: printf("兵"); break; case 3: printf("王"); break; default:printf(" "); break; } } } printf("\n"); } } void main(){ while(1) { system("cls"); DrawMap(); } }

  • C言語の問題がわからないです。

    C言語のプログラムで、列数を自分で決めて、 (例)3列         ●(この行を最後として)   □● ●□● 上記のプログラムを作りたいのですが、 上手くいきません。途中まで作ったのですが、なかなか思うようにいかないです。どうすれば上記のようになりますでしょうか? #include <stdio.h> void disp(int x, int y); main() { int i,n; printf("表示する列:"); scanf("%d",&n); disp(3,3); for(i=1;i<=n;i++){ if(i%2==0){ disp(n-i,4); disp(i,2); } else{ disp(n-i,4); disp(i,1); } disp(1,3); } } void disp(int x, int y) { int i; for(i=0;i<x;i++){ if(y==1){ printf("●"); } else if(y==2){ printf("□"); } else if(y==3){ printf("\n"); } else{ printf("\0"); } } }

  • ソートの時間計算について

    ソートの時間計測について以下のようなプログラムを作成したのですが、ソートはうまく動きますが何度試しても処理時間が0.00000秒となってしまいます。どのように改良すればこのような問題を解決できるのでしょうか。ご回答よろしくお願いいたします。 #include <stdio.h> #include <time.h> #define SIZE 100 void swap(int data[], int s, int t){ int tmp = data[s]; data[s] = data[t]; data[t] = tmp; } void Bsort(int data[], int size) { int i, j; for(i=1; i<size; i++){ for(j=(size-1); j>0; j--){ if(data[j] < data[j-1]){ swap(data, j, j-1); } } } } void Ssort(int data[], int size){ int i, j, k, tmp; for(i=1; i<size; i++){ k = data[i-1]; for(j=i; j<size; j++){ if(k>data[j]){ tmp = k; k = data[j]; data[j] = tmp; } } tmp = k; k = data[i-1]; data[i-1] = tmp; } } void printArray(int ar[], int size) { int i; for (i = 0; i < size; i++) printf("%4d", ar[i]); printf("\n"); } int main(void) { int i, x; int data[SIZE]= {412, 54, 595, 329, 24, 488, 313, 272, 129, 210, 670, 516, 342, 541, 491, 640, 167, 117, 726, 206, 474, 762, 153, 292, 1000, 607, 151, 661, 93, 270, 737, 531, 641, 548, 299, 287, 547, 394, 550, 475, 443, 261, 707, 503, 403, 739, 226, 646, 778, 588, 427, 169, 477, 572, 413, 300, 88, 321, 55, 779, 542, 680, 211, 273, 288, 276, 405, 307, 424, 668, 756, 255, 190, 449, 35, 435, 91, 486, 58, 408, 4, 63, 534, 330, 701, 65, 256, 311, 586, 404, 459, 254, 291, 333, 42, 343, 418, 512, 164, 56}; clock_t t1,t2; printf("番号を入力してください。\n1,Bubble Sort\n2,Selection Sort\n"); scanf("%d", &x); switch(x){ case 1: printf("before:"); printArray(data, SIZE); t1 = clock(); Bsort(data, SIZE); t2 = clock(); printf(" after:"); printArray(data, SIZE); printf("処理時間:%f[ms]¥n", (double)(t2 - t1) / CLOCKS_PER_SEC); break; case 2: printf("before:"); printArray(data, SIZE); t1 = clock(); Ssort(data, SIZE); t2 = clock(); printf(" after:"); printArray(data, SIZE); printf("処理時間:%f[ms]¥n", (double)(t2 - t1) / CLOCKS_PER_SEC); break; } return 0; }

  • 関数の出力引数をクラスにするには?

    既出、または基礎の質問でしたらすみません。 ここでも他の検索エンジンでも見つけられなかったので。。。 C++です。 クラスを出力する関数を作りたいのですが、うまくできません。 ソースは以下のとおりです。問題は、プログラム下方のf1(),f2(),main()です。 長くて、そして見づらくてすみません・・・ //////////// #include<stdio.h> class test{ private: int num; float *vec; public: test(int n=1); //ctor ~test(); //dtor int getnum(){return num;} float* getvec(); void set(int,float*); void show(); }; test::test(int n){ num = n; vec = new float[n]; for(int i=0; i<n; i++) vec[i] = (float)i; } test::~test() {delete[] vec;} float* test::getvec(){ float *v; v = new float[num]; for(int i=0; i<num; i++) v[i] = vec[i]; return v; } void test::set(int n, float *v){ num = n; vec = new float[n]; for(int i=0; i<n; i++) vec[i] = v[i]; } void test::show(){ for(int i=0; i<num; i++) printf("%d: %g\n",i,vec[i]); } void f1(test &x, test &y){ int n; float *v; n = x.getnum(); v = x.getvec(); for(int i=0; i<n-1; i++) v[i] = 2.0*v[i]; y.set(n-1,v); } test f2(test x){ test y; //* int n; float *v; n = x.getnum(); v = x.getvec(); for(int i=0; i<n-1; i++) v[i] = 2.0*v[i]; y.set(n-1,v); return y; //** } void main(){ test x,y; int n = 4; float v[4] = {1.0,2.0,3.0,4.0}; printf("x:\n"); x.set(n,v); x.show(); printf("f1:\n"); f1(x,y); y.show(); printf("f2:\n"); y=f2(x); y.show(); } //////////// これを実行すると x: 0: 1 1: 2 2: 3 3: 4 f1: 0: 2 1: 4 2: 6 f2: 0: 7.38979e-38 1: 7.38979e-38 2: 6 となります。 関数f2がうまく動かない理由がわかりません。。。 出力引数にクラスはとれないのでしょうか?? よろしくお願いします。

専門家に質問してみよう