• ベストアンサー

VB2008: 構造体と関数との関係?

VB.Net を知って60日余という初学者です。 やっと、構造体の基本事項の確認まで辿り着きました。 で、構造体と関数の関係をテスト。 結果、「関数に構造体全体を渡す場合には、たとえモジュールレベルの変数として宣言してモジュールレベルだけで用いるとしても Public で広域な変数として宣言しなければならない」ことが判明しました。 このことに関しての個人的な見解は次のようです。 >「関数のパラメータの型に用いる構造体等は全て Public で宣言されることで公開されていなければならない。 >関数がどういう型を受け取って、どのように演算し、いかなる型の値として戻すかは公開されていてこそ判断できる。 つまり、「関数の内々の事情、関数の約束事からの Public 宣言であって、構造体の通用範囲を広域にするためのそれではない」というのが私の理解。 問題は、MSDN ライブラリでこの理解の裏付けを取りたいのですが、なかなか見つかりません。 そこで、質問の角度を変えます。 この「関数の内々の事情説」、「関数の約束事説」という理解はいかがなものでしょうか?

noname#140971
noname#140971

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

  • ベストアンサー
  • KG_
  • ベストアンサー率62% (34/54)
回答No.2

先日の投稿も拝見したのですが、構造体とはStructureのことですよね? VB2008が手元にないためVB2005でテストしたのですが、 Publicでは無くとも動作はするようです。どのようなコードでどんなエラーになったのかご提示頂ければ、皆様も回答を付けやすいと思うのですが、 いかがでしょうか。VB2008で変更になったとは確認が取れないもので、 実際エラーになるのであれば申し訳有りません。 一応下記コードにて動作することは確認できました。 ---------------------------------------------------------- Public Class Form1 Private Structure TEST Dim TESTSTRING As String Dim TESTINTEGER As Integer End Structure Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Dim tst As TEST tst.TESTSTRING = "START" tst.TESTINTEGER = 0 Debug.Print(tst.TESTSTRING) Debug.Print(tst.TESTINTEGER.ToString) tst = TESTFUNCTION(tst) Debug.Print(tst.TESTSTRING) Debug.Print(tst.TESTINTEGER.ToString) End Sub Private Function TESTFUNCTION(ByVal source As TEST) As TEST Dim returnTEST As TEST = source returnTEST.TESTSTRING = "CHANGE" returnTEST.TESTINTEGER = 1 Return returnTEST End Function End Class ----------------------------------------------------------

noname#140971
質問者

お礼

' ================================ ' 関数に構造体全体への参照を渡す ' ================================ Module theTEST   Public Structure TEST4     Dim MembersCount As Integer     Dim Member1 As String     Dim Member2 As String   End Structure   Sub Main()     Dim T4 As TEST4     T4.MembersCount = 2     T4.Member1 = "T4:Member1"     T4.Member2 = "T4:Member2"     ReferenceAllMember(T4)     Debug.Print(T4.MembersCount.ToString)     Debug.Print(T4.Member1)     Debug.Print(T4.Member2)   End Sub   Sub ReferenceAllMember(ByRef T4 As TEST4)     T4.Member1 = "Member1 of T4"     T4.Member2 = "Member2 of T4"   End Sub End Module このようなテストです。

その他の回答 (2)

  • KG_
  • ベストアンサー率62% (34/54)
回答No.3

redfox63様の回答の補足的なものになりますが、、 StructureをPrivateで宣言するとおそらく下記の関数がエラーになるかと思います。 >  Sub ReferenceAllMember(ByRef T4 As TEST4) >    T4.Member1 = "Member1 of T4" >    T4.Member2 = "Member2 of T4" >  End Sub これは、Privateで宣言された構造体TEST4がPublicな関数、ReferenceAllMemberで外部に公開されようとしているからです。(VBでアクセス修飾子を省略した場合、暗黙でPublicになります。) なので、「ReferenceAllMember」関数も「Private Sub」とすればエラーも解消できるはずですが、、、

noname#140971
質問者

お礼

必死の解釈も見当違いだということがわかりました。 >これは、Privateで宣言された構造体TEST4がPublicな関数、ReferenceAllMemberで外部に公開されようとしているからです。 本当に質問してよかったです。 ありがとうございました。

  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.1

その関数がモジュールの外部からアクセスされないのであれば 構造体の宣言は Privateにできますよ Module Module1   private Structure stType1     public ss as String   End Structure   private Sub SubFunc1( st1 as stType1 )     Debug.Print( st1.ss )   End Sub   ' 以下のように Module1以外へ公開するメソッドなどの引数として   ' 使いたいなら Privateでの宣言はできません   ' Sub SubFunc2( st1 as stType1 )   '   Debug.Print( st1.ss )   ' End Sub   public Sub Test()     dim p1 as StType     p1.ss = "hoge"     SubFUnc1( p1 )   End Sub End Module といった具合で ...

noname#140971
質問者

お礼

今、思ったのですが Sub Main() が・・・。 つまり、テストしているステージの問題かなー・・・。 と、思い出しました。 まだ、よく判っていません。

関連するQ&A

  • 関数 構造体 ポインタ

    番号、名前、年齢を一組とした構造体の変数をmain関数で宣言し、そのアドレスを副関数に引き渡す。副関数で従業員番号、氏名、年齢を入力し、main関数に戻る。main関数で構造体の内容を表示する。 困ってます、ポインタがどうにも理解できません。

  • ポインタ 構造体 関数

    番号、名前、年齢を一組とした構造体の変数をmain関数で宣言し、そのアドレスを副関数に引き渡す。副関数で従業員番号、氏名、年齢を入力し、main関数に戻る。main関数で構造体の内容を表示する。 困ってます、ポインタがどうにも理解できません。

  • 構造体について

    linuxのソースコードを呼んでいる者ですが、構造体について、実際に使う方法が分かりません。 ソースコードを少し書き換えて改良したいのですが、構造体が定義されているので、それをそのまま引用しないといけないので分からなくなってしまいました。 例えば、それぞれの関数のなかで最初の変数宣言の部分にstructが付いているものもあれば、付いていないものもあります。 この差はなんなのでしょうか?

  • 構造体の使い方

    構造体が定義されている場所では、 struct runqueue{ task_t としかないのに、実際の関数の部分では task_t *p = current というように、変数として宣言されている部分があるのですが、これにはどういった意味があるのでしょうか?

  • 構造体と構造体型の変数宣言箇所

    はじめてborlandC++builder6でプログラムを作っているのですが、構造体と構造体型の変数宣言箇所についてわからないことがあるので質問させてください。 あるフォームのソースファイル(○○○.cpp)内の関数で、自分で定義した構造体を使う場合、ヘッダファイル(○○○.h)に構造体を定義すると、関数内で「変数が未定義」エラーになってしまいます。一方、ソースファイル(○○○.cpp)の先頭に書けばエラーになりません。  ヘッダファイルに変数定義した場合とソース内の先頭に構造体と構造体型変数を定義するのでは何が違ってくるのでしょうか?

  • HOSTENT構造体を宣言する必要はないのですか?

    ネットワークプログラミングを勉強しているのですが,ソケットを用いた通信のサンプルで, HOSTENT *lphost として,HOSTENT構造体へのポインタを宣言して, lphost = gethostbyname(ホスト名の文字列); で,サーバーのアドレスをHOSTENT構造体にセットするとあります。 構造体へのポインタを宣言しても,構造体自体の領域は確保されないのではないかと思うのですが,gethostbyname関数が返すポインタは,いったい誰がどこに確保した領域を指しているのか,そしてその領域はいつまで保持されるのか,よく理解できません。構造体そのものを宣言せずに,それへのポインタを宣言し,それに関数の戻り値を代入するというのが,よく理解できないです。どなたか解説していただけると幸いです。

  • 構造体の纏め方

    関数のポインタを使用して、 /* プロトタイプ宣言 */ void func1 ( void ); void func2 ( void ); void func3 ( void ); /*******************/ /* プロトタイプ纏める */ void ( *funcs[] ) ( void ) = { func1, func2, func3 }; /*********************/ と言うのが、構造体でも出来ないでしょうか?と言うのが質問です。 変数(添字)によって、見るべき構造体を自由に変更させたいと言うのが主な使用方法です。 typedef struct _tag { int arg1; int arg2; } tag; tag watch1 , watch2 , watch3; とある変数が1なら、watch1、とある変数が2なら、watch2、とある変数が3なら、watch3を見ると言うようなプログラムにしたくて、質問しました。 witch文を使うしかないのでしょうか? 良き回答、お待ちしています。

  • C言語の構造体

    組込み系でマイコンにソフトをプログラミングの仕事をしています。 C言語は初心者です。 http://www9.plala.or.jp/sgwr-t/c/sec15.html のページの冒頭に、 「構造体は幾つかの異なる型のデータをまとめて 1つのデータ型として扱うものなのです。」と書かれています。 1つのデータ型として扱うとどのようなメリットがあるのでしょうか? 例えば、 struct seiseki seito1; のように対象が1つ(seito1)なら int seito1_no; char  seito1_name[20]; double seito1_average; と変数を確保すれば済むのに、 何故、構造体で宣言するのでしょうか? 例えば、 struct seiseki seito2[20]; のように、似たものが複数ある場合は(seito2が20人分なるなら、) 構造体で宣言する意味があるとはなんとなくわかります。 後ページの http://www9.plala.or.jp/sgwr-t/c/sec15-4.html では、関数でのやり取りが書かれています。 関数で引数や返値で扱うときに構造体にしておいた方が良いからでしょうか? 構造体のメリットというのが今一わかりません。 対象が1つでも構造体で書いた方がいろんな意味で良いのでしょうか? 如何せん、初心者なので質問がうまく書けませんがご了承ください。 ※上から目線的な回答はご遠慮願います。

  • 構造体のアドレス渡し

    構造体をmain()からアドレス渡しで別関数(test.cpp)に渡し、その関数の中だけでの別関数test1()にその構造体を、値渡しでもアドレス渡しでも、渡せるのでしょうか? ちなみにmain.cppと、test.cppと、myhead.hとして分割コンパイルでやりました。 /*---------main.cpp--------*/ //ヘッダファイルで構造体宣言、test()のプロトタイプ宣言済み void main() { struct data dt[10]; ・・・・・・ test(dt); //test.cppのtest関数に構造体を渡す。 } /*---------test.cpp---------*/ void test1(??????); //test1()のプロトタイプ宣言 void test(struct data *p) //構造体をアドレス渡しで受け取った { ・・・・・ test1(?????); //test.cppで宣言したtest1関数に構造体を渡したい } どうかよろしくお願いします。

  • 構造体を引数で関数へ渡す

    こんばんは。現在C言語を学んでいます。 課題という形で構造体で定義されたデータを関数の引数に当てはめ、データを渡すという処理を行わねばならぬのですが、関数を利用しての構造体の受け渡しが分からず苦戦しております。ご助言頂ければ幸いです。 分かりづらいかとは思いますが下記が私が簡単にですが作ったものとなります。 私の考えている動作プロットとしては 1. 構造体の形式を定義する。 2. 冒頭にて存在する関数を定義 3. main関数内にて構造体に名前を付けて定義し、値を入力より受付 4. do_it_hoge関数に構造体を引数として与え(ここが分からず)関数を呼び出す。 5. 関数内にて引数で受け取った &hoge.a,b,c等を表示するなどしたい。(受け取る方法が分からず) 関数を呼ぶ際にカッコ内に入れるのは構造体の名前のみで良いのでしょうか? (例: do_it_hoge(hoge); のように) また呼び出される関数側の括弧は何を記述するのでしょうか? いつもならint hogehoge, や char hoge, などと宣言しているかと思うのですが。 読みづらく、分かりにくいものかとは思いますが どうぞ宜しくご教授頂ければと思っております。 構造体を触るのが久しぶりだったのでそちらでミスがあるかもしれません。もし何か補足等必要でしたらメッセージ頂ければ返事させていただきたいと思います。 //----------------------------------------------------------------// //構造体HOGEHOGE定義 //----------------------------------------------------------------// typedef struct tagHOGEHOGE { int a,b; int c; }HOGEHOGE; void do_it_hoge();//関数定義。ここでのカッコ内の定義も不明 //----------------------------------------------------------------// // main //----------------------------------------------------------------// void main(){ HOGEHOGE hoge;//hogeをHOGEHOGE利用で定義 scanf("%d,%d",&hoge.a,&hoge.b);//カンマ区切りで代入 scanf("%d",&hoge.c);//数値をhoge.cへ do_it_hoge();//←ここが分からず } //----------------------------------------------------------------// // do_it_hoge 関数。構造体を引数で受け取りたい関数。 //----------------------------------------------------------------// void do_it_hoge(){ // ←括弧内の受け方が分からず // ここでmainで入力された &hoge.aなどを参照して表示したい // 例: printf("hogeA:%d",&hoge.a); } //----------------------------------------------------------------//

専門家に質問してみよう