外出自粛中でも楽しく過ごす!QAまとめ>>

 ルネサスHEWのサンプル・プログラムを見ると、I/Oの初期化、Bセクションのクリア、DセクションからRセクションへのコピーなどを行ってから、main関数に飛んでいます。

 これらの初期化はメイン関数の中で行うべきだと思っているのですが、どうなんでしょう。

 パソコンでexeファイルを実行した場合、mainに飛ぶと思っているのですが、初期化プログラムに飛んでからmainに飛ぶのでしょうか。

 宜しくお願いします。

このQ&Aに関連する最新のQ&A

A 回答 (9件)

回答者の中にもよく分かっていない人がいつようですが....



まず、リセットがかかったときにどのアドレスからプログラムを実行するかはCPUによって異なります.
HEWということですが、H8やSHであれば0番地にリセットベクタを格納しますので、そのアドレスから実行されることになります。M16CやM32Cであれば、アドレス空間の最後にリセットベクタを格納します。MIPSなんかは0xbfc00000番地から実行します。このように、CPUによって事情が異なります。

次に、スタートアップの話ですが、Cの規格では、プログラム開始位置が実行される時点では、静的記憶域期間を持つオブジェクトの初期化が完了していなければなりません。これはフリースタンディング環境(OSのない環境)でも同じです。ですので、スタートアップでそうした初期化を行います。
スタートアップでは、静的なオブジェクトの初期化以外に、DRAMやキャッシュの初期化など、ハードウェアの初期化も行います。スタートアップは処理系の一部ですので、そうした処理を書くのは処理系を構築する作業になります。
モニタプログラムなどが存在するシステムでは、こうした処理をモニタがやってくれることもありますが、ハードウェアが変わるたびにスタートアップを書き換える必要がありますので、誰がやるかは別として、ポーティングは組込みでは必須の作業となります。
    • good
    • 0
この回答へのお礼

 いつも回答有り難う御座います。

>Cの規格では、プログラム開始位置が実行される時点では、静的記憶域期間を持つオブジェクトの初期化が完了していなければなりません。

 そのような規格が有るのなら、納得出来ます。

 I/Oの初期化はどうでしょう。組み込みプログラムの説明によると、「ノイズによってI/0の設定が変わるおそれがある。信頼性を上げるため、定期的に再設定した方が良い。」となっています。

 I/Oの初期化は、main関数の中で行うのがスマートかなと思うのですが。

お礼日時:2009/10/27 11:47

>今までの回答から、パソコンにおいてユーザーが作るのはmein以降と思ったのですが、今回の回答ではスタートアップルーチンもユーザが作ると思うのですが。



昔は全部自分で書いてましたが(スタートアップの簡単なサンプルみたいな物は開発キットに付属してました)、HEWなど統合環境ではマイコンの種類に合わせてHEWがスタートアップを用意してくれますね。
ただ、それを無視して自分のスタートアップを書く事も可能だと思いますが書く必要があるのは疑問です。別に任せても問題ないのでは?

環境によりますが、組み込み系ならスタートアップは自分で用意する場合も多々あります。HEWやWinアプリなどの統合環境やCコンパイラなどは自動的にスタートアップを用意してくれます。
例えばH8でもHEWを使わずにgccを使うならスタートアップを用意する必要がありますね。
http://tokyo-ct.net/usr/kosaka/for_students/H8/3 …
    • good
    • 0
この回答へのお礼

 何度も回答有り難う御座います。

 いろいろと有り難う御座います。

 C言語で出来ないスタックポインタの設定などはスタートアップで行うにしても、C言語で出来る事はmain関数の中で行った方が良いんじゃないかなと思っています。

 サンプルを見ると私の考えと違うので、一般的にはどのように行われているのかと思い質問しました。

 みなさんの回答を見て、参考になりました。有り難う御座いました。

お礼日時:2009/10/27 12:06

>C言語では初期値を持たない変数をゼロクリアする約束が有りますが、それはOSが行ってくれて、プログラム開発者は意識しなくていいのでしょうか。


それは言語毎のお約束で、OSがやるべきことではありません。スタートアップルーチンの役割です。
セクションをメモリ空間に展開するのはOSの役割ですが、OSの無い組み込み環境ならスタートアップルーチンやブートローダがその役目を負う必要があります。

Windows実行ファイル「EXE」の謎に迫る
http://codezine.jp/article/corner/61
    • good
    • 0
この回答へのお礼

 再度回答有り難う御座います。

 「http://codezine.jp/article/corner/61​」は参考になりました。

 今までの回答を見て、スタートアップルーチンはOSの役目だと思いました。
 OSでないとすると、Cコンパイラが自動的に作ってくれる物なのでしょうか。初期値を持たない変数をゼロクリアするスタートアップルーチンはコンパイラが自動的に生成出来るしょうが、I/Oの初期化はユーザが作らないと無理だと思います。

 今までの回答から、パソコンにおいてユーザーが作るのはmein以降と思ったのですが、今回の回答ではスタートアップルーチンもユーザが作ると思うのですが。

お礼日時:2009/10/26 17:42

main() は、「ユーザーが書いたプログラム


のうち、一番最初に実行されるもの」です。
これ以前の処理は、その環境(OS とか)に
応じて、処理系が勝手にプログラムをくっつ
けます。
これが、スタートアップとか呼ばれるものに
なります。

例えば、Cでは、「初期値が省略されたグロー
バル変数は暗黙のうちに、0 で初期化される」
という決まりがあります。
これを実現するためには、main() より先に、
「グローバル変数をゼロで初期化する」プログ
ラムが動作しなければなりません。

そして、そのプログラムは(暗黙の初期化なので
)ユーザーが書いたものではありません。
こういうものが、main() の実行前に行われます。

Hew が main() の実行前に行っている初期化は
「RAM 領域全体を一括してゼロクリアする」と
言うレベルの初期化です。
(上で書いたような、グローバル変数の暗黙の
初期化もこのあたりで実現できる)

一方でC言語で、「実装している RAM領域全
体」を、知る方法はありません。
C言語(というか、ユーザーの書いたプログラ
ム)では、「使うつもりの変数を、適切に初期
化する」ということを行うべきです。

これが、main() の実行に先立って、暗黙のう
ちに実行される初期化と、ユーザーが書く初
期化の違いです。

さて、CPUは、リセットされると、その
CPUに決まった方法で、プログラムの実行
を開始します。
(必ずしも、ゼロ番地から実行を開始するわ
けではありません)

この位置には、スタートアップルーチンが来る
ケースが多いです。
ユーザーが書く main() は、スタートアップ
が終了した後に呼び出されるプログラムに過
ぎません。

なお、パソコンのOSでもこのあたりの事情は
同じです。
実行ファイルは、「ローダ」というプログラム
でメモリに展開されて、必要な前処理がなされ、
それが終わった後に、ユーザープログラムの
実行開始点である main() などが呼び出され
ます。
    • good
    • 0
この回答へのお礼

 早速の回答有り難う御座います。

 みなさんの回答から、main関数の前にデータ領域の初期化がC言語の規格だと分かりました。

>Hew が main() の実行前に行っている初期化は「RAM 領域全体を一括してゼロクリアする」と言うレベルの初期化です。

 HEWのサンプルプログラムは、BセクションのゼロクリアとDセクションからRセクションのコピーを行っています。

お礼日時:2009/10/26 19:18

#3です。



組込みのmain関数は、パソコンのOSと同じと例えれば分かり易いかな?
どちらも必要な手続きをしないと、いきなり実行は不可という意味で同じです。
    • good
    • 0
この回答へのお礼

 再度回答有り難う御座います。

お礼日時:2009/10/26 16:15

基本的に、Cのmain()関数の前に、スタートアップルーチンが走ります。



ルネサスHEWがなにかは、存じませんが、スタートアップルーチンで、どこまでやるかは、その言語処理系(OS)で、決まります。
    • good
    • 0
この回答へのお礼

 早速の回答有り難う御座います。

 みなさんの回答を見て、組み込みマイコンの場合スタートアップルーチンがOSに相当するらしいと分かって来ました。

お礼日時:2009/10/26 15:54

どんなCPUでも、ブート後は0番地から実行を開始するのをご存じですか?


組込みのスタートアップルーチンは、パソコンのBIOSに相当すると言えば分かりやすいかな?
パソコンだって、いきなりOSは走らない(走れない)でしょ?

>パソコンでexeファイルを実行した場合、mainに飛ぶと思っているのですが、初期化プログラムに飛んでからmainに飛ぶのでしょうか。

既に動作中のOS上で実行するアプリケーションと組込プログラムは、実行開始時点の状態が全く異なります。
比較する事自体ナンセンス。
    • good
    • 0
この回答へのお礼

 早速の回答有り難う御座います。

>どんなCPUでも、ブート後は0番地から実行を開始するのをご存じですか?

 最後のアドレスにベクタアドレスが書いて有るCPUも有ったような気がします。68000だったかな。

>組込みのスタートアップルーチンは、パソコンのBIOSに相当すると言えば分>かりやすいかな?
>パソコンだって、いきなりOSは走らない(走れない)でしょ?

 OSがBIOSを呼ぶと思っているのですが、そうでは無いのですか?

>既に動作中のOS上で実行するアプリケーションと組込プログラムは、実行開>始時点の状態が全く異なります。比較する事自体ナンセンス。

 組み込みモニタでプログラムをロードしたり実行したりします。このモニタが、パソコンのOSに相当するのでは?

お礼日時:2009/10/26 15:34

この辺の意識は「組み込み」な人とそうでない人の間には差があるかもしれない.


順番を変えますが, 「パソコンでexeファイルを実行した場合」には, 「カーネルから直接 main関数が実行される」ことはありません. なぜなら, main関数の実行の前後に「定型的にしなければならないこと」があるからです. 例えば main関数の開始直後から printf が使えるわけですが, そのためには構造体 FILE を適切に初期化する必要があります. しかし, そんなことを毎回 main に書かせる (あるいは初期化ルーチンを main から呼び出させる) よりも, 「main の前後にしなければならないこと」を行うルーチンを作り, そこから main を呼び出す形にした方が便利です. つまり, 処理系の作成者においては「どんなプログラムでも必ず実行される」ことを前提にできますし, プログラムの作成者にもそのような「プログラム本体とは直接関係ないこと」を書かなくて済むからです.
一方, 組み込み方面だとおそらく意識は違うと思います. つまり「自分の書いたことだけを実行し, 書いていないことは実行しない」のが動作として正しい, という考え方があると思います. そう考えれば「これらの初期化はメイン関数の中で行うべき」というのは正論です. これに対し, 「定型的に行うことをいちいち書くのは面倒」あるいは「書き忘れると痛いのでいや」というのももちろん 1つの考え方たり得ます. そして, そう考えれば「初期化を行ってから改めて main に飛ぶ」ということも十分な意味があります.
    • good
    • 0
この回答へのお礼

 早速の回答有り難う御座います。

 C言語では初期値を持たない変数をゼロクリアする約束が有りますが、それはOSが行ってくれて、プログラム開発者は意識しなくていいのでしょうか。

 exeファイルに何か情報が書いてあり、OSがそれを見てゼロクリアしてくれるのでしょうか。

お礼日時:2009/10/26 15:22

>これらの初期化はメイン関数の中で行うべきだと思っているのですが、どうなんでしょう。


スタートアップルーチンで初期化しなければならない物は、スタートアップルーチンで初期化すべきです。特にセクション関係はアセンブラで無いと記述できないのでは?

>パソコンでexeファイルを実行した場合、mainに飛ぶと思っているのですが、初期化プログラムに飛んでからmainに飛ぶのでしょうか。
パソコンのexeもスタートアップルーチン経由でmainに飛びます。
    • good
    • 0
この回答へのお礼

 早速の回答有り難う御座います。

>特にセクション関係はアセンブラで無いと記述できないのでは?

 普通はそうだと思いますが、HEWでは __sectop, __secend と言う演算子が用意されています。

>パソコンのexeもスタートアップルーチン経由でmainに飛びます。

 そうですか。例えば編集するテキスト名を指定してエディタを起動した場合、main(int argc, char *argv[]) のパラメータにテキスト名を入れ、エディタソフトのmainを呼ぶと思ったのですが違うのですね。

お礼日時:2009/10/26 15:04

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QC言語 配列の長さの上限

C言語で配列Array[N]の長さNの上限っていくらなんでしょうか?
もし可能なのであれば上限を2147483647にしたいのですが、方法を教えてください。

Aベストアンサー

そもそもWindowsの32bit版はアプリが仮想メモリ空間を2GBしか使えません。2GBを超えるには64bit版が必要です。
たとえ64bit版OSだとしても添え字が2147483647って、単純なintの配列だとしても4x2147483647=8GB必要ですね。実メモリ16GBとかのPCを用意しますか?
そもそも配列で2147483647個必要なアルゴリズムに問題ありだと思います。

Q#if 1 #elseの意味について

#if 1
 文 
#else 
 文
#endif
という表記に関して、「#if 1」が「必ず有効」という事はわかるのですが、ここでの「#else」とは「1」でない時ということで、「#if 0」と同じ意味と考えていいのでしょうか?

Aベストアンサー

>「#if 0」と同じ意味
「#if~#endif」がすこーぷの範囲ですから、似ていますが、正確には違います。

「#if 1」であれば、「#if 1~#else」の間の処理が有効、「#else~#endif」が無効、
「#if 0」であれば、「#else~#endif」の間の処理が有効、「#if 0~#else」が無効
と排他になります。

Q組み込みマイコンでのソフトウェアによるリセット

組み込み用マイコン向けのファームウェアをC言語で
書いています.
ここで, ソフトウェア側からマイコンにリセットをかけ
るにはどのような方法があるでしょうか?
※マイコン自体には内部的なハードウェアリセットを行
う機能は無いものとします.

素人考えで思いつく限りだと:
・リセットを行う場所の関数からmainまですべて戻る
経路を作っておく.
main (または, mainを呼び出すスタートアップルーチ
ンの部分)をループにしておき, その始めで内蔵周辺
機能のレジスタやstatic領域のメモリをすべて初期化
するようなコードを
ひたすらハードコーディングしておく.
(※static領域のメモリ初期化はどのみち行うからよ
いとして, 内蔵周辺機能のレジスタをひたすら初期化
するのが面倒に思われます)

・ウォッチドッグタイマ機能があれば, わざとカウン
タをオーバーフローさせてハードウェアリセットをか
ける.

・外部リセット端子に何らかの形で出力ポートを
接続しておいて, 自分でハードウェアリセットをかける.


上記のものでもやればそれなりに動作しそうな気は
しますが, どういう方法が一般的なのか知らないため
どうしてよいか悩んでいます.

どのようにリセットを行うのがスマートであるか
ご教示いただけませんでしょうか?

組み込み用マイコン向けのファームウェアをC言語で
書いています.
ここで, ソフトウェア側からマイコンにリセットをかけ
るにはどのような方法があるでしょうか?
※マイコン自体には内部的なハードウェアリセットを行
う機能は無いものとします.

素人考えで思いつく限りだと:
・リセットを行う場所の関数からmainまですべて戻る
経路を作っておく.
main (または, mainを呼び出すスタートアップルーチ
ンの部分)をループにしておき, その始めで内蔵周辺
機能のレジスタやstatic領域のメモリをすべて...続きを読む

Aベストアンサー

確実さの順で行くと、
1、外部ポートからワンショット回路を経由してリセット端子へ
2、ウォッチドッグタイマで自滅

ソフト的にリセットベクタへ飛ぶのは、周辺デバイス(マイコン内臓も外部も)が初期化されませんから、初期化ルーチンがパワーオンリセット状態であることを前提に書かれていれば、予期せぬ状況を招きます。
マイコン外部に周辺デバイスを接続している場合は、2の方法も同様に危険です。

ちなみに、出力ポートをリセットピンに直結すると不完全なリセットになり、やはり予期せぬ事態になり得ます。

私は余計な回路を載せるのがいやなので、可能な限り2を、それがダメなら1の方法を使用しています。

QExcelで16進数の計算

セルA1にFFFF、セルA2にもFFFFが格納されているとします。
A1とA2の和をA3に16進数表記で格納することは可能でしょうか?

一度10進数に直さなければならないのかと思い、分析ツールのアドインを有効にし、A1の数式を【=HEX2DEC(FFFF)】と入力してみたのですがセルには#NAME?と表示されてしまいます。

エクセルの経験があまりないので、自分なりに調べてやってみましたがこの有様です。解決策をご存知の方がおられましたら、ご伝授をよろしくお願いします。

Aベストアンサー

あ、ごめんなさい。
式が間違っていました。

誤)=DEX2HEX(HEX2DEC(A1)+HEX2DEC(A2))

正)=DEC2HEX(HEX2DEC(A1)+HEX2DEC(A2))

でした。

# A1やA2はセルを指定する式なのでダブルクォートで
# くくる必要はないですよ。

QH8 マイコン セクションの設定について

最近H8/3694Fを使ってマイコンの勉強をしております。
HEWを使ってコンパイルするときのセクションの設定に
ついて質問があります。

プログラム・セクションの設定を一通り終え、ビルドすると
「L2321 (E) section "S" overlaps sction "P"」
とエラーメッセージが出てしまいました。

色々調べてみるとSはスタック領域、Pはプログラム領域
でこれに重なりができてしまっているようなのですが、
これ以上どうしてよいのかわからず困っています。

おそらくセクション設定を変更すればよいと思っていますが
プログラム領域にどれくらい、スタック領域にどれくらい
を配置すればいいというのはどうやって求めればよいのでしょう?
HEWのメモリマップを表示させて見る方法があるようですが
見てもいまいちわかりませんでした。

使用環境:OS:WindowsXP、HEW4.04.01.001

以上、追記補足いたします。詳しい方教えていただけないでしょうか

Aベストアンサー

実際のリンク結果のアドレスマップは、「Standard Toolchain」の最適化リンカのオプションを変更すれば出力できるはずです。
「リンクマップファイル」がキーワードでマニュアル等を探してみてください。うまく行けば、[プログラム名].mapの名前で作成されるはずです。

>「L2321 (E) section "S" overlaps sction "P"」
RAMで実行する設定にしたなら、このエラーも納得です。
プログラムが本当に大きすぎるんだと思います。
>0X0000FE80 S
となっていますので、設定を変えていないと0x100サイズのスタックが取られるらしいので、0xFD80-0xFE80はスタックになります。
プログラムの部分のPセクションが、0xFD80を超えてしまっていると思いますよ。

Q「#undef」と「#define」の使い方について

代記のとおりですが、

#undef HENSU
#define HENSU 16MAX

という定義をした場合は、#undefで一旦定義を無効にして、
#defineで再定義されるという認識でよろしいでしょうか?

ご存知の方教えてくださいお願いします。

Aベストアンサー

よろしいです。

#ifdef HENSU
#undef HENSU
#endif
#define HENSU ...

の方がより安全かも。

Qメモリのセクションに関して

こんばんは。
表題の通り、セクション領域に関して3点ほどご質問が御座います。

(1)グローバル変数は、
 ・0でない初期化を行う→.dataセクション
 ・0で初期化、または、初期化なし→.bssセクション
 上記のようにメモリに配置されると思いますが、
 上記をstatic宣言した場合でも結果は同じでしょうか?
 (static宣言したグローバル変数)

(2)スタック、ヒープそれぞれが属するセクションは、それぞれ専用の
 スタックセクション、ヒープセクションという名のセクションがあるという認識であっていますでしょうか?
 (.dataでもなく、.bssでもなく、.textでもなく、.rodataでもなく。。。)

(3)プログラム中に宣言した変数名や、そのアドレスを使用して、属しているセクションを確認することが出来る方法はありますでしょうか?

どうかご教授をお願い致します。

Aベストアンサー

> (1)グローバル変数は、
> 上記をstatic宣言した場合でも結果は同じでしょうか?
> (static宣言したグローバル変数)

静的グローバル変数はシンボルの公開が抑止されるのみでその他に違いはない場合が多いかと。


> (2)スタック、ヒープそれぞれが属するセクションは、それぞれ専用の
> スタックセクション、ヒープセクションという名のセクションがあるという認識であっていますでしょうか?

ありません。


> (3)プログラム中に宣言した変数名や、そのアドレスを使用して、属しているセクションを確認することが出来る方法はありますでしょうか?

通常、各アドレスはまとまっている(例えば1000-2999はtextで3000-3999はbss,4000-5999はdataの様に)のでアドレスを調べれば解ります。
実行ファイルの形式上情報がありますので実行ファイルを解析すれば各セクションの位置や大きさはわかります。(詳しく知りたい場合にはunix系のsizeコマンドのソースを参照するのも良いかと)
elf形式やaout形式にマニュアルページやヘッダなども知る上で良い資料となりそうに思います。
※javaやC++には固有のセクションが追加されている場合があったり。


> (3)プログラム中に宣言した変数名や、そのアドレスを使用して、属しているセクションを確認することが出来る方法はありますでしょうか?

通常、アドレスを調べれば解ります。

予約された領域を除き残った領域を下位アドレスからヒープとして、上位アドレスからスタックとして動的割り当てしたりするのではないかな。

> (1)グローバル変数は、
> 上記をstatic宣言した場合でも結果は同じでしょうか?
> (static宣言したグローバル変数)

静的グローバル変数はシンボルの公開が抑止されるのみでその他に違いはない場合が多いかと。


> (2)スタック、ヒープそれぞれが属するセクションは、それぞれ専用の
> スタックセクション、ヒープセクションという名のセクションがあるという認識であっていますでしょうか?

ありません。


> (3)プログラム中に宣言した変数名や、そのアドレスを使用して、属しているセクションを確認す...続きを読む

QRS232C 調歩同期のビットレート誤差について

RS232C 調歩同期のビットレート誤差は何%程度まで許容できるのでしょうか?
また、目安とその理由について教えて下さい。

SH4のプログラムを組んでいます。
例えば、パソコンとRS232C(調歩同期)通信を行う際のビットレートの設定で、SH4側のビットレート誤差は何%以内にするべきでしょうか?
クロック同期の場合は、「なるべく1%以内になるように」とマニュアルに記載があるのですが。。。

Aベストアンサー

まずは
データ長8ビット
パリティなし
ストップビット1

だとすると、シリアルデータは全部で10ビットです。

スタートビットから同期し、各ビットの中央でデータをサンプリングするなら、10番目のビットが50%以上ずれるとアウトです。つまり5%誤差ですね。

しかし世の中そううまくいきません。コントロールICによって違いますが、ビットレートの8倍や16倍で各データをサンプリングします。1ビットを8回や16回チェックしてるんですね。

ビットがHかLかを判断するのもいろいろですが、中央部数回分(8回サンプルなら3~4回程度)を多数決原理で判断するのが多いようです。とすると、せいぜい2.5%となります。

これに、クロック源の誤差も加味すると2%くらいが限度です。



CPUクロックからビットレートを生成する場合、ビットレートにあわせた変な周波数のクロック源でなければ0%なんて無理ですよね。実際は1%以内なら気にしませんし、大丈夫ですよ。

QC言語のポインタに直接アドレスを割り振りしたい

C言語のポインタに直接アドレスを割り振りしたいのですが、どうしたら良いのでしょうか?

Aベストアンサー

直接アドレスを割り振りたい、というのは
int* pnValue;
pnValue = (int*)0x12345678
ということでしょうか?このようにすればポインタにアドレスを代入することはできるかと思います。

Q複数ファイルで使うグローバル変数の位置

メイン関数の処理で、関数A→関数B→関数Cという順序で関数が呼び出される場合(1関数1ファイルとします)、関数A,B,Cすべてで使用するグローバル変数の宣言を関数Bのファイルでおこなって、他のファイルではそれをexternするというのでも問題ないでしょうか?

Aベストアンサー

問題ありません。
が、しかし、そのような方法は、実務レベルの場合は、行いません。
以下のような方法をとります。

ファイル名:xxx_ext.c
変数のみを宣言したファイル。

ファイル名:xxx_ext.h
上記の変数のみを宣言したしものをexternで参照するファイル。

ファイル名:func_a.c
関数Aのファイル。
このファイルで、#include xxx_ext.h する

ファイル名:func_b.c
関数Bのファイル。
このファイルで、#include xxx_ext.h する

ファイル名:func_c.c
関数Cのファイル。
このファイルで、#include xxx_ext.h する

上記のようにすることで、externで参照する変数が1つのファイル内に閉じこめられるのでメンテナンス性がよくなります。たとえば、ある理由があって、変数Xの型をintからdoubleに変えることを想定してください。
xxx_ext.c とxxx_ext.hの2つのファイルのみが変更対象
となります。
上記のようにしない場合は、3つのファイル(あるいはそれ以上)を変えることになります。

問題ありません。
が、しかし、そのような方法は、実務レベルの場合は、行いません。
以下のような方法をとります。

ファイル名:xxx_ext.c
変数のみを宣言したファイル。

ファイル名:xxx_ext.h
上記の変数のみを宣言したしものをexternで参照するファイル。

ファイル名:func_a.c
関数Aのファイル。
このファイルで、#include xxx_ext.h する

ファイル名:func_b.c
関数Bのファイル。
このファイルで、#include xxx_ext.h する

ファイル名:func_c.c
関数Cのファイル。
このファイル...続きを読む


人気Q&Aランキング