[완료] 파스칼 문법에 관하여

qubick의 이미지

요즘 파스칼을 공부하면서 파스칼로 이진트리를 구현해보고 있는데요,
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

일단 다른 함수는 다 제거하고 삽입, 삭제 함수 코드만 적었습니다.

익명 사용자의 이미지

델마당에 가서 질문하시면 1시간 안에 답을 얻으실겁니다.

http://www.delmadang.com/

익명 사용자의 이미지

insert 함수에서 대입할 노드를 탐색하는 과정을 보시면 종료 조건이 pPos = nil 입니다.
항상 pPos는 nil이 되는 거죠. 함수 parameter 선언에서 var를 사용하시면 C++의 & 선언과
같은 효과를 보게 됩니다. 즉, 참조입니다. Head 값을 바꾸게 되면 참조의 대상이 되는
pHead 값도 동일하게 바뀝니다. 그리고 포인터에 불필요하게 new를 사용하여 메모리를 할
당하지 마시기 바랍니다. Pascal과 C의 포인터는 100% 동일합니다. (일부 함수 포인터의
사용 방법에는 차이가 있습니다만 변수의 경우에는 100% 동일하게 쓸 수 있습니다)

qubick의 이미지

C언어에서의 == 연산자가 파스칼에서는 =로 쓰이고,
대신 할당 연산자 = 는 파스칼에서 :=로 쓰입니다.

pPos = nil이라고 해서 항상 pPos가 nil이 되지는 않죠.

문제는 해결했습니다만, 답변이 잘못된 거 같아서요.

완(전)소(용없는)녀

익명 사용자의 이미지

이항 연산자로 해석한 것이 아니라 pNode와 pPos를 착각했군요.
(저도 Delphi 유저라서 Pascal 문법을 C와 혼동하지는 않습니다)
while pNode <> nil do 부분을 while pPos <> nil로 봤습니다.
아뭏튼 지적 감사합니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.