• ベストアンサー

2次元配列をポインタで参照したいのですが・・

下記Aのような2次元配列を作るとします。 A:1行あたり1024文字(ASCII)格納できるN行の2次元配列 Aの定義をまず下記Bのように行い、その後サイズ分メモリを確保しました。 B:char *str; この変数strを使って、x番目の行のy番目の文字を参照したい場合、どのようにすれば良いのでしょうか? 下記Cではやはりうまくいかないのでしょうか? C:str[x][y] 申し訳ございませんが、ご教授よろしくお願い致します。

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

  • ベストアンサー
  • ranx
  • ベストアンサー率24% (357/1463)
回答No.4

しばらくCから離れていたので、自信があやふやですが char (*str)[1024]; str = ((*)[1024])malloc(sizeof(*str)*N); でどうでしょう。 #2さんのように考えれば1024ではなく1025でも良いでしょう。 x行y列目は str[x-1][y-1] で参照できます。

ketchappt
質問者

お礼

目から鱗の回答、とても勉強になりました! どうも有難うございます!

その他の回答 (4)

noname#25358
noname#25358
回答No.5

 2次元配列の場合、「N個のポインタ配列」を作り、それをそれぞれ個別に制御する方法が挙げられます。  一番簡単なのは、   char **str;  という多重ポインタ配列を用意し、まず N 個のポインタ配列を malloc します。  str = (char**)malloc(sizeof(char*)*N);  次に、確保した N 個の配列に、1つずつ文字列を malloc していきます。  for ( i = 0; i < N; i++ ) {   str[i] = (char*)malloc(256);  }  このとき、   str[x]  は、N 個中の x 番目の文字列を指します。  また、   str[x][y]  は、N 個中の x 番目の文字列の中の、y 番目の文字を指します。

ketchappt
質問者

お礼

とても参考になりました! どうも有難うございます!!

回答No.3

> 行単位でデータを参照したい場合は、いい方法はありますでしょうか? char* str = (char*)malloc(sizeof(char)*1024*N); のとき、str+1024*x が第x行の先頭です。

ketchappt
質問者

お礼

ご回答重ねて感謝いたします!

  • arukamun
  • ベストアンサー率35% (842/2394)
回答No.2

私なら、 #define N 100 char str[N][1025] ; とか1024では無くて、1025で作ります。 (mallocで領域確保するにしてもです。) なぜかは文字列だから最後の'\0'の1文字を加えてという事です。

ketchappt
質問者

お礼

ご回答とご指摘どうもありがとうございます。Nが可変長である場合、str[x][y]やstr[x]のように参照したい場合はどうしたらよいでしょうか?大変申し訳ございませんが、良かったら教えていただけないでしょうか?よろしくお願いします。

回答No.1

char* str = (char*)malloc(sizeof(char)*1024*N); char c = str[x*1024+y]; > 下記Cではやはりうまくいかないのでしょうか? > C:str[x][y] ダメです。

ketchappt
質問者

お礼

早速のご回答どうもありがとうございます。追加で質問させていただきたいのですが、行単位でデータを参照したい場合は、いい方法はありますでしょうか?恐れ入りますが、お時間に余裕がございましたらご教授ください。

関連するQ&A

  • 2次元配列とポインタの引数受け渡しについて

    2次元配列を関数に渡すときは、引数に渡す2次元配列と同じサイズを指定、もしくは2次元目のサイズのみ合わせて渡す方法がありますが、両方とも違うサイズで同じ関数を使いたいです。 最初は中身が同じで引数で受け取る2次元配列のサイズだけ、それぞれに合わせた引数を持つ関数を2つ作っていたのですが、なんだか冗長な気がしました。 そこで、2次元配列の先頭ポインタとサイズを受け取るようにすればいいのかと思い、テストとして次のプログラムを作成してみました。 #include <stdio.h> void func(unsigned char *a, int y, int x); int main(void) { unsigned char a[10][10]; func(a, 10, 10); printf("%d\n", a[7][4]); return 0; } void func(unsigned char *a, int y, int x) { int i, j; for (i = 0; i < y; i++) { for (j = 0; j < x; j++) { *(a + i*y + j) = i * j; } } } もちろんこれでも動くのですが、やはりこういう書き方はルールにはないので、コンパイルで警告が出ます。 a.c: In function ‘main’: a.c:10: warning: passing argument 1 of ‘func’ from incompatible pointer type a.c:4: note: expected ‘unsigned char *’ but argument is of type ‘unsigned char (*)[10]’ このような書き方はやはりやめたいいのでしょうか。 また、その際はサイズ別に関数を作るしかないのでしょうか。 他にいい方法があれば教えていただけると助かります。

  • 3次元配列から2次元配列に

    3次元配列のデータを2次元配列に移すにはどのように したらよいのでしょうか.とりあえず下記のように考えてみましたが. data3[500][500][4000]; //3次元配列 data2[500][500]; //2次元配列 for(y=0; y<500; y++) for(x=0; x<500; x++){ for(z=0; z<4000; z++){ data2[y][x] = data3[y][x][z]; } } } これでいいのでしょうか?

  • ポインタ配列

    "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'; }

  • 3次元配列から2次元配列への代入

    C言語初心者です。 詳しい方、宜しくお願い致します。 下記のような三次元配列(Sanjigen[2][5][5])があります。 ダンプしたもので見難くてすみません。 00FFBCBC [0][0][0] 01 02 03 04 05 00FFBCC1 [0][1][0] 06 07 08 09 10 00FFBCC6 [0][2][0] 11 12 13 14 15 00FFBCCB [0][3][0] 16 17 18 19 20 00FFBCD0 [0][4][0] 21 22 23 24 25 00FFBCE4 [1][0][0] 26 27 28 29 30 00FFBCE9 [1][1][0] 31 32 33 34 35 00FFBCEE [1][2][0] 36 37 38 39 40 00FFBCF3 [1][3][0] 41 42 43 44 45 00FFBCF8 [1][4][0] 46 47 48 49 50 このデータ(Sanjigen[2][5][5])を、二次元配列にしまう方法をご教授ください。 Nijigen1[5][5]には三次元配列のデータ(1~25)と(26~50)をアンドしたデータを格納します。 Nijigen2[5][5]には三次元配列のデータ(1~25)と(26~50)をオアしたデータを格納します。 下記は自分の作ったプログラムですが、うまくいきません。 char Sanjigen[2][5][5]; char Nijigen1[5][5]; char Nijigen2[5][5]; void get_data( void ) { char i; for( i=0; i<8; ++i ){ Nijigen1[i] = Sanjigen[0][i] & Sanjigen[1][i]; Nijigen2[i] = Sanjigen[0][i] ^ Sanjigen[1][i]; } } 説明わかりにくくて申し訳ありません。 宜しくお願い致します。

  • 多次元配列の一次元目の最大値の求め方

    多次元配列の一次元目の最大値の求め方 下記のような多次元配列(ちなみに、これって二次元配列ですか?)があるとき、 常に、「一次元目の最大値+1」を返すようにしたいのですが、 どうすればよいのでしょうか? $data[0][0]とか$data[1][0]とか$data[2][0]とかの最大値の意味です。 下記の例でいくと、一次元目の最大値が3なので、数値の4を返したいのですが…、 ■$data 1,0,A1,B1,C1 2,5,A2,B2,C2 3,0,A3,B3,C3 3,2,A4,B4,C4

    • ベストアンサー
    • PHP
  • 配列とポインタについて

    #include <stdio.h> int main() { char x[3]; char *y; x[0]='a'; x[1]='b'; x[2]='\0'; y="abc"; printf("xの値は%s\n",x); printf("yの値は%s\n",y); } 通常の配列宣言では、このままだと文字列をまとめて 代入できないのに対して、ポインタ変数ならまとめて代入することができるのは何故ですか?そういう仕組みだと言われてしまえば、それまでなんですが・・・

  • 配列とポインタの関係

    配列とポインタについてです。 char *p_str="HAPPY";と char p_str[10]={'H','A','P','P','Y'}; は同じことでしょうか?

  • テキストファイルを二次元配列に

    お世話になります。 テキストファイルを1行ずつ読み込んで二次元配列に格納するプログラムですが、 //最大行数 #define LINE_MAX 10 //行内最大文字数 #define INPUT_MAX 128 char str[LINE_MAX][INPUT_MAX]; というようにして実現しています。 これを行数が分からないテキストファイルでも大丈夫なようメモリを動的に確保したいと考えています。 二つの次元の内、一つを動的に確保するにはどのようにしたら良いでしょうか。

  • 多次元配列の初期化

    多次元配列の初期化を行いたいのですが、 下記の方法では、配列の値が多くなったときに大変 なので他に良い方法はありませんでしょうか? char lesson[7][6] = { {'A', 'B', 'C', 'D', 'E', 'F'}, {'G', 'H', 'I', 'J', 'K', 'L'}, {'M', 'N', 'O', 'P', 'Q', 'R'}, {'S', 'T', 'U', 'V', 'W', 'X'}, {'Y', 'Z', 'a', 'b', 'c', 'd'}, {'e', 'f', 'g', 'h', 'i', 'j'}, {'k', 'l', 'm', 'n', 'o', 'p'}, };

  • C#で、引数における一次元と二次元配列の取り扱い

    C#について質問させていただきます。 以下のようにすればそれぞれ一次元配列と二次元配列を格納出来ますが 同時に一つの引数に収めることは無理なのでしょうか?    public static void Join(string[] Ary_str){ 本文 }    public static void Join(string[ , ] Ary_str){ 本文 } そのために、例えば以下のようにしたとします。    public static void Join(object Ary_obj){ 本文 } こうすれば一次元でも二次元でも格納出来ますが 格納された値が何次元配列なのか確認するために    Ary_obj.Rank としてもエラーになってしまいます。 (1)Objectに格納した値が何次元配列なのか確認する方法か (2)一次元でも二次元でも格納できる引数の指定方法 をご存じの方、ぜひお教え願います。><

専門家に質問してみよう