OS

[OS] C언어 코드 분석_3

효진인데요 2023. 12. 18. 15:24

 

 

작년, 그러니까 3학년 2학기에 운영체제 강의를 들으며 주어졌던 C code 분석 과제를 다시 한번 정리해보려고 한다.

 

C 언어로 작성된 코드를 주고 이를 분석하는 과제였는데, C 언어를 한 번도 사용해 본 적 없을 때라 (사실 현재까지도) 어려웠지만 흥미로웠던 기억이 있었다.

 

C 언어를 배우기 전이기도 하고, 구조에 대해 이해하고 코드를 분석해 보는 데에 의의를 둔 것이기에,

분석하고 정리한 내용이 정확하지 않을 수도 있는 점,,🙏🏻

 

 

https://jinnycoding.tistory.com/77

 

[OS] C언어 코드 분석_2

작년, 그러니까 3학년 2학기에 운영체제 강의를 들으며 주어졌던 C code 분석 과제를 다시 한번 정리해보려고 한다. C 언어로 작성된 코드를 주고 이를 분석하는 과제였는데, C 언어를 한 번도 사용

jinnycoding.tistory.com

 

위 포스팅이 2탄이고 이번 포스팅에도 2탄과 같이 코드 분석이 주 내용이 될 것 같다.

 

 

나도 이해하기 쉽도록 대부분 주석으로 간단하게 설명을 적어가며 최대한 정확하게 분석하려고 노력 많이 했었다...^^

 

 

 

 

 

이전 포스팅에서 begin이나 end를 찾고 있었는데, 둘 다 찾지 못했을 3번째 경우인 else 문이다.

 

두 가지 함수를 간단하게 파악해봤다.

 

 

 

1.1 strtok 함수

strtok 함수 원형

 

 

strtok 함수는 stringtokenize한다는 의미로 문자열을 토큰처럼 자르는 함수이다.

위 사진과 같이 앞에 받은 문자열을 뒤의 구분자를 기준으로 자른다.

 

분석하려는 함수를 보면 line 문자열을 공백을 기준으로 잘라서 firstword라는 변수에 할당할 것으로 볼 수 있다.

 

 

 

 

1.2 atoi 함수

atoi 함수 원형

 

 

atoi 함수는 문자형 string을 정수 값으로 변환하는 역할을 한다.

입력 받는 string은 지정된 유형으로 리턴 유형의 숫자 값으로 해석이 되어야 하며, 인지할 수 없는 첫 번째 문자에서 입력 스트링을 읽는 행위를 중지한다.

 

 

 

 

다시 코드로 돌아가서 분석을 해보았다.

 

  1. 첫 번째 if문을 보면 잘라진 문자열 중 int와 같은 단어가 있는지 확인한다. int라는 단어를 찾으면 if문 내부로 진입해 tempNode의 type 1로 설정한다.

  2. strtok의 첫번째 인자가 NULL일 경우, 이전에 구분자를 찾았던 그 문자열의 주소에서 다시 탐색을 시작해달라는 의미이다. 그 동안 tempNode exp_data에 찾은 firstword 단어를 저장한다.

  3. 만약 탐색을 진행하다가 =라는 문자열을 찾으면 atoi함수를 이용해 문자열 =이 저장된 firstword를 정수 타입으로 바꾼다. tempNode의 line 0번째로 설정한 뒤 stack Push해서 찾은 정보를 저장한다.

 

 


 

 

 

 

 

 

다음으로는 잘린 문자열을 찾던 도중 function이라는 문자열을 찾은 경우 사용하는 함수이다.

 

 

  1. tempNode type 2로 전환한 뒤, strtok의 첫번째 인자로 NULL을 주어 탐색을 진행하도록 한다. tempNode exp_data에는 firstword 리스트의 0번째 데이터를, line에는 curLine을 넣는다. val 0으로 설정하고 위 정보를 Push로 저장한다.
  2. 만약 문자열 배열 [0], [1], [2], [3] 이 차례대로 m, a, i, n이면 foundMain의 상태를 1로 바꾼다.

  3. m, a, i, n을 찾지 못한 경우, else문 내부의 if문으로 들어가 문자열을 찾는 상태로 둔다. tempNode type 1로 전환한 뒤, tempNode exp_data에는 firstword 리스트의 0번째 데이터를, val에는 CalingFunctionArgVal을 넣는다. line에는 0을 넣고 위 정보를 Push로 저장한다.

 


 

 

 

 

마지막으로 firstword[0]‘(‘ 문자인 경우이다.

우선 정수형 변수 i y를 선언하고 초기 값을 0으로 잡는다.

MainStacktop NULL을 가리켜 초기화 시킨다.

 

앞으로 나오게 되는 if문이 상당히 긴 탓에 전체 else if문의 코드와 if문의 코드 안에 존재하는 while문을 압축시켜 while문의 구조를 먼저 나누어 두었다.

 

  1. 앞서 상위 코드에서 strcpy 함수를 사용하여 line lineyedek으로 문자열을 복사해 두었음을 알고 있어야한다.
  2. lineyedek의 리스트 값이 ‘\0’이 아니면 while 반복문을 실행한다.

  3. 위 코드를 보면 알 수 있듯이 while문 내부에는 다섯개의 if 문이 존재한다. 연산자나 알파벳, 기호 등을 각각 저장하는 용도이며, 더 자세한 설명은 다음 과정을 통해 진행하려고 한다. 가장 밑 줄에는 i++을 통해 while문을 돌리고 있다.

 


 

 

 

 1, 2, 3번 함수를 설명하기 전 내부에서 사용되는 함수에 대한 설명을 먼저 보려고 한다.

 

 

2.1 isdigit 함수 원형

isdigit 함수 원형

 

먼저 isdigit 함수는 위와 같은 모양으로 정의할 수 있다.

해당 함수는 매개변수로 char형을 입력하게 되면, 입력한 char형이 숫자에 해당하는 ASCII 코드의 값이 맞는지 아닌지 판별하게 된다.

 

입력으로 char을 받지만 원형함수의 매개변수가 정수인 이유는 입력한 문자가 ASCII 코드의 번호로 들어가기 때문이다.

0부터 9에 해당하는 10진수 숫자로 변경이 되어 들어오면 0이 아닌 값이, 숫자가 들어오지 않으면 0을 반환한다.

 

 

 

2.2  isStackEmpty 함수

isStackEmpty 함수

 

 

isStackEmpty 함수는 스택이 비어 있는지 아닌지 확인하며 int형 리턴 값을 가지는 함수이다.

stck의 최상단이 0이면 1을 리턴하고 아닌 경우 0을 리턴 한다.

 

 

 

2.3 PushOp 함수

PushOp 함수

 

다음으로 PushOp 함수이다.

매개변수로 문자형 op와 스택을 받는다.

opNodenewnode라는 포인터 변수에 저장한다.

newnodeopNode 타입 노드의 사이즈만큼의 메모리 할당이 안되면 메모리 할당에 실패했다는 오류 메시지와 함께 함수를 빠져나간다.

 

할당이 성공할 경우, opnewnode가 가리키고 있는 문자열 op을 가리키고 newnode의 다음 노드는 opstcktop 스택을 가리킨다.

 

newnode opstcktop을 가리키고 opstck에 할당한 메모리의 주소를 리턴 한다.

 

 

PushOp 과정 시각화

 

처음에 분석할 때 과정이 이해가 잘 가지 않아서 직접 그려보며 이해하려고 노력했다.

 

 

 

2.4 PopOp 함수

 

PopOp 함수

 

PopOp 함수는 OpStack opstck이라는 변수에 주소를 저장하고, opNode형 자료 주소를 temp라는 변수에 저장한다.

문자형 변수 op를 생성하고, 만약 스택의 topNULL이면 스택이 비어 있는 상태임을 알리는 에러 메시지를 띄운 뒤 리턴 값이 없이 함수를 종료한다.

 

비어 있지 않은 경우, op opstcktop에 있는 op가 가리키는 값이 되고, temp opstck에 있는 top이 가리키는 값이다.

opstcktop은 그 다음 opNode를 가리키도록 변경되었고, 임시로 값을 가리키고 있던 temp 변수에 할당되었던 메모리의 공간을 해제해준다.

그리고 리턴 값 op를 넘긴다.

 

PopOp 과정 시각화

 

 

 

함수로 돌아가 먼저 상단 3개의 if, else if 문을 분석해보겠다.

 

 

  1. isdigit 함수를 사용해 lineyedek[i] 10진수 숫자로 변경이 가능한지 확인한다. 
    가능하면 postfix y번지에 lineyedek i번지를 복사해서 넣고, y 1씩 더해가며 반복한다.

  2. 만약 lineyedek[i] (라는 문자이면 앞서 설명한 PushOp 함수를 사용하여 스택에 추가한다.

  3. 2번째 else if문과 비슷하게 진행되는 해당 else if문은 lineyedek[i] )라는 문자이면 MathStack이 빈 자리가 있는지 확인하고, 빈 자리가 없는 경우 postfix y번지에 있는 문자를 PopOp 함수를 사용하여 삭제한다.

 

 

 

728x90