[解決済み] Cエラー:関数への参照は未定義ですが、定義されています。
質問
簡単なプログラムなのですが、このようなコンパイラーエラーが出続けています。コンパイラはMinGWを使用しています。
以下はヘッダーファイルです。 ポイント.h :
//type for a Cartesian point
typedef struct {
double x;
double y;
} Point;
Point create(double x, double y);
Point midpoint(Point p, Point q);
そして、こちらが point.c :
//This is the implementation of the point type
#include "point.h"
int main() {
return 0;
}
Point create(double x, double y) {
Point p;
p.x = x;
p.y = y;
return p;
}
Point midpoint(Point p, Point q) {
Point mid;
mid.x = (p.x + q.x) / 2;
mid.y = (p.y + q.y) / 2;
return mid;
}
そして、ここでコンパイラの問題が発生します。私はずっと
testpoint.c: 'create(double x, double y)' への未定義の参照。
point.cで定義されているのに...。
という別ファイルです。 testpoint.c :
#include "point.h"
#include <assert.h>
#include <stdio.h>
int main() {
double x = 1;
double y = 1;
Point p = create(x, y);
assert(p.x == 1);
return 0;
}
何が問題なのか、途方に暮れています。
解決方法は?
コンパイルとリンクはどのように行っているのでしょうか?両方のファイルを指定する必要があります、みたいな。
gcc testpoint.c point.c
...そうすれば、両方の関数を一緒にリンクすることができます。しかし、今のようなコードを書くと、逆の問題にぶつかることになります。
main
. 1つ(おそらくpoint.cにあるもの)を削除する必要があります。
大きなプログラムでは、通常、変更されていないものを再コンパイルするのを避けるために、コンパイルとリンクを別々に行います。通常、makefile で何をすべきかを指定し、その際に
make
を実行します。この場合、次のようなものになります。
OBJS=testpoint.o point.o
testpoint.exe: $(OBJS)
gcc $(OJBS)
1つ目は、オブジェクトファイルの名前をマクロ化しただけのものです。これを展開するには
$(OBJS)
. 2つ目は、1) 実行ファイルがオブジェクトファイルに依存していること、2) オブジェクトファイルと比較して古い場合/古い場合に実行ファイルをどのように作成するかをmakeに指示するためのルールです。
ほとんどのバージョンのmakeは(MinGWのものも含めて)、Cソースファイルからオブジェクトファイルを作成する方法を伝えるために、組み込みの"暗黙のルール"を持っています。これは通常、おおよそ次のようなものです。
.c.o:
$(CC) -c $(CFLAGS) $<
これは、Cコンパイラの名前がCCというマクロ(のように暗黙のうちに定義されている)にあると仮定しています。
CC=gcc
という名前のマクロで、気になるフラグを指定することができます。
CFLAGS
(例,
CFLAGS=-O3
で最適化をオンにする)と
$<
は、ソースファイル名に展開する特殊なマクロです。
という名前のファイルに保存するのが一般的です。
Makefile
を入力し、プログラムをビルドします。
make
をコマンドラインで実行します。という名前のファイルが暗黙のうちに探されます。
Makefile
そして、そのルールに含まれるすべてのルールを実行します。
これの良いところは
make
は自動的にファイルのタイムスタンプを調べるので、前回コンパイルしたときから変更されたファイルだけを再コンパイルします(つまり、".c" ファイルのタイムスタンプが、一致する ".o" ファイルよりも新しいファイルです)。
また、1) 大きなプロジェクトになると、makeの使い方にはたくさんのバリエーションがあること、2) makeの代わりとなるものもたくさんあること、に注意してください。2)makeの代替ソフトもたくさんある。
関連
-
[解決済み】"Expected expression before ' { ' token"(トークンの前に期待される式)。
-
[解決済み】「複数の定義」「最初に定義されたのはここです」エラーについて
-
[解決済み】.axfファイルとは何ですか?
-
[解決済み] メソッドと関数の違いは何ですか?
-
[解決済み] Bash関数にパラメータを渡す
-
[解決済み] 関数名を文字列として取得するには?
-
[解決済み] 未定義、未指定、および実装で定義された動作
-
[解決済み】JavaScriptの関数にデフォルトのパラメータ値を設定する
-
[解決済み】C言語の関数ポインタはどのように機能するのですか?
-
[解決済み】関数の前のエクスクラメーションマークは何をするのですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] Connect: ソケット以外でのソケット操作
-
[解決済み】式は、単純なポインタ演算を使用して完全なオブジェクト型へのポインタでなければなりません【重複】。
-
[解決済み】LEALアセンブリ命令は何をするのですか?
-
[解決済み] テスト
-
[解決済み】MB/sとMiB/sを計算する方法は?
-
[解決済み】「複数の定義」「最初に定義されたのはここです」エラーについて
-
[解決済み] C: エラー: ';'トークンの前に ')' があると予想される
-
[解決済み】Makefile:1: ***セパレータがありません。停止します。
-
[解決済み】makefile:4。*** missing separator. 停止する
-
[解決済み] C++でextern "C "を使用した場合の効果は?