100分:把一段c代码转成pascal(100分)

  • 主题发起人 主题发起人 Haw Wang
  • 开始时间 开始时间
H

Haw Wang

Unregistered / Unconfirmed
GUEST, unregistred user!
第一段:
//: NESTED.H-- Nested struct in linked list
#ifndef NESTED_H_
#define NESTED_H_

struct stack {
struct link {
void* data;
link* next;
void initialize(void* Data, link* Next);
} * head;
void initialize ();
void push(void* Data);
void* peek();
void* pop();
void cleanup();
};
#endif //NESTED_H_

第二段:
//: NESTED.CPP -- Linked list with nesting
#include <stdlib.h>
#include <assert.h>
#include "nested.h"

void stack::link::initialize(
void* Data, link* Next) {
data = Data;
next = Next;
}

void stack::initialize() {head = 0;}

void stack::push(void* Data) {
link* newlink = (link*)malloc(sizeof(link));
assert(newlink);
newlink->initialize(Data, head);
head = newlink;
}

void* stack::peek() { return head->data
}

void* stack::pop() {
if(head==0) return 0;
void* result = head->data;
link* oldHead = head;
head = head->next;
free(oldHead);
return result;
}

void stack::cleanup() {
link* cursor = head;
while(head) {
cursor = cursor->next;
free(head->data)
//Assume a malloc!
free(head);
head = cursor;
}
}

我试着想用一个类来实现这个栈,但不成功,想看看各位大虾的高着。

 
unit Stack;

interface

type

TLink = Class
private
FData: Pointer;
FNext: TLink;
public
constructor Create(AData: Pointer
ANext: TLink);
destructor Destroy
override;
property Data: Pointer read FData;
property Next: TLink read FNext;
end;

TStack = Class
private
FHead: TLink;
public
procedure Push(AData: Pointer);
function Peek: Pointer;
function Pop: Pointer;
destructor Destroy
override;
end;

implementation

{ TLink }

constructor TLink.Create(AData: Pointer
ANext: TLink);
begin
FData := AData;
FNext := ANext;
end;

destructor TLink.Destroy;
begin
//在这里释放 FData 所指向的内存块?
//如 Dispose(FData)
但要保证 FData 所指内存块是由 New 分配的
end;

{ TStack }

procedure TStack.Push(AData: Pointer);
begin
FHead := TLink.Create(AData, FHead);
end;

function TStack.Peek: Pointer;
begin
Result := FHead.Data;
end;

function TStack.Pop: Pointer;
var
OldHead: TLink;
begin
if FHead = nil then
begin
Result := nil;
exit;
end;
Result := FHead.Data;
OldHead := FHead;
FHead := FHead.Next;
OldHead.Free;
end;

destructor TStack.Destroy;
var
Cursor: TLink;
begin
Cursor := FHead;
while FHead <> nil do
begin
Cursor := Cursor.Next;
FHead.Free;
FHead := Cursor;
end;
end;

end.

其实 Delphi 中已经有了 TStack 这个类,直接用就行了。
 
写了一段测试代码,结果不对啊。:(
var
tmp: PChar;
begin
for I := 0 to 99 do
begin

tmp := PChar(IntToStr(I));
DStack.Push(tmp);
end;
for I := 0 to 99 do
begin
Memo1.Lines.Add(PChar(DStack.Pop));
end;
end;
 
问题在于你的使用方式不对。
IntToStr 返回 string 类型的字符串,这种字符串是利用引用计数来控制自己的生存期的。
例如,
var
s : string
//s 实际是指针,指向一个内存块,其中包括引用计数字段,和存放实际串
//内容的字段
b: string;
..
s := 'aaaa'
//初始化;s 所指向的字符串的引用计数 = 1
b := s
//s 所指向的字符串的引用计数增1
b := ''
//s 所指向的字符串的引用计数减1
...
当 s 的引用计数为 0 或程序结束时,s 所指向的内存被释放。
你这样 tmp := PChar(IntToStr(I))
强制转换,IntToStr 为它的结果临时分配的字符串
的引用计数并不会增加,执行完这一句之后,该临时字符串就接着被释放掉了,tmp 就指
向了无意义的内存区,所以下面在 memo 中会出现乱码的。
你可以使用Delphi 提供的 contnrs 单元中的 TStack 替换着试试,结果也是乱码。
 
但就算我改成这样,
var
tmp: PChar;
Stack: TStack;
begin
Stack := TStack.Create;
for I := 0 to Memo1.Lines.Count - 1 do
begin
tmp := PChar(Memo1.Lines);
Stack.Push(tmp);
end;
for I := 0 to Memo1.Lines.Count - 1 do
begin
CopyMemory(tmp, Stack.Pop, SizeOf(Stack.Pop^));
Memo2.Lines.Add(tmp);
end;
end;
memo1有101行,第1行是0,第2行是1,如此类推,
结果应该是100,99,98......
但无论是用Delphi的TStack还是用您的,结果都是101行100.
能帮忙看看是什么问题吗?
 
//第一个循环
for i := ...
begin
...
end;
//此时 tmp 指向 Memo1的 Lines[101],内容是 '100';
for I := 0 to Memo1.Lines.Count - 1 do
begin
CopyMemory(tmp, Stack.Pop, SizeOf(Stack.Pop^));
//按 CopyMemory 的参数要求,tmp 是目标地址,而循环中你的 tmp 始终未变,
//Stack.Pop 返回无类型的指针,SizeOf 返回总是 0。CopyMemory 什么都没做。
//另,这一句相当调用了两次 Stack.Pop
Memo2.Lines.Add(tmp)
//因此总是相当于 Add('100');
end;
 
找到问题了:
把第一个循环改成:
var
tmp: PChar;
Stack: TStack

begin
Stack := TDStack.Create;
for I := 0 to Memo1.Lines.Count - 1 do
begin
tmp := AllocMem(Length(Memo1.Lines));
StrCopy(tmp, PChar(Memo1.Lines));
Stack.Push(tmp);
end;
end;
把第2个循环改成这样:
for I := 0 to Memo1.Lines.Count - 1 do
begin
tmp := AllocMem(100)

StrCopy(tmp, PChar(Stack.Pop));
Memo2.Lines.Add(tmp);
end;
end;
就OK了!
谢谢您的耐心指点,明白了许多以前十分模糊的概念。
 

Similar threads

I
回复
0
查看
615
import
I
I
回复
0
查看
632
import
I
I
回复
0
查看
2K
import
I
I
回复
0
查看
3K
import
I
I
回复
0
查看
3K
import
I
后退
顶部