• ベストアンサー

関数に引数として配列を渡す方法

mainからtest関数にクラスAの中の ch[2][4]を渡したいのですが *hiki[1][1] = 'A';がコンパイルに通りません。 やり方が違うのでしょうか? class A{ char ch[2][4]; }; void test(char *hiki){ *hiki[1][1] = 'A'; } int main(){ A ob1; test(&ob1.ch[0][0]); return 0; }

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

  • ベストアンサー
  • chie65536
  • ベストアンサー率41% (2512/6032)
回答No.2

void test(A *hiki){ hiki->ch[1][1] = 'A'; } int main(){ A ob1; test(&ob1); return 0; } ではどうでしょう? なお、元のプログラムでは、testに渡されたhikiは、単なるcharへのポインタで、hiki[1]やhiki[3]などと記述するのは可能ですが、hiki[0][1]や*hiki[0]や*hiki[1][1]などとは記述出来ません。 何故なら、test関数の中では、2次元配列の1次目の要素数が判らないので、実際のアドレスが計算出来ないのです。 例えば「30人を、前から順に何列か、1列の中は右から順に、出席番号順に四角く並べました。前から2列目の、右から2番目の人の人の出席番号は何番ですか?」と聞かれても、答えるのは不可能です。何故なら、1列が3人なのか、5人なのか、6人なのか、10人なのか、15人なのか判らないからです。 「charへのポインタだけ渡す」って事は、上記の例で言えば「先頭はこの人です。全体で何列なのか、1列が何人なのかは判りません」って言うのと同じです。「前から何列目の右から何人目」って言われても、1列の人数が判らないので、どうしようもありません。

jetblue
質問者

お礼

ありがとうございました。 二次元配列の仕組みがわかりました。 ありがとうございました。 また、他の回答をしてくださった方も ありがとうございました。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (2)

  • ryumei
  • ベストアンサー率60% (3/5)
回答No.3

根本的な回答にはなっていませんが、参考までに。 折角クラスを使うのですからC++らしくやってみてはいかがでしょう。 ※以下の例は初期化やセキュリティ性は中途半端にしか(むしろ殆ど)考慮してませんが^^; #define MAX_X 2 #define MAX_Y 4 class A{ public: // 任意の箇所に任意の文字を入れる void setChar(int x,int y,char pChr); private: // 2次元配列の本体 char ch[MAX_X][MAX_Y]; }; void main(){ A obj; // 実体の生成 obj.setChar(0,0,'A'); // 2次元配列の最初に'A'を代入 } void A::setChar(int x,int y,char pChr) { ch[x][y] = pChr; // 本体にセットする } ※配列を引数にする際にはNo.2氏がおっしゃるように注意が必要です。 配列の先頭アドレスだけを受け渡すことになるので、渡された関数側ではどのような配列なのかがわからず、2次元以上の配列操作は不可能なのです。 (多次元配列もメモリー上の見た目では順番に並んでるだけなのです)

全文を見る
すると、全ての回答が全文表示されます。
  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.1

★引数の宣言を変えるのが一番簡単ですよ。 void test( char hiki[2][4] ) ←ここがポイント {  hiki[ 1 ][ 1 ] = 'A'; ←『*』は必要ありません。 } int main() {  A ob1;    test( &ob1.ch[0][0] ); ←『ob1.ch』でも可能。  return( 0 ); } ・短いですがこれで終わりです。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • 関数の引数なしを変数に代入したら入ってきた数値は何?

    デバッグソフトで自分のプログラムを動かしていたときに、 int test_func(char x) { x = x + 1; ------(中略)----------- return x; } int main(void) { int test_val; ------(中略)----------- test_val = test_func; ------(中略)----------- } このようにtest_func(char x)という関数の戻り値を変数test_valに代入するつもりだったのですが、間違って引数部分を書かずにコンパイルしてしまいました。 このときにコンパイルでエラーが出ると思ったのですが、コンパイル完了でデバッガで変数test_valをみてみると何か値が入っていました。 ちょっと気になったのですが、この変数の中に入った値はいったい何なのでしょうか。ご存じの方いらっしゃいましたらご教授お願いいたします。

  • 関数へ引数を渡す時・・・(C言語)

    Cを始めたばかりです。 レベルの低い質問だと思いますがお願いします。 【ソース】 /* a1.c */ #include <stdio.h> void aaa(char); int main( int argc, char *argv[] ) { char box[] = "test"; aaa(box); return 0; } /* a2.c */ #include <stdio.h> void aaa(char box) { printf( "%s",box ); } 【質問】 変数boxの中身を関数aaaに渡したいだけですが、 上記ソースをコンパイルすると、a1.cの aaa(box) の部分でエラーが出てしまいます。 どうもデータ型(ポインタ?)がまずいようですが、 何が問題なのでしょうか? 御回答宜しくお願い致します。

  • 関数から配列を返すには?

    return で配列を返すにはどうしたらよいのでしょうか。 例えば以下のような場合です。 int main (){ char Value[] = "999"; int a;  a = test(Value);  printf ("%d", a);   } int test(char *Value) { int nVal[255]; ここで nVal に適当な処理をして・・・  return Value; }  int a を配列とかにしてみましたけど、コンパイラが 通りません。 要は配列数値を main で受け取って表示したいのですが、 本日C言語はじめたところなので、教えていただければありががたいです。

  • 関数の引数をvoid*でキャストする

    最近見かけたCのプログラムで、関数の引数の型は void* なのですが、その関数を使うときに 引数をvoid*でキャストしていました。 例えば、 func ( (void*) p ); こういうことです。 私の知っている知識では、 void* と 任意の型のポインタは キャストなしに相互に代入可能です。 関数の引数でも、キャストは要らないものだと思っていました。 そうすると、引数を void* でキャストするのは無意味だと思うのですが、・・・ 違うのでしょうか。処理系によるとか。 逆に、関数の引数の型がchar*などで、渡すものが void* のときはどうなのでしょうか。 下のプログラムは、関数byte_orderの引数の型はvoid*ですが、int型へのポインタ( &a )を設定しています。私の環境では、コンパイルエラーも警告もないし、動作も正常です。 #include <stdio.h> #include <string.h> void byte_order(void *vp) { char char_array[4]; strncpy(char_array, vp, 4); printf("出力します:%x %x %x %x\n", char_array[0], char_array[1], char_array[2], char_array[3]); } int main(void) { int a = 0x12345678; byte_order(&a); return 0; } このプログラムは単なる一例であって、質問はバイトオーダに関するものではありません。 また、C言語の質問であって、C++ではありません。

  • 構造体を引数とする、クラス間のデータの受渡し方法について

    現在、C++の構造体を理解しようと努めていますが、どうしても理解できない点があり、 なにとぞ、ご指導・ご助言のほどよろしくお願い致します。 1.質問内容  a.構造体を引数とする、クラス間のデータの受渡し方法について ・主プロ(主クラス)側の構造体のメンバ変数を、サブプロ(サブクラス)側で更新するのに、 メンバ変数を一つずつ引数として渡せば、正しく更新できるのですが、構造体を引数として渡すと    コンパイルエラーになります。   ・どのように定義すれ場良いのかをご助言お願い致します。 2.プログラムの内容を簡単に記載します。  全部を記載する事は出来ないので、一部を省略して簡単に必要な所だけを記載します。  a.Main.cpp int main() { CMain main; CSub sub; //Main_Classの関数に、Sub_Classクラスのポインタを引数として渡し、Sub_Classクラスの関数を呼び出す main.Main_FuncCall(&sub); return 0; } b.CMain_Class.h class CMain { public: //コンストラクタ 省略 //デストラクタ 省略 typedef struct CHAR1 { int m_chx; int m_chy; bool m_chValidFlag; }; CHAR1 *pc; //データの受け渡し(ポインタ) void Main_FuncCall( CSub* cs ); };  c.CMain_Class.cpp void CMain::Main_FuncCall( CSub* cs ) { //メインクラスの構造体を引数として、サブクラスの関数を呼び出す //サブプロ側の構造体を更新する cs->Sub_FuncCall4( pc ); } d.CSub_Class.h class CSub { public: //コンストラクタ 省略 //デストラクタ 省略 typedef struct CHAR_S { int m_chx; int m_chy; bool m_chValidFlag; }; CHAR_S *ps; void Sub_FuncCall( CHAR_S *pc ); }; e.CSub_Class.cpp void CSub::Sub_FuncCall( CHAR_S *pc ) { pc[1].m_chx += ps[1].m_chx; } 3.コンパイルする  a. cs->Sub_FuncCall4( pc ); -> 1 番目の引数を 'struct CMain::CHAR1 *' から 'struct CSub::CHAR_S *' に変換できません。 (新しい機能 ; ヘルプを参照) 指示された型は関連がありません; 変換には reinterpret_cast、 C スタイル キャストまたは関数スタイルのキャストが必要です。 b.色々と試してみましたが、現在の私の知識ではコンパイルができません。   アドバイスのほど、よろしくお願いします。

  • オブジェクトのポインタ

    #include<iostream> using namespace std; class letters{ char ch; public: letters(char c){ch=c;} char get_ch(){return ch;} }; int main(){ letters ob(A) cout<<ob.get_ch(); return 0; } なんですが cout<<ob.get_ch(); を cout<<&ob->get_ch(); には何故できないのですか? これならコンパイルできるのですが、 letters *p; p=&ob; cout<<p->get_ch(); コンパイラはVisual Studio 2008です よろしくお願いします。

  • 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]’ このような書き方はやはりやめたいいのでしょうか。 また、その際はサイズ別に関数を作るしかないのでしょうか。 他にいい方法があれば教えていただけると助かります。

  • 関数の引数の書き方。

    AとBのどちらの書き方でもよいのですか? 私が読んだ本(やさしいC)には、 Aパターンのみだったような? Aパターン ------------------ void main(int argc,char *argv[]) { int i; ・・・・ } Bパターン ------------------ void main(argc, argv) int argc; char *argv[]; { int i; ・・・・ } http://ash.jp/db/ora_c.htm

  • 関数の引数表記なしについて

    はじめまして。C言語初心者です。 質問させてください。 関数を宣言して引数を表記しないで使用することは可能なのでしょうか? またどのような場合に使用するのでしょうか? 例として以下コードになります。 ----------------------- #include<stdio.h> int test1(int a); void test2(int b); void main(){ int i = 0; int j = 0;       //この部分 i = test1; printf("%d\n", i);        //この部分 j = test2; printf("%p\n", j); } int test1(int a){ return a + 1; } void test2(int b){ printf("test"); } --------------------------- 出力結果を見ると関数のアドレスが帰ってくるように思われますが、詳細が分かりません。 詳しい方がいらしましたら教えてください。 宜しくお願いいたします。

  • 関数ポインタにvirtual関数を与えたいです

    //関数ポインタについて質問させてください。 //error C2440: '=' : 'void (__thiscall A::* )(int,int)' から 'void (__cdecl *)(int,int)' に変換できません。 //というエラーが出ます。 //どうすればいいのか教えてください。 //よろしくお願いします。 #include<stdio.h> class A { public: void (*aaa)(int a,int b); virtual void test(int a,int b)=0; virtual void test2(int a,int b)=0; void execute() { aaa=test;//error C2440 } }; class B : public A { public: void test(int a,int b) { printf("test"); } void test2(int a,int b) { printf("test2"); } }; int main() { B b; b.execute(); b.aaa(2,3); return 0; }