ActiveBasicでのプログラミングでわからないこと、困ったことなどがあったら、ここで質問してみましょう(質問を行う場合は、過去ログやWeb上であらかじめ問題を整理するようにしましょう☆)。
卓漏
記事: 32 登録日時: 2005年11月30日(水) 06:38
お住まい: 静岡県の田舎町
#1
投稿記事
by 卓漏 » 2006年6月07日(水) 20:05
下のようなプログラムを作ったのですが、
関数内では、正しく値を表示できるのですが、
関数から戻ってきた値が正しく表示されません。
誰か教えてください。
コード: 全て選択
Print makePtr(x)
End
Function x() As *char
Dim Str$ As String
/* 何らかの処理 */
Print Str$
x = StrPtr(Str$)
End Fuction
[/code]
C1000
記事: 185 登録日時: 2006年5月07日(日) 17:16
お住まい: 宮城県
連絡する:
#2
投稿記事
by C1000 » 2006年6月07日(水) 20:12
エラーなどがでていたらここに書いてください。
あとコードのミスを発見したので書いておきます。
コード: 全て選択
Print MakeStr(x)
End
Function x() As *char
Dim Str$ As String
/* 何らかの処理 */
Print Str$
x = StrPtr(Str$)
End Function
卓漏
記事: 32 登録日時: 2005年11月30日(水) 06:38
お住まい: 静岡県の田舎町
#3
投稿記事
by 卓漏 » 2006年6月07日(水) 20:32
エラーは出ないのですが、文字化け状態で表示されます。
あと、コードをミスしていましたが、それが原因ではありません。(恥)
C1000
記事: 185 登録日時: 2006年5月07日(日) 17:16
お住まい: 宮城県
連絡する:
#4
投稿記事
by C1000 » 2006年6月07日(水) 20:38
StrPtrは簡単に言うとString型をBytePtrに変換する関数なので*charではなくBytePtrにしてみてください。(*charってABで定義無いような気が・・・)
最後に編集したユーザー
C1000 [ 2006年6月07日(水) 20:41 ], 累計 1 回
イグトランス
記事: 899 登録日時: 2005年5月31日(火) 17:59
お住まい: 東京都
連絡する:
#5
投稿記事
by イグトランス » 2006年6月07日(水) 20:40
xの呼び出しに関数呼び出しの()がありませんが書き写し間違いでしょうか。
String型は文字列のメモリの管理をしてくれますが,ポインタ型はそうではありません。
そのため,関数xを抜ける際に変数Str$の中身の文字列のメモリが解放されてしまっています。
特に事情が無ければxがString型を返すようにすれば良いのですが,そうできない事情でもあるのでしょうか?
NoWest
記事: 264 登録日時: 2005年5月31日(火) 10:52
お住まい: 高知
連絡する:
#6
投稿記事
by NoWest » 2006年6月07日(水) 20:41
この問題は関数をよく理解していないとやってしまうポカの1つです。
まずはローカル変数とグローバル変数についてよく理解してください。
関数内で宣言された変数はローカル変数ですよね。
ローカル変数は基本的に関数を抜けた時点で消滅しますので
消滅する変数へのポインタを関数の戻り値に指定するとどうなるか考えてみてください。
P.S.
イグトランス様に先を越されたようですね。
イグトランス様が仰っているのは
コード: 全て選択
Function x() As String
Dim Str$ As String
/* 何らかの処理 */
Print Str$
x=Str$
End Function
ってことです。
どうしてもポインタを返したいなら
コード: 全て選択
Function x() As *Char
Dim pStr As *Char
pStr=calloc(256)
/* 何らかの処理 */
Print MakeStr(pStr)
x=pStr
End Function
この場合、x()関数が返したポインタをfree()で解放しないといけなくなります。
cdecl形式の関数であればスタックは呼び出し側が始末するので
後で解放しなくてもよいものができそうですが。。。
最後に編集したユーザー
NoWest [ 2006年6月07日(水) 20:51 ], 累計 3 回
C1000
記事: 185 登録日時: 2006年5月07日(日) 17:16
お住まい: 宮城県
連絡する:
#7
投稿記事
by C1000 » 2006年6月07日(水) 20:46
自分もポカしてましたね(恥)直し方はわかりましたがわりと簡単なのでここには書きません。
卓漏
記事: 32 登録日時: 2005年11月30日(水) 06:38
お住まい: 静岡県の田舎町
#8
投稿記事
by 卓漏 » 2006年6月07日(水) 22:35
BytePtr型を使ってもだめだったので、
「NoWest」さんのコードを参考にして、「String型」から強引に「*char型」に変換する関数(StrToChar)を作って組み込んだところ、問題が解決しました。
コード: 全て選択
Print MakeStr(x)
End
Function x() As *char
Dim Str$ As String
/* 何らかの処理 */
Print Str$
x = StrToChar(Str$)
End Function
Function StrToChar(Str$ As String) As *char
Dim I As Integer, Max As Long
Dim pStr As *char
Max = Len(Str$)
pStr = calloc(Max + 1)
For I = 1 To Max
pStr = Asc(Mid$(Str$, I, 1))
Next I
StrToChar = pStr
End Function
イグトランス
記事: 899 登録日時: 2005年5月31日(火) 17:59
お住まい: 東京都
連絡する:
#9
投稿記事
by イグトランス » 2006年6月07日(水) 23:02
コード: 全て選択
For I = 1 To Max
pStr = Asc(Mid$(Str$, I, 1))
Next I
この部分はもっと簡単に,これだけで済みます。そしてこの場合callocはmallocで置き換えられます。
コード: 全て選択
memcpy(pStr, StrPtr(Str$), Max + 1)
また,callocで確保したメモリはfreeで解放すべきです。
コード: 全て選択
Print MakeStr(x)
End
これを(たとえば)こうします。
コード: 全て選択
Dim pStr As *Char
pStr = x()
Print MakeStr(pStr)
free(pStr)
End
もう1度言いますが,私なら関数xがString型を返すようにします。
こんなfreeしなければならないなんて面倒くささは受け入れられませんから。
NoWest
記事: 264 登録日時: 2005年5月31日(火) 10:52
お住まい: 高知
連絡する:
#10
投稿記事
by NoWest » 2006年6月08日(木) 14:31
私もどうしてポインタを返す関数を作りたいのか知りたいですね。
自分だけで使う関数なら、ポインタを返す関数を作ってもよいと思いますが
他の人に公開するライブラリの一部などであれば勿論のこと
「3日も経てば他人のソース」という格言のように自分でも混乱しかねません。
文字列操作の関数であれば外部から目的の文字列バッファを引数に与えてやるのが
基本だと思います。
こんな感じ [ここをクリックすると内容が表示されます] [ここをクリックすると非表示にします]
コード: 全て選択
#N88BASIC
Dim buf[256] As Char
lstrcpy(buf,"ABABABA")
AtoB(buf)
Print MakeStr(buf)
'アルファベットの大文字Aを大文字Bに置換する関数
FUnction AtoB(lpstr As *Char) As *Char
If lpstr=NULL Then Exit Function
AtoB=lpstr
Dim cnt=0 As DWord
While AtoB[cnt]<>0
If AtoB[cnt]=Asc("A") Then AtoB[cnt]=Asc("B")
cnt++
Wend
End Function
卓漏
記事: 32 登録日時: 2005年11月30日(水) 06:38
お住まい: 静岡県の田舎町
#11
投稿記事
by 卓漏 » 2006年6月08日(木) 19:25
> 私もどうしてポインタを返す関数を作りたいのか知りたいですね。
↑作った理由は、たいした理由では無いです。
昔、研究していた「スパゲッティプログラム」と「プログラム方言」を、もう一度、初めから研究するためです。
konisi
記事: 893 登録日時: 2005年7月25日(月) 13:27
お住まい: 埼玉県東松山市
連絡する:
#12
投稿記事
by konisi » 2006年6月08日(木) 21:29
研究対象がスパゲッティプログラムか。どういうレポート結果になったの?
卓漏
記事: 32 登録日時: 2005年11月30日(水) 06:38
お住まい: 静岡県の田舎町
#13
投稿記事
by 卓漏 » 2006年6月08日(木) 22:50
>研究対象がスパゲッティプログラムか。どういうレポート結果になったの?
↑痛いところを衝かれました。実言うと、レポートとかは残っていません。
昔、「スパゲッティプログラム」を研究していたのですが、仕事で忙しくなり、
挫折したためです。
でも最近、プログラムの「方言」が、「スパゲッティプログラム」を生み出す原因のひとつになっていそうだな・・・・。と思ったので、また一から研究を始めたわけです。
と言うか、レポートとか文学は苦手です。
konisi
記事: 893 登録日時: 2005年7月25日(月) 13:27
お住まい: 埼玉県東松山市
連絡する:
#14
投稿記事
by konisi » 2006年6月09日(金) 23:19
CやJavaを始めとするほとんどの高水準言語にはスパゲッティープログラムの元になるgoto文が用意されてます。
覚えてる限りでは、COBOL(事務処理系)やForTran(科学技術系)等のやつらでgoto文あるいは同等の働きをする文が用意されていたような・・・。
低水準言語なら、アセンブリ言語ならjmpとかマシン語なら0xE9~0xEBと0xFFがgoto文と同じ働きをします。
イグトランス
記事: 899 登録日時: 2005年5月31日(火) 17:59
お住まい: 東京都
連絡する:
#15
投稿記事
by イグトランス » 2006年6月10日(土) 00:49
そんなCとかJavaとか持ち出さなくても,Goto付きのプログラミング言語なら目の前にあるでしょう,Basicが。
そういえば最近めっきりGotoを使う機会がありませんね。それでよいのでしょうけど。
PS 記念すべき400件目の投稿になりました。これからもみなさんよろしくおねがいします。