Pascal の初心者用の ..
[2ch|▼Menu]
749:デフォルトの名無しさん
03/11/18 03:17
TurboPascal風のコンソールユニット

URLリンク(www.slis.keio.ac.jp) から
Win32Crt.pas (w32crt03.lzh) を落として、解凍後、Win32Crt.pasを
Libフォルダにコピーする。
古いユニットなので、Delphi6では未定義の識別子 : 'KeyEvent' という
エラーが出るから、KeyEventという文字列を全てEvent.KeyEventに
置き換える。
これで、TurboPascalのCRTユニット風の関数が使えるようになる。
GotoXY, WhereX, WhereYがゼロオリジンなので、互換性を考えれば
ソースをいじったほうがいいかもしれない。


750:749
03/11/18 03:18
とりあえず、簡単なサンプル(Delphi6で確認)。 何かキーを押すと終了する。
program Project2;
{$APPTYPE CONSOLE}
uses
Windows, SysUtils, Win32Crt;
var
  f, b: Integer;
begin
  for b := 0 to 15 do
  begin
    ClrScr;
    for f := 0 to 15 do
    begin
      TextColor(f);
      TextBackground(b);
      gotoXY(f * 2, f);
      Writeln('Test String [', WhereX, ',', WhereY, ']');
      Sleep(1000);
      if KeyPressed then
        Exit
    end
  end
end.

751:デフォルトの名無しさん
03/11/18 23:36
n個の値 a[0] , a[1] , ・・・ , a[n-1] が与えられているとき、
a[i]の順位 r を求めるプログラムを書いてください。
ただし、順位=(自分より大きいものの個数+1)です。

また、プログラム中に使用する名前の型、属性、意味内容を明示し、
実際の実行例もお願いします。

752:デフォルトの名無しさん
03/11/19 00:00
順番に調べればいいんじゃない。
x := 1;
for i := 0 to n-1 do
if a[i] > a[r] then x := x + 1;

753:デフォルトの名無しさん
03/11/19 00:39
>また、プログラム中に使用する名前の型、属性、意味内容を明示し、
>実際の実行例もお願いします。

それくらいは自分で考えた方が良いぞ。属性ってそもそも何?

754:デフォルトの名無しさん
03/11/19 10:04
とても素朴な疑問なんだが。

>n個の値 a[0] , a[1] , ・・・ , a[n-1] が与えられているとき

この「与えられているとき」ってのを見る度に悩むんだな。
サンプルをどうしよう?って。
programなら、入力ルーチンを作るか、ファイルから読み込むか、
constで適当な値を作るか。

procedureやfunctionだけ作るとしても、pascalでは配列を
関数には渡せないよね?
それとも、a[0]...っていうグローバル変数があるものと
してもいいけど、それも美しくないし。

755:デフォルトの名無しさん
03/11/19 11:17
>>754
ポインタで渡せば?

756:デフォルトの名無しさん
03/11/19 11:37
>pascalでは配列を関数には渡せないよね?

いや…渡せるけど
procedure A(B: array[C..D] of Integer); みたいな。
Delphiならprocedure A(B: array of Integer); で範囲はLow/Highで取る。

757:デフォルトの名無しさん
03/11/19 12:46
いや、勘違いだったら失礼。

>>756
そのC..Dが変数でもできたっけ?
>>755
ポインタで渡すのが確実か。確かに。


758:デフォルトの名無しさん
03/11/19 18:31
>>754
渡せるぞ。ちゃんと宣言すれば。以下参照。

Type
  TIntArray = array[LO..HI] of integer;
var
  A : TSomeArray;
procedure DoSomething(B : TIntArray);

として(LOとHIは定数で適当に宣言されているとする)、
  DoSomething(A);
とすればちゃんと呼び出せるぞ。


>>756
手続き宣言の場所で直接配列を宣言すると、処理系に
よっては「違う型と見なされて配列を渡せない」事態にな
る可能性があるぞ。これは実装依存らしいから、絶対大
丈夫だとか絶対ダメだとか言えないのが面倒。


>>757
変数はダメです(処理系によっては大丈夫かも)。標準で
は定数しか受け付けません(というか実行時に大きさが
決まる配列自体が使えないはず)。

759:756
03/11/20 07:38
>>758
いや、私が言いたかったのはオープン配列。
規格はよく知らないけど、ものの教科書では
procedure A(B: array[C..D] of Integer);
で、任意の長さの配列を渡せるらしい。C..Dには実引数の添え字範囲が入る、らしい。
(もっとも、対応しているコンパイラは知らないけどね)
追記しているようにTP系(FreePascal/Delphi)では同じ機能はあっても構文が違う。

760:デフォルトの名無しさん
03/11/20 08:44
たぶん、環境に依存しないやり方としては、>758が
正しいと思う。見て、おぼろに思い出した。
だけど、わざわざ型を指定するのって、面倒なんだよね。


761:デフォルトの名無しさん
03/11/20 18:20
>>759
あー、オープン配列は使ったことがなかったので、完全に
忘れていました。書かれて初めて「そういうのがあったっけ
なぁ」という感じ。

私はオープン配列を使うような場面ではTListを使うので使っ
たことがありません。オープン配列を使わなきゃならないよ
うな手続きなんかも書かないし。

762:デフォルトの名無しさん
03/11/20 22:44
Why Pascal is Not My Favorite Programming Language
URLリンク(www.lysator.liu.se)
誰か Why Pascal is My Favorite Programming Language を書いてください。

763:デフォルトの名無しさん
03/11/21 00:07
>>762
いいじゃん、放っておけば。大体用途の違う言語を
比較して「こっちが好きだ」って書いているような人
にろくなのはいないから。

分かっている人は「その言語はそういう用途には向
かない」とか「そういうことを目的として設計された言
語ではない」と書くと思う。

764:デフォルトの名無しさん
03/11/21 11:38
俺はタイプ量が多くなっても
if (hoge)と括弧を書くよりは
if hoge thenと書くほうが好きだ。

好きなところってそこしか思い浮かばなかった。
嫌いなところばっかり浮かんで来る・・・。

765:デフォルトの名無しさん
03/11/21 12:19
部分範囲型、集合型、配列の関係が好きだ…
C系の言語でこれらの概念を持ってるのがサッパリ無いのはどういうことか

766:デフォルトの名無しさん
03/11/21 14:40
ビットで済ましているんだろ。

767:デフォルトの名無しさん
03/11/22 11:26
お願いします

英単語を入力して、そのつづりを逆順にした文字列を作りなさい。
実行例
    英単語は?  beautiful
    逆順にしたつづりは  lufituaeb

できそうだと思ったんだけど挫折・・・

768:デフォルトの名無しさん
03/11/22 13:48
function ReverseString( S : String ) : string;
var
I, J : Integer;
begin
J:=Length(S);
SetLength( Result, J);
for I:=1 to J do
Result[i]:=S[J+1-I];
end;

実行してないんで動くかどうかはシラネ

769:デフォルトの名無しさん
03/11/22 15:47
program rev;
var st : string; i : integer;

procedure swap(var a, b : char);
var t : char;
begin
  t := a; a := b; b := t;
end;

begin
  readln(st);
  for i := 1 to length(st) div 2 do
    swap(st[i], st[length(st) - i + 1]);
  writeln(st);
end.

こんな感じ?

770:デフォルトの名無しさん
03/11/22 17:51
回すのは、半分くらいでいいのでは?

771:デフォルトの名無しさん
03/11/22 17:52
あっ、半分になってるよね。スレ汚しすまん。

772:デフォルトの名無しさん
03/11/22 18:20
■フォーマット

xx xx xx xx
-- -- -----
A B C

A... アイテムコード
B... 強化パラメータ ( 9C < 0 < 64 )
C... 使用回数 ( 00 01 < E8 03 < 00 00 )
※00 00 : 無制限
これどういういみでつか??

773:デフォルトの名無しさん
03/11/22 19:12
>>768
funciton ReverseString(S : String) : string;
var i : integer;
begin
  for i := length(S) downto 1 do
    result := concat(result, S[i]);
end;

これで良い気がする。

774:768
03/11/23 23:25
ほぉ。concat関数ですか。知りませんでした。
でも
>function Concat(s1 [, s2,..., sn]: string): string;
>説明
>Concat 関数を使うと,任意の数の文字列を結合できます。各パラメータは文字列型の式です。結果はすべての文字列型パラメータ>の結合です。
>次に示すように,正符号演算子(+)を使っても Concat 関数と同じ結果が得られます。
>S := 'ABC' + 'DEF';
>参考正符号演算子の方が Concat よりも処理が速くなります。
正符号演算子では文字列の加算の「度に」文字列分のメモリの確保と開放が行われてる(と思う)ので
前もってメモリを確保してある>>768のほうが速いと思われます。
(文字列が長くなるに従って差は大きくなると思います。
つまり、
速度を求めるなら>>773氏の方法より>>768のほうがよろしいかと。

実際に試してないんで知らないけど。
添字の計算部分の差で負けたりして(w

775:デフォルトの名無しさん
03/11/24 00:19
>>774
うーん、確かに速度的には遅くなるかもしれないけど、
この関数をそんなに頻繁に使うとは思わないので、な
るべく単純な形の方が分かりやすいような気がする。

あと、以下の形にすると、日本語に対応するのも楽。

function ReverseString(S : string) : string;
var


776:775
03/11/24 00:23
途中で書き込んでしまった。

function ReverseString(S : string) : string;
var i : integer;
begin
  for i := 1 to length(S) do
    result := concat(S[i], result);
end;

777:デフォルトの名無しさん
03/11/24 17:04
再帰バージョン

 function reverseString (a: string): string;
 begin
  if length(a) <= 1 then
   reverseString := a
  else
   reverseString := concat(reverseString(omit(a, 1, 1)), a[1]);
 end;

omitは omit(文字列,位置,文字数) で指定した部分を削除した文字列を返す,
THINK Pascal の組み込み関数。

778:デフォルトの名無しさん
03/11/24 18:09
>>775
単純さを求めるとなると手っ取り早い日本語対応は
function ReverseString(S : widestring) : widestring;
では?(w
>>776
>result := concat(S[i], result);
result := S[i] + result;
むしろこちらのほうが単純(直感的)かと。
ただconcat関数に慣れてないだけかも知れんが…

779:デフォルトの名無しさん
03/11/24 18:34
>ただconcat関数に慣れてないだけかも知れんが…

文字列連結に「+」が使える事にかえって驚く。
resultというのもDelphi独自の規格だよね。

780:デフォルトの名無しさん
03/11/24 23:12
>>778
widestringを使うのは環境にだいぶ依存しそう
ですけど(確かに単純と言えば単純だけど)。

concatを使うのはあくまで私のやり方ですので、
+の方が分かりやすければそちらで問題ありま
せん。

781:デフォルトの名無しさん
03/11/25 00:22
>>779
Turbo Pascalからの仕様ですね。

782:デフォルトの名無しさん
03/11/25 08:07
おながいします


正の整数を読み込み、30桁の数になるまでそれを2倍、2倍にしていき、
30桁の数になったら出力する。

桁数ってどうだっけ・・・

783:デフォルトの名無しさん
03/11/25 09:34
program Hoge;
{$APPTYPE CONSOLE}
var bignum : array [1..30] of Integer;
function keta: Integer; var i : Integer; begin
i := 30; while (bignum[i] = 0) and (i > 1) do i := i - 1;
keta := i; end; { keta }
procedure nibai; var i : Integer; begin
for i := 1 to 30 do bignum[i] := bignum[i] * 2;
for i := 1 to 29 do begin
bignum[i+1] := bignum[i+1] + bignum[i] div 10;
bignum[i] := bignum[i] mod 10; end;end; { nibai }
procedure print; var i : Integer; begin
for i := 30 downto 1 do Write(bignum[i]);end; { print }
procedure init; var i : Integer; begin
for i := 2 to 30 do bignum[i] := 0; bignum[1] := 1;end; { init }
begin init; while keta < 30 do nibai; print; end.

784:デフォルトの名無しさん
03/11/25 09:49
procedure init;
var i : Integer;
begin
Read(i);
bignum[1] := i;
for i := 1 to 29 do begin
bignum[i+1] := bignum[i] div 10;
bignum[i] := bignum[i] mod 10;
end;
end; { init }

785:デフォルトの名無しさん
03/11/25 11:46
>>767

program ensyu(input,output);
const msg ='英単語の綴りを逆順にします。';
var engword,downword:string[30];
Len,i :integer;
begin
writeln(msg);
write('英単語は?');
readln(engword);
Len:=length(engword);
for i:=Len downto 1 do
begin
downword:=downword+engword[i];
end;
writeln('逆順にした綴りは',downword,'です。');
readln;
end.





786:デフォルトの名無しさん
03/11/25 12:41
function ReverseString(S: String): String;
var
i, j : integer;
c : char;
begin
i := 1;
j := Length(S);
while i < j do begin
c := S[i];
S[i] := S[j];
S[j] := c;
i := i + 1;
j := j - 1;
end;
ReverseString := S;
end; { ReverseString }

787:デフォルトの名無しさん
03/11/25 13:54
激遅
function ketaketa(e : extended):integer;
begin
while true do begin
e:=e*2;
if log10(e)>=30 then break;
end;
ShowMessage(FloatToStr(e));
end;

788:デフォルトの名無しさん
03/11/25 14:16
procedure ketaketa(e : extended);
begin
while log10(e) < 30-1 do
e:=e*2;
ShowMessage(FloatToStr(e));
end;

789:デフォルトの名無しさん
03/11/25 14:39
procedure ketaketa(e : extended);
var
i : Integer;
begin
for i := 1 to Ceil((30-1 - log10(e)) / log10(2)) do
e := e * 2;
ShowMessage(FloatToStr(e));
end;

790:デフォルトの名無しさん
03/11/25 14:52
procedure ketaketa(e : extended);
begin
ShowMessage(FloatToStr(e * power(2, Ceil((30 - 1 - log10(e)) / log10(2)))));
end;

791:デフォルトの名無しさん
03/11/25 15:14
procedure ketaketa(e : extended);
begin
ShowMessage(FloatToStr(e * power(2, Ceil((30-1)*log2(10) - log2(e)))));
end;

792:デフォルトの名無しさん
03/11/25 16:28
function keta(e : Extended): Integer;
var
n : Integer;
begin
n := 1;
while e >= 10 do begin
n := n + 1;
e := e / 10;
end;
keta := n;
end;

procedure ketaketa(e : extended);
begin
while keta(e) < 30 do
e := e * 2;
ShowMessage(FloatToStr(e));
end;

793:デフォルトの名無しさん
03/11/25 23:30
>>787-792
extendedって30桁まであるのか?

794:782
03/11/26 03:27
いろいろカキコ有難うございます。今日の授業で>>782を以下の.........の部分を埋めて作れと言われました。

program enshu(input,output);
const K=30;
var i,j,m,v, :integer
n :array[1..K]of integer;
begin
write('出発の値は?');
readln(m);
if m >0 then
begin
.............
while m<>0 do
begin
.............
end;
J:=J+1;
・・。

795:782
03/11/26 03:28
while j > 1 do
begin
for i:=K downto J do
n[i]:= 2*n[i];
for i:=K downto J do
begin
...............
end;
if n[i-1]<>0 then j:=j-1
end;
for i:=1 1 to K do
write(chr(n[i]+Ord('0')));
writeln
end;
readln
end.

スマソ全然わかんないです・

796:デフォルトの名無しさん
03/11/26 09:14
program enshu(input,output);
const K= 30;
var i,j,m : integer; {var i,j,m,v, : integer}
n : array[1..K]of integer;
begin
write('出発の値は?');
readln(m);
if m >0 then
begin
j := K;
while m<>0 do
begin
n[j] := m mod 10;
m := m div 10;
j := j - 1;
end;
J:=J+1;

797:デフォルトの名無しさん
03/11/26 09:15
while j > 1 do
begin
for i:=K downto J do
n[i]:= 2*n[i];
for i:=K downto J do
begin
n[i-1] := n[i-1] + n[i] div 10;
n[i] := n[i] mod 10;
end;
if n[j-1]<>0 then j:=j-1 { if n[i-1]<>0 then j:=j-1 }
end;
for i:= 1 to K do { for i:=1 1 to K do }
write(chr(n[i]+Ord('0')));
writeln
end;
readln
end.

798:デフォルトの名無しさん
03/11/26 18:12
URLリンク(do.sakura.ne.jp)
前にあったブラックジャックを作ってみた。
つくりかけだけど。

799:デフォルトの名無しさん
03/11/27 20:00
お願いします。
「・・・」の部分を埋めて作るように言われましたが、全然・・・。

氏名(全角7文字)、数学、英語の得点(100点満点)からなる個人データが保存されているファイルからデータを入力してそれぞれの合計点を計算し、合計点の大きい順に整列して表示するプログラムを作りなさい。

実行例 得点データを合計点順に整列します
データファイル名は? SEISEKI.DAT
氏 名 数学 英語 合計
あああああああ 100 59 159
いいいいいいい 80 80 160
・・・
program seiretu(input,output);
const nmax=100;
type index=1..nmax;
Person=record
name:string[14]
math,eng:0..100;
total:0..200;
end;


800:799
03/11/27 20:01
続きです
Personarray=array[index] of person;
procedure sort(n:index;var x:personarray);
procedure exchangeperson(var A,B:person);

var temp:person;
begin
・・・
end;

var i,j:index;
begin
for i:=1 to N-1 do
for j:=N-1 downto 1 do
・・・
end;

var num:o..nmax;
i:index;
Student:personarray;
Infile:text;
Filename:string[80];
begin
・・・
end.

801:デフォルトの名無しさん
03/11/27 20:25
あのー、少しは自分でやった方がいいと思うよ?
せめて、自分が考えたものを書くとかしたほうが。

802:デフォルトの名無しさん
03/11/27 22:18
コンパイル通しただけだから、バグ取りは自分で
program seiretu(input,output);
const nmax = 100;
type index = 1..nmax;
Person = record
name : string[14];
math,eng : 0..100;
total : 0..200;
end;
Personarray = array[index] of person;
procedure sort(n : index; var x:personarray);
procedure exchangeperson(var A,B : person);
var temp : person;
begin
temp := A; A := B; B := temp;
end;
var i,j: index;
begin
for i:=1 to N-1 do
for j:=N-1 downto i do
if x[j+1].total < x[j].total then
exchangeperson(x[j+1], x[j]);
end;

803:デフォルトの名無しさん
03/11/27 22:19
var num : 0..nmax;
i : index;
Student : personarray;
Infile : text;
Filename : string[80];
begin
Write('データファイル名は?');
Readln(Filename);
i := 1;
Assign(Infile, Filename);
while not eof(Infile) do begin
Readln(Infile, Student[i].name, Student[i].math, Student[i].eng);
i := i + 1;
end;
num := i - 1;
sort(num, Student);
for i := 1 to num do
Writeln(Student[i].name, Student[i].math, Student[i].eng,
Student[i].total);
end.

804:782
03/11/28 11:52
>>796-797
ありがとうございます

805:デフォルトの名無しさん
03/11/28 19:49
>>801
うん、私もそう思う。課題をそのまま丸写ししたのは、無視するか
どこが分からないか聞き直すのが良いと思う。

806:801
03/11/28 23:22
>>805
無視は冷酷なんで。ヒントくらいかな、最初は。

807:デフォルトの名無しさん
03/11/29 09:35
THINK Pascalに詳しい方がおられるようなので、
ちょっとスレ違いだけど、質問。

THINK Pascalで、「アプリケーションはそのままで、
ライブラリで機能拡張するもの」は作れますか?
具体的には、「HyperCardとXCMD/XFCN」や
「フォトショップとプラグイン」
「MacOSと機能拡張やコントロールパネル」
みたいな関係のもの。

できるとしたら、大雑把に言って、どうやるんですか?

808:デフォルトの名無しさん
03/12/01 17:08
>>805
いや、別に何も考えずに教えてくださいといってるわけではないんですよ。
クラスみんなですごく悩みながらやってて、どうしても分からん問題だけ聞いてるんです。
ただ、これからは途中のわかるとこまで書き込むように心がけます。
これは言い訳なんですけど、授業では何もパスカルのこと教えないのにやたら難しい問題ばかり出す先生なので・・・

809:デフォルトの名無しさん
03/12/02 21:44
>>807
出来ないかも。

やり方は多分『(1)コードリソースを作って(2)それをメモリ上に読み込み、(3)それを呼び出す』
という手順でやっているのだと思う。(68Kの場合)

で、3番目の“呼び出し”はC言語なら出来るんだけど
THINK Pascalだとハンドルを関数/手続き扱いしなければならないのでかなり難しいと思う。
(コードリソースの作成はTHINK Pascalでも出来る。)


色々やってみた結果CodeWarrior Pascalで

 fPtr = function (a,b:integer):integer;

こんな感じで関数を型定義してやったらできた。
しかし、これをTHINK Pascalに持ってくると文法違反でコンパイルが通らなかった。

810:809
03/12/02 21:45
CodeWarrior Pascalで実行できたソースコードの例
プラグイン側の関数は2数の和を返す関数。

 type
  fPtr = function (a,b:integer):integer; {←ここがTHINKでNG。型は必要に応じて変える}
  fHdl = ^fPtr;

 var
  plugHdl: fHdl;
  plugin: fPtr;
  c: integer;

 procedure loadPlugin; {とりあえずファイル名、リソースタイプ、IDは決め打ち}
  var
   iFileRef, iErr: integer;
 begin
  iFileRef := OpenResFile('pl1'); {プラグインファイルを開く}
  plugHdl := fHdl(Get1Resource('MyPL', 128)); {メモリ上に読み込み}
  iErr := FSClose(iFileRef);
 end;

begin
   loadPlugin;       {プラグインをファイルから読み込む}
   hlock(handle(plugHdl)); {ハンドルロック}
   plugin := plugHdl^; {一旦ポインタに移し替えないとダメっぽい}
   c := plugin(3,6);  {関数呼び出し。プラグインは2数の和を返す関数}

811:デフォルトの名無しさん
03/12/02 23:03
>>808
どうしても分からん問題だけ聞くのは良いんだけど、こっちは
どうしても分からなん問題かどうかなんて判断付かないし、問
題だけ書かれたら「ただ丸投げしている」と思われても仕方が
ないだろう。

あと、「分かるところまで書き込む」んじゃなくて、「分からない
ところだけ抜き出す」事をしてくれ。元の問題も分からず、ここ
まで分かりましたと書かれても答えようがないし、問題と分かっ
たところを書かれると「こっちが分からないところを探し出す作
業」をしなければならん。

分からないところを抜き出す作業が面倒と言うことはないと思
うが、「分からないところを抜き出す作業をミス」したり、間違っ
て解釈したりするかもしれん。それでお互い時間と数レスを費
やすかもしれないと思うと面倒くさい。

812:デフォルトの名無しさん
03/12/02 23:26
10進法で表現された数を
2進法、8進法、16進法の表現に変換するプログラムを書いてください。
ただし、入力する10進法の数は(16^4)-1=65535までです。
また、実際の実行例もお願いします。

813:デフォルトの名無しさん
03/12/03 00:15
IntToHex
といって見るだけ

814:デフォルトの名無しさん
03/12/03 01:06
>>812
**進法というのは分かっているのか? 分かっているとしたら
どこが分からないんだ? 分からないところだけを聞き直して
くれ。

あと、実行例くらい自分で実行して作ってもいいだろ。おん
ぶにだっこじゃ身につかんぞ。

815:807
03/12/03 08:39
>>809,810
いろいろ試していただいたようで、ありがとうございます。
ハンドルを関数型で確保するのが無理、って事ですね。
仕方ないですね。型にうるさいのは仕様ですから。

型を指定しないで、普通のハンドルなりポインターで確保
して、いきなりそのアドレスをinlineでコールしたら・・・
って思ったけど、それだと変数の受け渡しが出来ませんね。


816:デフォルトの名無しさん
03/12/03 08:41
>>812
今までの課題よりも簡単に思えるけど。


817:デフォルトの名無しさん
03/12/03 12:11
function hoge(n, base: integer): string;
var
x: integer;
s: string;
begin
if (base <> 2) and (base <> 8) and (base <> 16) then
base := 16;
s := '';
repeat
x := n mod base;
if x < 10 then
s := chr(ord('0') + x) + s
else
s := chr(ord('A') + x - 10) + s;
n := n div base;
until n <= 0;
hoge := s;
end;

818:デフォルトの名無しさん
03/12/03 15:25
>実際の実行例もお願いします。
萎え

819:デフォルトの名無しさん
03/12/03 18:13
>>812
またおまえか

820:809
03/12/03 18:39
>>815 (807)
できました!

最初、引数・返り値を同じにしたダミーの関数を作って
その関数を実行時に機械語の絶対ジャンプで上書きするというのをやってみたんですが
デバッガ(Lights Bug)で追うと、きちんと上書きされているにも関わらず
平然と元の関数を実行してるんですね。(失敗)


で、動作をMacs Bugで追ってみたところ、
どうやら関数のアドレスを取得すると
ジャンプテーブルのアドレスが帰ってくるみたいです。
で、普通に関数コールするとジャンプテーブルをショートカットして
元の関数がダイレクトに呼び出されているようです。

そこで関数を引数にした手続きを別に作成し、
そこから関数を呼び出してみたところ、
うまいこと、プラグインの関数が呼び出されました。

[通常の関数コール]→[目的の関数]
[関数、手続きを引数とした関数コール]→[ジャンプテーブル]→[目的の関数]

なお、inline関数の場合、関数のアドレス取得自体が出来ませんでした。(コンパイル時にエラー)
どこかにひとつ、その関数が作られるわけではなく
コードの随所にそのバイト列が単純に埋め込まれるようになっているからだろうと思います。

821:809
03/12/03 18:39
THINK Pascalで出来るコードリソース呼び出し
 type
  funcOverWriteT = record {関数書換用の型}
    opCode: integer;   {JMP命令オペコード用領域}
    operand: longint;  {JMP先絶対アドレス用領域}
   end;
  funcOWPtr = ^funcOverWriteT;
 var
  fp: funcOWPtr; {ダミー関数アドレス保持}
  h: handle;   {プラグインアドレス保持}
  c: integer;

 function dummy_Func (a, b: integer): integer; {ダミー関数。形式はプラグインと合わせる}
 begin
  dummy_Func := 1 + a + b - 3 + 4;
 end;

 procedure Plugin_Caller (function f (a, b: integer): integer); {Plug-in呼び出し用手続き}
 begin
  c := f(3, 6);
 end;

begin
 h := loadPluginManual; {プラグインアドレス取得。>>810の手続きを関数にしたもの}
 hlock(handle(h));    {プラグインのハンドルロック}
 fp := funcOWPtr(@dummy_Func); {ダミー関数のアドレス取得}
 fp^.opCode := $4ef9;   {68KのJMP命令を上書き}
 fp^.operand := ord4(h^); {プラグインの絶対アドレスを上書き。ハンドル→ポインタを忘れずに}
 c := dummy_Func(3, 6); writeln(c); {失敗。ジャンプテーブルを経由しないので元の関数が呼ばれる。}
 Plugin_Caller(dummy_Func); writeln(c); {プラグイン呼び出し成功!!}

822:デフォルトの名無しさん
03/12/03 21:17
>>820,821
なんと!!できましたか!!すばらしい。小生の
知識不足からまだ理解も、再現も出来ていませんが、
希望が持てました。がんばってみます。

823:812
03/12/03 23:29
>>817
ありがとうございました。
実行例もお願いします。

824:デフォルトの名無しさん
03/12/03 23:39
>>823
自分の所で実行してみなよ。
それが実行例。

825:807,815,822
03/12/04 13:10
>>809,810
>>820,821
動きました。
Plugin_Callerを書き換えて変数を渡せるように
しても、ちゃんと動きました。
ありがとうございました。

826:812
03/12/04 18:26
>>817
のプログラムの意味解説をお願いします。

827:デフォルトの名無しさん
03/12/04 18:39
>>826
お前やる気あんの?
全部分からない訳じゃないだろ?
分からないとこを聞けよ。
漠然とした要求をするな

828:デフォルトの名無しさん
03/12/04 19:11
>>817
これでも良さそう

const
  STR16='0123456789ABCDEF';
・・・略
  repeat
    x := n mod base;
    s := concat(STR16[x + 1], s);
    n := n div base;
  until n <= 0;
・・・略

829:デフォルトの名無しさん
03/12/04 19:11
>>826
解説するまでもない明解なプログラムだぞ。>817は。


830:デフォルトの名無しさん
03/12/04 19:12
>>826
意味って>>812のことじゃないの?

831:デフォルトの名無しさん
03/12/04 20:24
10÷2=5...0
5÷2=2...1
2÷2=1...0
1÷2=0...1

10=1010

この意味が分からなければ、
調べ直した方がいい。

832:812
03/12/04 21:38
わからないのは以下の部分です。

>hoge(n, base: ): string;
>s: string;
hoge,n,base,string はどういう意味ですか??

>(base <> 2) and (base <> 8) and (base <> 16)
これはどういう意味ですか。

>base := 16;
>s := '';
>n mod base;
n mod baseとはどういう意味ですか。

>s := chr(ord('0') + x) + s
>s := chr(ord('A') + x - 10) + s;
chr,ordはどういう意味ですか。

>n div base;
これはどういう意味ですか。

>until n <= 0;
>hoge
ここもまるでわかりません

お願いします

833:デフォルトの名無しさん
03/12/04 21:50
>>832
ちっとは、Pascalの教科書を読んでおいでよ。
さすがにそれは、不勉強すぎです。

834:デフォルトの名無しさん
03/12/04 21:51
>>832
ちょいと812さん、mod divが分からないなんて…
ぶっちゃけpascalなんにも知らないと違います?(;´▽`A``

835:812
03/12/04 21:56
>>834
そうなんです。
私は数学科で、pascalは何も知らないんです。
コンピュータの教科書に詳細な説明はないんです。
わかるのは
function,var,integer,if,then,elseといったものぐらいです。
そこであらためて
817の意味解説をお願いします。

836:デフォルトの名無しさん
03/12/04 22:08
>>835
Pascalの教科書を図書館で借りて読め。「分からないから
教えてくれ」というのは先生にしか言っちゃいけない言葉だぞ。

837:デフォルトの名無しさん
03/12/04 22:22
>>835
URLリンク(directory.google.com)

838:817
03/12/04 22:35
hogeは関数名、nは変換する数値、baseは変換の基底、stringは文字列
baseが2,8,16以外だったらbaseを16にしてる。
n mod baseで一の位が分かる。
数値から文字への変換。'0'の次が'1'、'A'の次が'B'
n div baseは整数の割り算。base進数で一の位を削る
0になったら終了。関数の返り値をsにする。

839:デフォルトの名無しさん
03/12/04 22:44
>817さんが親切に>838のような解説を書いても、
>812にはさっぱり意味不明だろう。
pascalの教科書を探して読んで来ない限り、
どこまでいっても全く無駄。

教科書じゃなくても、pascalの初歩のページでも
せめて探して読んできなよ。


840:デフォルトの名無しさん
03/12/04 22:49
たとえば
URLリンク(grape.c.u-tokyo.ac.jp)

841:805
03/12/04 23:30
やっぱり「何も考えずに教えてください」って言っているのと
変わらんな。やっぱり無視した方が良いかも。>>801

842:809
03/12/05 01:03
>825
あ、できましたか。よかったですね。

843:デフォルトの名無しさん
03/12/05 01:20
6ケタの数を入力し、N個右にずらす(たとえばN=2だとすると123456を
を561234)にするにはどのようなプログラムにすればいいですか?

844:デフォルトの名無しさん
03/12/05 01:40
x := x div 10 + (x mod 10) * 100000 をN回繰り返せばいーんでないの

845:デフォルトの名無しさん
03/12/05 04:00
こいつ、課題を全部ここで訊いて済まそうとしているのか?
そんなやつに答える事はないと思うけど。>>ALL

846:デフォルトの名無しさん
03/12/05 10:43
10のN乗を使ってもいいね。

847:デフォルトの名無しさん
03/12/05 10:56
10のn乗だと、桁、大丈夫?

848:デフォルトの名無しさん
03/12/05 12:59
6乗までだから大丈夫でしょう。
function hoge(x, n: integer): integer;
const
k = 1000000;
var
i, j: integer;
begin
x := x mod k;
j := 1;
for i := 1 to n mod 6 do
j := j * 10;
hoge := (x mod j) * (k div j) + x div j
end;

849:デフォルトの名無しさん
03/12/05 19:50
>function,var,integer,if,then,elseといったものぐらいです。
えっ、?
>>hoge(n, base: ): string;
>>s: string;
>hoge,n,base,string はどういう意味ですか??
function分かってるんじゃなかったの?
しかも抜き出し方がおかしすぎだろう
>function hoge(n, base: integer): string;
これで何で分かる「単語」だけを消すかなぁ
>hoge(n, base: ): string;
ここでintegerを抜いて意味が分からないとは・・・レベル高杉(藁
ほんと基本から学んできてね?
というより、分からない単語があったら
まず
せめて
最低限
ヘルプで調べてね?



あかん、、突っ込みどころ大杉
根負けするわ

850:デフォルトの名無しさん
03/12/05 20:03
ひょっとして、質問してる>812は
自分の実行環境を持ってないのか?


851:デフォルトの名無しさん
03/12/05 20:40
winならDelphi
DOSならturbo pascal
macならTHINK Pascal
debianならgpc
linuxならKylix
ぜ〜んぶ無料


852:デフォルトの名無しさん
03/12/05 20:48
空いてる時間は大学のコンピュータにかじりついてでも
コードを書いてコンパイルしてとにかく試せ。

処理系が見つからなくてCへのコンバータ使ってたころもあったなあ。

853:デフォルトの名無しさん
03/12/05 23:19
Pascal入門
URLリンク(www.ics.kagoshima-u.ac.jp)

854:デフォルトの名無しさん
03/12/12 00:28
ほしゅすしゅしゅ(´・ω・`)ショボーン

855:デフォルトの名無しさん
03/12/12 01:48
では、保守ついでに、またもTHINK Pascalの質問。

コードリソースからToolBoxのルーチンを使うには、
コードリソースのプロジェクトに何を入れれば良い?


856:デフォルトの名無しさん
03/12/13 01:05
>>855
・Runtime.libを外してかわりにRSRCRuntime.Libを入れる。
・Interface.libはそのまま。

857:856
03/12/13 01:26
↑はコードリソースを作る時の一般的な手順なんだけど
これでダメって事?

858:デフォルトの名無しさん
03/12/13 07:56
>>856,857
アプリしか作った事が無いので、
その一般的な手順を知らなかった・・・(^^;
あとで試してみます。ありがとう。

859:デフォルトの名無しさん
03/12/23 02:12
ある手続きで、newでメモリーを確保しながら不定の個数の
データを生成するとする。
type
myPtr = ^myList;
myList = record
next: myPtr;
Word: string[255];
end;
のようなリスト形式だから、順番にデータを読みだせる。
disposeも順番にできる。

この手続きをライブラリ化したとして、
disposeをライブラリ外のメインルーチン側に任せるのは
お行儀としてはいかがでしょう? あぶない?
ライブラリに、読み出しやdisposeのルーチンを含める
べきでしょうか?


860:デフォルトの名無しさん
03/12/23 22:31
>>859
使う使わないは別として、一揃いの機能はライブラリにもって
いて欲しいというのが普通じゃないかな。ライブラリ側としては
堅牢に作っておけば、それで問題ないわけだし。あと、リスト追
加(メモリ確保も含む)、削除、ソート、検索なども入れておけば、
わざわざライブラリ外で操作しようと思わないだろうし。

もしリスト形式(というかデータ形式)を「ライブラリ外から隠す」
ようなコンパイラの場合は「ライブラリで処理すべき」だと思い
ます。そうすれば「メモリ保護機能を付け加える」というような
場合でも、インターフェイスさえ変えなければ、同じ感覚で使う
ことが出来ますから。

861:デフォルトの名無しさん
04/01/08 20:49
質問です
A、B、Cに数値が移動していく問題なのですが
A B C
100 0 0
という状態から
A B C
70 30 0

A B C
49 48 3

上記のように
AからBには30%、BからCには10%分ステップごとに移動していくようには
どのようなプログラムを書けばよろしいのでしょうか?
御教授の程よろしくお願いします。


862:デフォルトの名無しさん
04/01/08 20:55
var x, y: integer;
begin
repeat
x = a * 30 div 100;
y = b * 10 div 100;
a = a - x;
b = b + x - y;
c = c + y;
until loop_end;

863:861
04/01/08 21:37
迅速な回答本当にありがとうございました。

重ね重ね失礼を承知の上で2,3お聞きしたいことがあるのですが
上のプログラムではABC3個の値の移動ですが
自分で移動する個数を指定したり(10と入力すればA〜Jまでの数値の移動)
Aから右に数値が移動していくと同時に、Cからある割合で左に数値を返していく
A B C
100 0 0

A B C
70 30 0

A B C
52 39 9
(右へは30%、左へは10%という感じです)

というプログラムはどう書けばよろしいのでしょうか?
よろしければ教えていただけると嬉しいです。

864:デフォルトの名無しさん
04/01/08 22:27
配列かな。
右へ移動する分を蓄えるのと左の分を蓄えるのと用意して計算する。
Pascalで動的確保はどうやるか知らない。

865:デフォルトの名無しさん
04/01/09 02:14
宿題は自分でやりましょう

866:デフォルトの名無しさん
04/01/09 03:00
よくやるのが、値とポインタをセットにした構造体を定義して、
newでメモリーを確保しながら、つないで行く事かな。
これなら、メモリーの許す限り、いくつ増えても大丈夫。
あ、でも、標準のpascalだと、メモリー確保できたかどうかは
検出できないんだっけ。
ただ、最大何個か決まってるなら、配列でそれだけの数を
確保しちゃってある方が、プログラムは簡単だわな。


867:863
04/01/09 09:24
>>864,865,866
アドバイスをどうもありがとうございました。

配列を用いてといているのですが、
『右へ移動する分を蓄えるのと左の分を蓄えるのと用意して計算』
という部分がどう記述していいのかよくわからないのです。
右から戻ってくる値はdowntoを用いて計算すればいいのでしょうか?
また、蓄えた値を足したり引いたりして解を求めるということは
ABC…といった場所の値が常に変化してしまうので
変化した値を常に用いて左右に移動する値を求める
という部分の記述がどうにもわかりません。
どうか御教授の程よろしくお願いします。

868:デフォルトの名無しさん
04/01/09 09:49
自分なりに、出来ているコードを提示してはどうですか?
コードが出てくればどの程度の知識があるのかも予測できるし。



869:デフォルトの名無しさん
04/01/09 11:26
hoge: array [0..1] of array [0..10] of integer;
hoge[0]にa,b,c...が入り
hoge[1]に右からと左からを入れる
最後にhoge[0]に足す。

870:デフォルトの名無しさん
04/01/09 21:14
>>869
わざわざ二次元配列にするより、一次元配列を2つ作った方が
分かりやすいと思うんだけど。

871:デフォルトの名無しさん
04/01/09 21:38
配列を2つ作る必要ってあるのか?

872:デフォルトの名無しさん
04/01/09 21:50
>>871
私に言わせると「わざわざ二次元配列にする必要ってあるのか」
になるんだけど。

値を保存する配列と計算用の配列は分けた方が分かりやすいと
思うんだけど。

873:デフォルトの名無しさん
04/01/09 22:36
ああ。出題の意味を取り違えていた。
配列は2ついるね。失礼。
2次元配列は意味ないね。確かに。

874:デフォルトの名無しさん
04/01/10 02:56
>>867
問題をもう少し整理してくれ。

1. 移動率は場所によって変わるのか? >>861だとA->Bは30%、B->Cは10%になっている。
2. >>863で左右に移動する場合、上記1と左右の移動率の関わりは?
3. 左右端の処理はどうするのか?

あと、移動率は定数か変数のどちらかもはっきりしないし。
ここいらへんがちゃんと定義されていないと、プログラムを書こうにも書けないぞ。

875:861,863,867
04/01/10 09:41
皆様色々とアドバイスをありがとうございます。

>>874
そうでしたすみませんでした。

1は
移動率は場所によって変動です。
2は
移動率なんですが右方向へは(n/50)、左方向へは(n/100)といったようにN番目の場所により移動率が変化。
3は
左端は右隣に移動と右隣からの移動、右端は左隣からの移動と左隣への移動です。

移動率は変数です。


876:デフォルトの名無しさん
04/01/10 09:48
宿題の設問、そのまま書いてくれたほうがわかりやすいんだけどなぁ

877:875
04/01/10 10:12
下のような状態遷移図が書いてあって

 → → →   →
@ A B ・・・ I
 ← ← ←   ←

@に適当な値を与えると
まず@からAに移動、次に@からAに、AからBに、Aから@に、その次は・・・
といった様に数値が移動していく。
また、移動率は右方向には(n/50)、左方向には(n/100)というように、位置Nの値を
用いて設定する。
これにより、各場所での定常値を求めるプログラムを作成しなさい。
というようなことが書いてあります。

878:デフォルトの名無しさん
04/01/10 11:32
ほんとに宿題だったか....

右が n/50, 左が n/100 だと足して1になりませんが、ここはホントはなんてかいてあった?

879:デフォルトの名無しさん
04/01/10 11:53
別に足して1にならなくてもいいんでしょ。
const
N = 10;

var
foo: array [1..N] of integer;

procedure move;
var
i, right, left, temp: integer;
begin
right := foo[1] div 50;
for i := 2 to N do begin
left := foo[i] * i div 100;
foo[i-1] := foo[i-1] - right + left;
temp := right;
right := foo[i] * i div 50;
foo[i] := foo[i] + temp - left;
end;
end;

880:デフォルトの名無しさん
04/01/10 18:57
>>877
「移動率は位置Nの値を用いて設定する」ってのがよく分からない
なぁ。Nは何を表していて、その場所との関係はどうなっているの
かをはっきりさせないとプログラムは組めないと思うんだけど。あと
「右方向には(n/50)」のnって何を表しているの?

あと、数値は実数にするのか? それとも整数で良いのか? もし整
数なら除算の余り部分の処理はどうするのかが問題ですね。

881:877
04/01/10 22:18
>>878,879,880
アドバイスをどうもありがとうございました

>>880
説明が足らず申し訳ありませんでした。
NというのはN番目ということです。
図の@〜Iのことです。
「右方向には(n/50)」、「右方向には(n/100)」のnはNと同じです。
@からAに移動する時は(1/50)、AからBに移動する時は(2/50)、・・・
HからIに移動する時は(9/50)ということです。
数値は実数です。


882:デフォルトの名無しさん
04/01/10 23:51
>>881
なんだ算出可能なら簡単じゃん。私は場所によって特定値
(左右別)になるのかと思って「場所別、左右別の配列」を
用意しなければならないかと思っていました。

で、ここまではっきりすれば簡単に組めるのでは。日本語ア
ルゴリズムだとこんな感じ。

{ 事前に元量配列に量をセットしておく}
for 遷移回数ループ do begin
  計算配列を0クリア
  for 最初の要素から最後の要素まで do begin
    左右の漏れ率計算
    左右の漏れ量、残り量計算
    計算配列に漏れ量と残り量を加える
  end;
  元量配列に計算配列を代入
  {途中結果の出力(遷移回数,元量配列)}
end;
{最終結果出力(元量配列)}

移動する個数を可変にする場合は、配列宣言を大きくセット
しておいてその一部だけを使うとか、動的配列を使う(処理
系が許せば)などの方法があります。

注意点は最初の要素と最後の要素は片方にしか漏れ出さ
ないことです。あとは自分で組めるでしょ。

883:881
04/01/11 10:06
皆様のアドバイスを単に組み合わせただけですが以下のように記述してみました。
type foo=array [1..100] of real;
var data:foo;
i,j,n:integer;
right,left,temp:real;
begin
write('移動する個数は?');
readln(n);
data[1]:=100;
j:=0;
repeat
right:=data[1]/50;
for i:=2 to n do begin
left:=data[i]*i/100;
data[i-1]:=data[i-1]-right+left;
temp:=right;
right:=data[i]*i/50;
data[i]:=data[i]+temp-left
end;
j:=j+1
until j=100;
for i:=1 to n do begin
writeln(i,'番目の定常値は',data[i]:5:3,'です。')
end.

884:883
04/01/12 09:18
上のプログラムを1000回繰り返したときと2000回繰り返したときに
得られた値に変化が見られないのですがなぜなのでしょうか?

また、左右に移動する確率をrandomを用いて得ようと思い
簡単なプログラムでどのような乱数が返ってくるのかを
試したところ毎回同じ値しか帰ってこないのはなぜなのでしょうか?



885:デフォルトの名無しさん
04/01/12 09:52
それが定常値

886:883
04/01/12 10:17
やっぱり定常値なんですね。
もっと果てしない回数を繰り返して得られるものだと思っていたので…

type x=array [1..5] of real;
var data:x;
a,n:integer;
begin
for n:=1 to 5 do
data[n]:=random;
for n:=1 to 5 do
writeln(data[n])
end.
こんなプログラムでいつも同じ乱数しか返ってこないのですが
違う乱数を得るにはどうしたらいいんでしょうか?

887:デフォルトの名無しさん
04/01/12 10:30
Randomと一緒にRandomizeを説明してない教科書は窓からポイ

888:883
04/01/12 10:45
窓から ・⌒ヾ(*´_`)ポイしてきました
ありがとうございました

889:883
04/01/12 12:33
883で書いたプログラムは
待ち行列と考えると
右に移動していく値は人の到着の確率
左に移動していく値はサービスをうけ列を離れていく確率
になるのではないかと思うのですがどうでしょうか?


890:883
04/01/12 15:47
type foo=array [1..100] of real;
var data:foo;
i,j,n,k,m:integer;
right,left,temp:real;
begin
write('行列の全人数は?');
readln(n);
write('何ステップ?');
readln(k);
write('窓口の数は?');
readln(m);
{初期値の設定}
data[1]:=1;
j:=0;
repeat
{最初に人がが到着する確率}
right:=data[1]*・・・;
{移動}
for i:=2 to n do begin
{窓口でのサービス提供}
if i<=m then begin
{サービス終了率}
left:=data[i]*・・・;
data[i-1]:=data[i-1]-right+left;
temp:=right;
right:=data[i]*・・・;
data[i]:=data[i]+temp-left
end


891:883
04/01/12 15:48
{待ち行列}
else begin
{途中放棄率?}
left:=data[i]*・・・;
data[i-1]:=data[i-1]-right+left;
temp:=right;
right:=data[i]*・・・;
data[i]:=data[i]+temp-left
end;
end
j:=j+1
{決められたステップ数まで}
until j=k;
for i:=1 to n do
writeln(i,'番目の定常値は',data[i]:5:10,'です。')
end.
待ち行列に用いて行列の定常値を求めるには
こんな感じにすればいいんでしょうか?



次ページ
最新レス表示
スレッドの検索
類似スレ一覧
話題のニュース
おまかせリスト
▼オプションを表示
暇つぶし2ch

5388日前に更新/272 KB
担当:undef