掲示板ランキング  チャイルドシート(自転車用)  チャイルドシート(アクセサリー)


掲示板利用宣言

 次のフォームをすべてチェックしてからご利用ください。

 私は

 題名と投稿者名は具体的に書きます。
 課題の丸投げはしません。
 ソースの添付は「HTML変換ツール」で字下げします。
 返信の引用は最小限にします。
 環境(OSとコンパイラ)や症状は具体的に詳しく書きます。
 返信の付いた投稿は削除しません。
 マルチポスト(多重投稿)はしません。

掲示板1

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    記事検索    ログ    タグ一覧

No.6973

2次元配列ポインタのextern宣言について
投稿者---薫風(2006/12/25 22:00:34)


こんばんは。表題の件で以下質問させてください。
(OSはMac OS 10.4.8 PPC / コンパイラはgcc-4.0.0です)

作成したじゃんけんプログラムを分割コンパイルしたところ、
リンク時はエラーが出なかったのですが、出来上がった実行ファイル
の実行途中で"Bus Error"もしくは"Segmentation Error"を起こします。

途中までの実行結果から、2次元配列のポインタを参照するところ
でエラーを出しているようです。そこでお聞きしたいのですが、
「char *ken[] = {"グー", "チョキ", "パー"};」
というグローバル変数を、別の.cファイルから参照する場合、
「extern char *ken[];」
という書き方ではまずいのでしょうか?

「extern char *ken;」
「extern char *ken[] = {"グー", "チョキ", "パー"};」
「extern char ken[];」
「extern char ken;」
と4つほど試したのですが、結果は変わりませんでした。
間違っている場所が違う可能性もありますが、上記のポイント
についてアドバイス頂ければ幸いです。
*ちなみに分割前の実行ファイルが正常に最後まで動くことは
確認できています


この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:2次元配列ポインタのextern宣言について 6974 2006/12/25 22:25:12


No.6974

Re:2次元配列ポインタのextern宣言について
投稿者--- (2006/12/25 22:25:12)


>作成したじゃんけんプログラムを分割コンパイルしたところ、
>リンク時はエラーが出なかったのですが、出来上がった実行ファイル
>の実行途中で"Bus Error"もしくは"Segmentation Error"を起こします。

コード全体の量がそれほど多くなければ、分割してあるファイルごとに
アップロードしてみるのが手かもしれません。



この投稿にコメントする

削除パスワード

No.6975

Re:2次元配列ポインタのextern宣言について
投稿者---薫風(2006/12/26 02:51:50)


返信ありがとございます。
以下が分割毎のファイルです。(.hファイル×1と.cファイル×4)


/* jyanken.h */
int user(void);
int computer(void);
void judge( int u, int c );

/* jyanken.c */
#include <stdio.h>
#include "jyanken.h"

char *ken[] = {"グー", "チョキ", "パー"}; /* 配列のグローバル変数 */

int main(void)
{
    int u, c;
    int i;
    
    printf("3回勝負だ?n");
    for ( i = 0; i < 3; i++ ) {
        u = user();
        c = computer();
        judge( u, c );
    }
    
    return 0;


/* user.c(ユーザのじゃんけんを入力する) */
#include <stdio.h>
#include "jyanken.h"

extern char *ken[]; /* 配列のexternal宣言 */

int user(void)
{
    int u;
    
    do {
        printf("じゃん、けん、ぽん!(1: グー  2: チョキ  3: パー) > ");
        scanf("%d", &u);
    } while( u < 1 || u > 3 );
    u--;
    printf("あなたは%s?n", ken[u]);
    return u;
}


/* computer.c(コンピュータのじゃんけんを決定する */
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "jyanken.h"

extern char *ken[]; /* 配列のexternal宣言 */

int computer(void)
{
    int c;
    
    srand( (unsigned)time(NULL) );
    c = rand() % 3;
    printf("コンピュータは%s?n", ken[c]);
    return c;
}


/* judge.c(勝敗を決定する) */
#include <stdio.h>
#include "jyanken.h"

void judge( int u, int c )
{
    char *hantei[] = {"あいこです。", "あなたの負けです。", "あなたの勝ちです。"};
    int table[3][3] = {0, 2, 1, 1, 0, 2, 2, 1, 0};
    
    if ( u >= 0 && u <= 2 && c >= 0 && c <= 2)
            printf("%s?n", hantei[table[u][c]]);
}


グローバル変数とextern宣言がただの配列「char ken[3][8]」であればエラー
を起こさないのですが、上記のようにポインタにすると正常に処理が進みません。
(ちなみに改行が"?n"になっていますが、実際のソースは正しく書けています)


この投稿にコメントする

削除パスワード

No.6976

Re:2次元配列ポインタのextern宣言について
投稿者--- (2006/12/26 10:10:41)


>グローバル変数とextern宣言がただの配列「char ken[3][8]」であればエラー
>を起こさないのですが、上記のようにポインタにすると正常に処理が進みません。

アップロードされたソースを、当方の環境
(Windows2000、Borland C++ Compiler)で
何も手を加えずにコンパイルした結果、
問題なく実行できました。

ポインタの配列の要素数を明記してみる
(char *ken[3], extern char *ken[3])
と、どうなるでしょうか?


この投稿にコメントする

削除パスワード

No.6977

Re:2次元配列ポインタのextern宣言について
投稿者---薫風(2006/12/26 11:39:05)


早速の返信ありがとうございます。

昨日と同じことをしているつもりなのですが、今日はULしたソースで
リンク→実行→終了と正常に処理できました。
ポインタの部分を何度も何度も変更していたので、どこかで記述ミスがあった
のかもしれません。

原因がはっきりせず後味がわるいですが、
「char *ken[3], extern char *ken[3](3は省略可)という形で
問題なく動くことが確認できたので安心しました。
原因に気がついたら、再度返信させていただきます。

取り急ぎ、お礼まで。どうもありがとうございました。


この投稿にコメントする

削除パスワード

No.6978

Re:2次元配列ポインタのextern宣言について
投稿者--- (2006/12/26 12:23:20)


>「char *ken[3], extern char *ken[3](3は省略可)という形で
>問題なく動くことが確認できたので安心しました。

お知らせくださってありがとうございます。



この投稿にコメントする

削除パスワード

No.6979

Re:2次元配列ポインタのextern宣言について
投稿者---wis(2006/12/26 16:54:49)


judge関数内の勝敗テーブル
int table[3][3];
の初期化は、
int table[3][3] = {
    { 0, 2, 1 },
    { 1, 0, 2 },
    { 2, 1, 0 }
};

のほうがいいのかな?(一応2次元配列なので)
#こういう初期化って処理系に依存するところが
#あるのでしょうか。。。


この投稿にコメントする

削除パスワード

No.6981

Re:2次元配列ポインタのextern宣言について
投稿者---RiSK(2006/12/26 21:33:35)


int table[3][3] = {
    { 0, 2, 1 },
    { 1, 0, 2 },
    { 2, 1, 0 }
};
のほうがいいのかな?(一応2次元配列なので)
人によります。見た目が変わるだけです。

>#こういう初期化って処理系に依存するところが
>#あるのでしょうか。。。

初期化や初期化子については規格できっちり規定されています。
# JIS X3010:2003 6.7.8 初期化 を参照。
しかし,規格に準拠できなかったり,しなかったりする処理系は
作れます。(存在するかどうかは知りません。)


この投稿にコメントする

削除パスワード

No.6982

Re:2次元配列ポインタのextern宣言について
投稿者---wis(2006/12/27 09:38:23)


># JIS X3010:2003 6.7.8 初期化 を参照。
情報ありがとうございます。
同じ結果を得ると確かに明記されていました。



この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    記事検索    ログ    タグ一覧





掲示板提供:(有)リアル・インテグリティ