プロが教える店舗&オフィスのセキュリティ対策術

ポインタの配列でエラーが出てしまいます。

私は今PICというマイコン(ロボットコンテストなどで用いられるロボットの頭脳となるもの)のプログラミングをしています。ポインタの配列を使って液晶表示器に文字列を表示させるプログラムを作っているのですが、エラーが出てしまいます。
このようなプログラムです。

・・・・
static const char *r_max[7] ={"err","750","7500","75k","750k","9.2M","20M"};
・・・・・
Lcd_Custom_Out(1,1,err_ms[1]);
・・・・

ただし、Lcd_Custom_outはあらかじめ用意されている関数で、定義は次のようになっています。

void Lcd_Custom_Out(char row, char col, char *text);

LCDとは2行16文字からなる液晶表示器で、rowで表示する行、colで左から何番目に表示するかを指定します。

そして、これが含まれたソースコードをコンパイルすると、Lcd_Custom_Outの行で、
illegal pointer conversion [?T53] to [text]
というエラーが返されてしまいます。
[?T53]という部分が理解できないのですが・・・

私はC言語はそこまで得意ではないので、何がいけないのか非常に困っています。
使用したコンパイラ「mikroC 8.2」で、ANSIに準拠しております。

大変困っております。どなたかご教授お願いいたします。

A 回答 (7件)

err_msがr_max書き間違えという前提で...


使ったことのないコンパイラですが、恐らく#5の方の回答の通りだと思います。

そこで、
static const char *r_max[7] = ...

static char * const r_max[7] = ...
に変えては如何でしょうか?
ポインタは静的領域に配置されて更新可能になってしまいますが、
各文字列自体はROM上に配置され、Lcd_Custom_Outの呼び出しもエラーにならないと思います。
(コンパイラとリンカの仕様次第ですが、恐らく)
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます!私にはそこをそう変えてなぜポインタが静的領域に配置されるのか分かりませんが、試してみます。アドバイスありがとうございます。

お礼日時:2010/05/11 19:33

>static const char *r_max[7] ={"err","750","7500","75k","750k","9.2M","20M"};


ここを、
static char r_max[7][5] ={"err","750","7500","75k","750k","9.2M","20M"};
とすれば、おそらくエラーは出なくなると思います。

ただ、問題はvoid Lcd_Custom_Out(char row, char col, char *text)の仕様ですね。
textが示す内容を書き換えるのか、書き換えないのか、書き換えるとすればどんな条件で書き換えるのか、といったことを確認する必要があるでしょう。

それらが確認できないのなら、
>static const char *r_max[7] ={"err","750","7500","75k","750k","9.2M","20M"};
ここはこのままで、
>Lcd_Custom_Out(1,1,r_max[1]);
ここを、
char buf[5];
strcpy(buf,r_max[1]);
Lcd_Custom_Out(1,1,buf);
などとする必要があると思います。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。定義がそうなっていますがtextが書き換えられるということは無いと思います・・・なんでこんな仕様なのか私には分かりません。おっしゃるとおりバッファを使ってやってみようとおもいます。

お礼日時:2010/05/11 19:36

 文字列配列 r_maxの型が const char * なのに、関数の引数の型が char * なのでエラーになってるようですね。

constの有無もコンパイラによって解釈が違うので、VC++だとwarningが出るだけですが、このコンパイラではエラーになってるのでしょう。(マイコンソフト等でstatic宣言されたconst変数がROM領域に割り当てられたりする場合は、このエラーチェックは特に重要です)

 この場合、関数の中でポインタの先が書き換えられるのかどうかが問題となります。書き換えられないのなら関数宣言で引数の型をconst char *としておいてくれたほうが親切です。
 書き換えられることが無いのなら(char *)でキャストすれば済む話ですが、書き換えられるなら書き換えられても良い領域に文字列をコピーして渡す必要があります。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。constを完全に見落としていました。解決しました!ありがとうございます。
マイコンだとこの判定は重要なんですね。初めて知りました。
試してみましたが呼び出しているLcd_Outという関数によって渡したポインタが書き換えられるということはないみたいです・・・
キャストして使うことにします。本当にありがとうございました!

お礼日時:2010/05/11 18:55

>#3さん


>どう見てもポインタではないので

なぜですか?
例えば、char *err_ms[] = { "error", "messege" };
という風に「ポインターの配列」を定義したとき、
err_ms[1]は当該配列の要素であって、"message"なる
文字列リテラルへの「ポインター」ですよね。

err_ms[1]という表記「だけ」をもって、
それがどう見てもポインターではない、などと
いえるはずがありません。
    • good
    • 0

No2の方の回答通り、関数の定義での型 char *と、


関数コール時に渡してる引数 err_ms[1]の型とが不一致なんでしょう。
で、ポインタの型変換ができなくてillegal pointer conversionになる、と。

err_ms[1]の宣言がないので型が不明ですが、どう見てもポインタではないので
そのせいだと思います。

渡したいのはエラーメッセージの文字列を格納した配列の先頭アドレスですよね?
であるならば *err_ms[1]ではないでしょうか。

(個人的には、文字列の配列はchar [][]型で宣言・定義しないと
 格納実体が文字列だとわかりにくいと感じます。
 別に間違いとかではなく個人の好き好きなので、どうでもいい話ですが。)

ポインタをこねくり回す必要のあるCはやっかいですね。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。私の書き間違いでした。ごめんなさい;;
Cはポインタが鬼門ですが使いこなせるようになるとスマートにプログラムを作れますね。

お礼日時:2010/05/11 18:51

> Lcd_Custom_Out(1,1,err_ms[1]);



ここで使っているerr_msの型が違っているからエラーになっているのでは?
渡しているのはr_maxではないですよね…。

この回答への補足

ああっごめんなさい!err_msではなくr_maxです!
行を書き間違えました(汗

補足日時:2010/05/05 17:21
    • good
    • 0
この回答へのお礼

間違えて大変失礼致しました。

お礼日時:2010/05/05 17:24

>static const char *r_max[7] ={"err","750","7500","75k","750k","9.2M","20M"};


>Lcd_Custom_Out(1,1,err_ms[1]);

この2行の関係がわかりません。
r_max[]は定義したけれど使っている気配がなく、
err_ms[]は使っているけれど定義した気配がありませんね。

この回答への補足

err_ms は r_maxの移し間違えでした(汗

補足日時:2010/05/05 17:25
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます
ごめんなさい、大変失礼しました。行の移し間違えでした。err_maxはr_maxの間違いです。
それでエラーが出るんです。

お礼日時:2010/05/05 17:24

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