pjs8927   3년 전

답은 다 정확히 나옵니다

메모리가 넘어가는 건지 중간에 끊기는 부분이 있는 건지 모르겠습니다.

시간도 안넘을 것 같은데 왜 런타임 에러가 뜨는지 알려주세요~.~

dldyddlwl   3년 전

예시]

2

apple

say

=> 런타임에러

우선, 시작하면 left = 0, right = 1, 따라서  i = -1, j = 2가 됩니다. 이 때, (int)(i+j)/2 = 0입니다. 따라서, key_string = string[0] = apple 이겠죠.


추신) while문에서, 논리연산자는 좌측에서 우측으로 진행되므로, a || b && c = (a||b) && c 와 같으므로, 의도하신대로 작동하지 않을 수 있습니다.


1. 첫번째 while

첫번째, while에 의해서 ++i , i=0이 되며 탈출합니다. ( 처음조건 || 2번째 조건 && 세번째 조건 )

처음 조건인 strlen(string[0]) < key_length는 만족하지 않으나 다음 조건인 strlen(string[0]) == key_length가 만족하므로, OR 연산에 의해 true이 됩니다. ( true && 세번째 조건 )

그 후, key_string과 사전순 비교, 두 값이 같으므로, false.   => 따라서, true && false 이므로 false가 되어 탈출.  

2. 두번째 while

두 번째 while에 의해서, --j에 의해, j = 1이 되며 탈출합니다. ( 처음조건 || 2번째 조건 && 3번째 조건 ), string[1] = say

첫 조건인 strlen(string[1])=3 > key_length는 만족하지않고, 다음 조건인 strlen(string[1]) == key_length 조건도 만족하지 않으므로, OR 연산에 의해 false가 됩니다. 

( false && 세번째 조건 ), 세번째 조건을 확인할 필요 없이 AND 연산에 의해 false.  => 따라서, false가 되어 탈출.


3. 그 이후의 과정

string[0]과 string[1]이 서로 교환됩니다. 그리고, 아직 j가 더 크므로, 전체 while을 다시 돌게 됩니다. 

그러고나서, 첫번째 루프로 가서, ++i로, i는 1이 됩니다. 그러면, string[0] = say ,string[1] = apple가 됩니다. 

그런데, key_string은 여전히, string[0]을 가리키므로, key_string = say가 됩니다. 그러나 key_length는 변하지 않았으므로 key_length는 여전히 apple, 5 입니다. 

첫 조건인, strlen(string[1]) < key_length는 는 만족하지 않지만, 다음 조건인 strlen(string[1]) == key_length는 만족하므로, true || false = true

세번째 조건인, 사전순에서, apple은 say보다 앞에 있으므로, true,  => 따라서 true&&true가 되므로, 배열의 인덱스가 넘어갈 때까지 루프가 진행됩니다.

pjs8927   3년 전

답글 감사합니다

답글을 보고도 이해가 가지 않는 부분이 있어서 다시 댓글을 쓰게 되었습니다.

처음조건을 a, 두번째조건을 b, 세번째 조건을 c라고 표현하겠습니다.

' (a || b && c) '이라고 표현하셨습니다.

저는 ' (a|| (b && c)) ' 이렇게 표현했는데 이렇게 안에다가 괄호를 넣어도 없는거랑 같은건가요?

dldyddlwl   3년 전

우선, 대단히 죄송합니다. 귀하신 시간 낭비하게 해서 진심으로 사과드립니다.

말씀하신대로, (a || (b&&c)) 가 맞습니다. 제가 괄호를 못봤습니다. 죄송합니다.

예시]

2
apple
say
=> 런타임에러

우선, 시작하면 left = 0, right = 1, 따라서 i = -1, j = 2가 됩니다.
이 때, (int)(i+j)/2 = 0입니다. 따라서, key_string = string[0] = apple 이겠죠.


1. 첫번째 while

첫번째, while의 조건문에 의해서 ++i , i=0이 됩니다.
처음 조건인 strlen(string[0]) < key_length는 만족하지 않고, strcmp 결과가 0이므로, && 연산에 의해,
최종적으로, false || false 연산이 되고, 그 결과 false가 되어 탈출합니다.

2. 두번째 while

두 번째 while에 의해서, --j에 의해, j = 1이 됩니다.
첫 조건인 strlen(string[1])=3 > key_length는 만족하지않고, false || (&&연산)
다음 조건인 strlen(string[1]) == key_length 조건도 만족하지 않으므로 &&연산에 의해 false가 되어,
false || false 가 나오게 되고, 최종적으로, false가 됩니다.


3. 그 이후의 과정

string[0]과 string[1]이 서로 교환됩니다. 그리고, 아직 j가 더 크므로, 전체 while을 다시 돌게 됩니다.
그러고나서, 첫번째 루프로 가서, ++i로, i는 1이 됩니다. 그러면, string[0] = say, string[1] = apple가 됩니다.
그런데, key_string은 여전히, string[0]을 가리키므로, key_string = say가 됩니다. 그러나 key_length는 변하지 않았으므로 key_length는 여전히 apple, 5 입니다.

4. 다시 while문으로

첫 조건인, strlen(string[1]) < key_length = 5, 따라서, false
다음 조건인 strlen(string[1]) == key_length, 따라서 true , strcmp값은 apple보다 say가 사전순으로 더 뒤에 있으므로, strcmp<0이 되어,
true, 최종적으로 false || (true&&true) 이므로, false || true = true가 되어, while문이 다시 반복됩니다.

그러면, i는 2가 되고, 문제는 char string[20000][55]는 전역변수로 선언되어, 모두 0으로 초기화되어있습니다. 그 말은, 입력받지않은 다음, str[2]부터는, 
strlen 값이 모두 0이 나온다는 뜻이 됩니다. 그렇다면, 첫번째 조건이 true || (&& 연산) 가 되면서
, 무조건 true가 되면서, 루프를 끊임없이 돌다가, i가 계속 증가하여, 
결국 string의 인덱스를 넘어가는 순간 잘못된 인덱스 접근으로 런타임에러가 뜹니다!

pjs8927   3년 전

감사합니다 명확하게 이해시켜주셔서 감사합니다.

댓글을 작성하려면 로그인해야 합니다.