[완료] 파스칼 문법에 관하여
글쓴이: qubick / 작성시간: 일, 2007/10/14 - 10:08오후
요즘 파스칼을 공부하면서 파스칼로 이진트리를 구현해보고 있는데요,
C언어와 비슷하다고 해서 문법이야 별 거 있겠나 싶었는데 쉽지가 않습니다;
일단 메인함수에서 구조체(레코드)를 넘기면 이건 잘 받는 것 같은데
아무래도 포인터 파라메터에 대하여 참조를 못 하는 것 같습니다.
삽입은 잘 되는 것 같은데 막상 삽입함수 Function insert(x:elemnetType; var pHead:treePtr)
안에서 pHead^.Id를 출력하려고 하면 거기서 에러가 나는데요.
아마도 파라메터로 넘겨받은 pHead에 접근을 하지 못 하기 때문이겠죠?
파스칼은 ptr를 선언하면 반드시 new(ptr)을 해 주어야
그 포인터에 대한 공간이 선언된다고 들었습니다.
그런데 함수 인자로 포인터를 넘겨받으면 이건 지역변수잖아요.
지역변수라고 함수 안에서 new(pHead)로 새로운 공간을 할당하고 나면 전달받은 인자는 어쩝니까;
여기저기 인터넷 파스칼 자료를 보면
주소 참조에 대한 포인터는 "var"을 앞에 선언해주면 된다고 들었는데,
이거 문법을 제가 잘못 쓴 건가요, 로직이 잘못된 건가요?
program treeSet; type treePtr = ^elementType; elementType = Record Id : integer; //search key eName : string[10]; Value : integer; pleft : treePtr; //pLeft node ptr pright : treePtr;//pRight node ptr end; var //global variable pHead : treePtr; menu : integer; cont : integer; term : elementType; number : integer; resul : boolean; index : integer; Function insert(x: elementType; var Head: treePtr) : treePtr; //Insert Element var pNode : treePtr; pNewNode : treePtr; pPos : treePtr; begin New(pNode); New(pPos); pNode := Head; while pNode <> nil do begin pPos := pNode; if x.Id < pNode^.Id then begin pNode := pNode^.pleft; end; if x.Id > pNode^.Id then begin pNode := pNode^.pright; end; end; // of while New(pNewNode); //std function malloc() pNewNode^.Id := x.Id; pNewNode^.eName := x.eName; pNewNode^.Value := x.Value; pNewNode^.pleft := nil; pNewNode^.pright := nil; if (pHead <> nil) then insert := Head; if (x.Id < pPos^.Id) then begin pPos^.pleft := pNewNode; end else pPos^.pright := pNewNode; insert := Head; write(x.Id); writeln(' is inserted'); writeln(''); end; //of insert procedure Procedure delete(x: elementType; var pNode: treePtr); //Delete Element var tmpNode : treePtr; begin New(tmpNode); if isMember(x, pNode) = false then begin writeln('This is not a member'); end else begin if pNode^.pleft = nil then begin if pNode^.pright = nil then Dispose(pNode); end else begin if pHead^.pleft <> nil then begin tmpNode := pNode; repeat tmpNode := tmpNode^.pright; until tmpNode = nil; pNode^.Id := tmpNode^.Id; pNode^.eName := tmpNode^.eName; pNode^.Value := tmpNode^.Value; Dispose(tmpNode); end; if pNode^.pright <> nil then begin tmpNode := pNode; repeat tmpNode := tmpNode^.pleft; until tmpNode = nil; pNode^.Id := tmpNode^.Id; pNode^.eName := tmpNode^.eName; pNode^.Value := tmpNode^.Value; Dispose(tmpNode); end; end; write(x.Id); writeln(' is deleted'); end; //of if end; //of delete procedure begin //main pgm //insert, delete, member search, size, init function call New(pHead); pHead := nil; cont := 1; while cont <> 0 do begin writeln('==================================='); writeln(' Menu List '); writeln('==================================='); writeln(' 1. Insert Data '); writeln(' 2. Delete Data '); writeln(' 3. End Program '); writeln('==================================='); write('Select Menu : '); read(menu); case menu of 1 : begin write('Enter Id : '); readln(term.Id); write('Enter Name : '); readln(term.eName); write('Enter Value : '); readln(term.Value); pHead := insert(term, pHead); end; 2 : begin write('Enter Id of term you want to delete : '); read(term.Id); delete(term, pHead); end; 3 : begin writeln('Bye bye!'); cont := 0; end; end; //of case end; //of continue while end. //of main
일단 다른 함수는 다 제거하고 삽입, 삭제 함수 코드만 적었습니다.
Forums:
델마당에 가서
델마당에 가서 질문하시면 1시간 안에 답을 얻으실겁니다.
http://www.delmadang.com/
알고리즘이 잘못되어 있습니다.
insert 함수에서 대입할 노드를 탐색하는 과정을 보시면 종료 조건이 pPos = nil 입니다.
항상 pPos는 nil이 되는 거죠. 함수 parameter 선언에서 var를 사용하시면 C++의 & 선언과
같은 효과를 보게 됩니다. 즉, 참조입니다. Head 값을 바꾸게 되면 참조의 대상이 되는
pHead 값도 동일하게 바뀝니다. 그리고 포인터에 불필요하게 new를 사용하여 메모리를 할
당하지 마시기 바랍니다. Pascal과 C의 포인터는 100% 동일합니다. (일부 함수 포인터의
사용 방법에는 차이가 있습니다만 변수의 경우에는 100% 동일하게 쓸 수 있습니다)
파스칼에서는 비교 이항 연산자가 = 입니다...
C언어에서의 == 연산자가 파스칼에서는 =로 쓰이고,
대신 할당 연산자 = 는 파스칼에서 :=로 쓰입니다.
pPos = nil이라고 해서 항상 pPos가 nil이 되지는 않죠.
문제는 해결했습니다만, 답변이 잘못된 거 같아서요.
완(전)소(용없는)녀
예... 제가 잘못 봤군요.
이항 연산자로 해석한 것이 아니라 pNode와 pPos를 착각했군요.
(저도 Delphi 유저라서 Pascal 문법을 C와 혼동하지는 않습니다)
while pNode <> nil do 부분을 while pPos <> nil로 봤습니다.
아뭏튼 지적 감사합니다.
댓글 달기