• ベストアンサー

配列とポインタの使い方

ROM領域にあるたくさんのデータの一部をRAMにコピーしたいのですが、うまくいきません。 どこがおかしいのか教えていただけないでしょうか? (例:int型の10個のデータとchar型の5個のデータをRAMへコピーする) // ROM領域に置いたテーブル const int int_table1[10]={1,2,3,4,5,6,7,8,9,0}; const char chr_table1[5]={1,2,3,4,5}; const int int_table2[10]={11,22,33,44,55,66,77,88,99,100}; const char chr_table2[5]={11,22,33,44,55}; // RAM領域 int int_data[10]; char chr_data[5]; // プロトタイプ宣言 void copy_data(int *int_p,char *chr_p); //メイン処理 | copy_data(int_table1,chr_table1); // テーブル1をRAMへコピー | | copy_data(int_table2,chr_table2); // テーブル2をRAMへコピー | // ROMデータをRAMに転送する関数 void copy_data(*int_p,*chr_p) { char i; for (i=0;i<10;i++) { int_data[i]=int_p; int_p++; } for (i=0;i<5;i++) { chr_data[i]=chr_p; chr_p++; } } コンパイルすると [Warning(ccom)] assignment from const pointer to non-const pointer ===> copy_data(int_table1,chr_table1); // テーブル1をRAMへコピー [Error(ccom)] mismatch prototyped parameter type ===> copy_data(int_table1,chr_table1); // テーブル1をRAMへコピー のワーニング&エラーになります。 どのようにしたらワーニング、エラーを直せますか? または「こうすればできる」という回答でもOKです。 よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

まず、すでに回答のある部分のほか、ポインタの使い方がおかしいです。 chr_data[i]=chr_p; は、おそらく、正しい動作をしないでしょう。 書くなら、 char_data[i] = *char_p; です。 というより、関数の引数として配列は使えるので、配列の形で処理するのも手なのですが。 void copy_data(const int int_src[], const char chr_src[]) { char i; for (i=0;i<10;i++) { int_data[i]=int_src[i]; chr_data[i]=chr_src[i]; } こういうの。

otaking
質問者

お礼

ありがとうございます。 申し訳ないです、AsanoNagiさんのやり方に変えてみたところ、ワーニングの方だけになっていました。(エラーは出なくなっています) ワーニングが沢山出てるのでエラーが無くなってるのに気付かなかったです。ごめんなさい。 みなさんにご迷惑をおかけして申し訳なかったです。 とりあえずワーニングは出ますが、実行ファイルは出来上がっているようなのでこれで動くと思います。 ありがとうございました。

otaking
質問者

補足

回答ありがとうございます。 配列の形に変更してみましたが、やはり関数の 呼び出し側 に質問文と同じエラーが出ます。 何が原因なんでしょうか・・・。

その他の回答 (4)

  • yama5140
  • ベストアンサー率54% (136/250)
回答No.5

No.4 です。 >まぎらわしい書き方してすいません。  いえ、こちらこそ。  あの部分を指摘すれば、お気づきになるのでは、と・・。  (年寄りは思い込みが強くて・・、申し訳ない) >どのようにしたらワーニング、エラーを直せますか?  ・No.4 で「←◆コンパイラが目をまわしそう」とした箇所を   「プロトタイプ宣言」と同じにする。  ・冒頭の const を全て取る(グローバル)。  ・No.2 さんが指摘した    int_data[i] = int_p; → = *int_p;    chr_data[i] = chr_p; → = *chr_p; この3点を直すと、少なくとも私の環境では「警告・エラー」は、   (Borland C++ 5.5.1) ★一つも出ません。 ☆質問者様が「したい」ことに、実行結果がなるかは別として。

otaking
質問者

お礼

ご回答、ありがとうございます。 constを外すとROM領域にデータが展開されないので外せません。 でも#2さんのやり方(ポインタを使わず、配列で渡す)でエラーは出なくなりましたので、これでやってみます。 ワーニングが気になりますが・・・。 ありがとうございました。

  • yama5140
  • ベストアンサー率54% (136/250)
回答No.4

>はい、同じように書いてます。 ★えっ、違いますよ。 ------------------------------------ ★ご質問文中程の関数の実体↓ void copy_data(*int_p,*chr_p) ←◆コンパイラが目をまわしそう void copy_data(int *int_p,char *chr_p) ★プロトタイプ宣言↑

otaking
質問者

補足

ありがとうございます。 >同じように書いてます。 というのは自分の質問文のことではなく、 「前の回答の方々のご指摘があった通りに訂正している」 という意味です。 まぎらわしい書き方してすいません。

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

> 配列の形に変更してみましたが > void copy_data(const int int_src[], const char chr_src[]) 関数の実体もプロトタイプ宣言も同じように書いていますね?

otaking
質問者

お礼

アドバイス、ありがとうございました。 この訂正でエラーは出なくなっていたようです。 ワーニングだけ出てますが。

otaking
質問者

補足

ありがとうございます。 はい、同じように書いてます。

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

> // ROMデータをRAMに転送する関数 > void copy_data(*int_p,*chr_p) void copy_data(int *int_p, char *chr_p) という風に、何型へのポインタであるかを明記してみると、 どうなりますか?

otaking
質問者

お礼

アドバイス、ありがとうございました。

otaking
質問者

補足

回答ありがとうございます。 型を入れても同じ結果でした。 関数側ではなく呼び出し側にエラーが出てるのでどうしたものか・・・。 今は関数を使わずにそこに直接転送する処理を入れてますが、マイコンなのでROMが少ないんです。 for(i=0;i<10;i++)int_data[i]=int_table1[i]; for(i=0;i<5;i++)cha_data[i]=chr_table1[i]; 毎回転送するところにコレを入れてます。 ROM削減のためにも何とか関数にしたいと思っています。

関連するQ&A

  • ポインタ配列

    "one","two","three","four","five","six","seven","eight","nine","ten" のポインタ配列の文字列を、ASCIIコード順に並べ変えようと思ったのですが、 もうどこが間違っているかさえわからないぐらいになってしまいました。 まだまだはじめたばかりなもので、わからないことだらけなんで、 できるだけわかりやすい説明おねがいします。 関数の引数に問題があるのじゃないかと思ったのですが、 何かいいアドバイスありましたら、お願いします。 #include <stdio.h> /* 関数のプロトタイプ宣言 */ int strmp(char *,char *); void cpy(char *,char *); int main (void) { /* ポインタ配列の定義 */ char *x[10]={"oneee","twooo","three","fourr","fivee","sixxx","seven","eight","ninee","tennn"}; /* ポインタのポインタの定義 */ char **pp=x; char k[100]; char *p=k; int i,t,a,b,c,d; a=0; /* ポインタ配列を自作関数を使って、ASCIIコードの大きいほうからに並び替える */ for(i=0;i<9;i++) { for(t=1;t<10;t++) { a=strmp(*(pp+i),*(pp+t)); if(a<0) { cpy(p,*(pp+i) ); cpy(*(pp+i),*(pp+t) ); cpy(*(pp+t),p); } } } for(i=0;i<10;i++) { printf("%s ,",x[i]); } printf("\n"); return 0; } /* 文字の比較をする関数 */ int strmp(char *x,char *y) { int i; for(i=0;*(x+i)==*(y+i);i++) { if( *(x+i)=='\0') { return 0; } } return *(x+i)-*(y+i); } /* 文字をコピーする関数 */ void cpy(char *a,char *b) { int i; for(i=0;*(b+i)!='\0';i++) { *(a+i)=*(b+i); } *(a+i)='\0'; }

  • ポインタ

    質問なのですが、このソースのchar *str_copy(char *d, const char *s)関数内のchar *p=d;はなんで、*pにdを入れるか分かりません。それと、このdは、*dなのですか?どうして、while (*d++ = *s++) みたいに*dをつけないんですか?教えてください。宜しくお願いします。 #include <stdio.h> char *str_copy(char *d, const char *s) { char *p=d; while (*d++ = *s++) ; return (p); } int main(void) { char tmp[100]; char st1[100], st2[100],st3[100]; printf("文字列を入力してください:"); scanf("%s",tmp); str_copy(st1,str_copy(st2,tmp)); printf("文字列st1は%sです。\n", st1); printf("文字列st2は%sです。\n", st2); printf("文字列st3は%sです。\n", str_copy(st3,tmp)); return (0); }

  • ポインタ

    String String Mid(int start, int length) const { char *p="HelloWorld"; char s[100]; p+=start; for(int i=0;i<length;i++) { *s++=*p+;; } return s3; で++には左辺値が必要ですとでます。 stringクラスのMid関数を実装しているのですが start分ポインタを進めてlength取り出す関数なんですが ここまでは組んだのですが、うまくいきません。 どうすればうまくいきますか?

  • ポインタとポインタのポインタの違い

    #include<iostream> #include<cstdlib> using namespace std; long myclass(const char *start,char **end,int base=10); int main(){ long d; char *p; char ss[]="231231"; d=myclass(ss,&p,16); cout<<d; d=myclass(ss,&p); cout<<d; return 0; } long myclass(const char *start,char **end,int base){ return strtol(start,end,base); } これはあるサンプルプログラムです。 これを自分が少しいじって char *pをchar**pにして&pをpにしました。 すると初期化されていないローカル変数pが使用されますと出て、警告がでました。 自分ではどちらのソースも初期化されていないと思うのですが、実際サンプルプログラムをコンパイルすると警告はでません。 何故なのでしょうか? コンパイラはvisual studio2008です。 よろしくお願いします。

  • 配列の配列?

    80字より長い行を全て印字するというプログラムを作ろうと思います。 それで今現在下記の状態なんですが #include <stdio.h> #define MAXLINE 1000 int getline(char line[], int maxline); void copy(char s1[], char s2[]); int main(int argc, char* argv[]) { int len; int max; char line[MAXLINE]; char longest[MAXLINE]; max = 0; while((len = getline(line, MAXLINE))> 0){ if(len > 80){ max = len; copy(longest, line); } } if(max > 0){ printf("%s", longest); } return 0; } int getline(char s[], int lim) { int c, i; for(i = 0; i < lim -1 && (c = getchar()) != EOF && c != '\n'; ++i){ s[i] = c; } if(c == '\n'){ s[i] = c; ++i; } s[i] = '\0'; return i; } void copy(char s1[], char s2[]) { int i; i=0; while((s1[i] = s2[i]) != '\0'){ ++i; } } この状態だと80字以上の行を1行しか表示しません。 おそらくは配列の配列を使って保存しておくのだとは考えたのですが 使い方がわかりません。教えて下さい。

  • ポインタについて

    下記<コード1>ではエラーが出ないのに、 <コード2>のように変更すると、 ”error C2105: '++' には左辺値が必要です。” とエラーが出ます。 どうしてなのか教えて下さい。 <コード1> char *str_copy(char *d , const char *s){ char *t=s2; while(*d++=*s++) ; return (t); } int main(void) { char s1[128]="ABCD"; char s2[128]="EFGH"; str_copy(s2,s1); <コード2> int main(void) { char s1[128]="ABCD"; char s2[128]="EFGH"; // str_copy(s2,s1); while(*s2++=*s1++) ;

  • C言語 ポインタと配列

    #include <stdio.h> /* scanf("%c", &search); ではなく scanf(" %c", &search); であることに注意する */ char *str_chr(const char *str, char c) { char *find; find = NULL; do { if(*str == c) { find = (char*)str; break; } } while(*str++); return(find); } int main(void) { char str[100] = {0}; char search; char *find; printf("文字列を入力してください:"); scanf("%s", str); printf("検索する文字を入力してください:"); scanf(" %c", &search); find = str_chr(str, search); if(find == NULL) { puts("検索した文字は見つかりませんでした。"); } else { printf("検索した文字 %c は\"%p\"にあります。\n", *find , find); } return(0); } このコードのfind = (char*)str;の (char*)str;の部分がどうなっているのかわかりません。 あとこのfindというのは&find[0]という解釈でいいでしょうか? 教えてくださいm(_ _ )m

  • 組み込みソフト。ROM領域にデータ

    C でデータに const 属性をつけて、初期値を設定して定義すると、初期値は ROMにテーブルが作られますがデータ自体は RAM領域に配置されます。 RAMの節約のため、ROM領域にデータを配置する方法はないのでしょうか。

  • ポインタと配列

    次のソースで、結果表示でポインタを使いたいのですが、うまくいきません。1件しか表示されないのです。 ポインタの扱いがおかしいのだと思いますが、どうしたらよいでしょうか? #include <stdio.h> #include <string.h> int search(char key[256],FILE *fp,char *result[256][256]); main(void) { FILE *fp; int rep,n,i; char x[256],key[256],*result[256][256]; printf("検索キーワードを入力してください。\n" "キーワード>"); gets(key); if((fp=fopen("personal.txt","r"))==NULL) { printf("ファイルをオープンできません\n"); exit(1); } printf("=====検索結果=====\n"); n=search(key,fp,result); for(i=0;i<n;i++) { printf("%s\n",result[i]); } printf("検索結果:%d件です。\n",n); fclose(fp); } int search(char key[256],FILE *fp,char *result[256][256]) { int n=0; char *p,word[256],*name; while((p=fgets(word,256,fp))!=NULL) { if(strstr(word,key)!=NULL) { name=strtok(p," "); strcpy(result[n],name); n++; } } return n; } 実行すると、下の警告がでます。 illegal pointer combination(param)

  • 関数内でconst修飾子を使用した場合の配置

    お世話になります 関数内でconst修飾子を付加した領域を宣言します。 その領域は何処に取られるのでしょうか? RAM?ROM?スタック? コンパイル環境により異なるのでしょうか? void Test(void) { const int i_dat = 0;   ・・・・・・ } よろしくおねがいいたします。

専門家に質問してみよう