처음으로 배우는 C 프로그래밍 제2부 기초 제4장 선택문
제 1 절 관계식 관계식: 연산항을 비교하는데 사용되는 수식, 조건이라고도 함 C의 관계연산자 <(~보다 작은) >(~보다 큰) <=(~보다 작거나 같은) >=(~보다 크거나 같은) ==(~과 같은) !=(~과 같지 않은)
제 1 절 관계식 관계식의 값 참일 경우는 1 거짓일 경우는 0 관계연산자는 정수, 부동소수점수, 배정밀도수 뿐만 아니라 문자 데이터형에도 쓰일 수 있음. 문자는 각각 해당되는 ASCII 코드값을 가짐. 논리연산자를 이용하면 좀 더 복잡한 조건을 만들 수 있음, AND, OR, NOT AND 연산자: &&로 표기, 두 수식이 모두 참일 때만 참, age > 40 && sale > 10000 OR 연산자: ||로 표기, 두 수식 중 하나 이상의 수식이 참일 때 참, a ge >= 20 || sale <= 5000 NOT 연산자: !로 표기, 수식이 참이면 거짓, 수식이 거짓이면 참, !(age == 30)
제 1 절 관계식 ==연산자를 사용하여 부동소수점수, 배정밀도수와 변수간의 동등성 검사를 피해야 함 부동소수점수 및 배정밀도수는 0,1의 비트열로 정확히 표현할 수 없음 부동소수점수 및 배정밀도수 동등성 검사시, operand1 == operand2는 fabs(operand1 - operand2) < 0.0001로 대체, 0.0001은 적당한 값으로 대체 가능
제 2 절 if-else 문 비교의 결과를 기초로 다음 명령을 선택 복합문 if (expression) statement1; else statement2; 수식의 값이 0이 아니면 statement1 실행, 0이면 statement2 실행 if (age > 18) printf(“adult\n”); else printf(“child\n”); 복합문 중괄호 {, }로 묶인 여러 개의 문장들, 위 if-else의 statement1, 2는 모두 복합문으로 대치될 수 있다.
제 2 절 if-else 문 단방향 if 문 if-else 문 사용시 주의할 점 if-else 문 중, else 부분이 생략된 if 문 if (expression) statement1; if-else 문 사용시 주의할 점 수식이 무엇을 의미하는지에 대한 잘못된 이해 C 언어의 모든 수식은 값을 갖고 0이 아닌 모든 수식의 값을 참으로 간주한다 관계연산자 ==대신 치환연산자 =를 사용하는 것 치환연산자가 사용된 수식의 값은 변수에 대입되는 값이다 age = 40 수식의 값은 40, 즉 참이다 if (age = 40) statement1; 잘못 표기된 관계연산자에 의해 statement1은 age의 값에 관계없이 항상 실행된다
제 2 절 if-else 문 복합문 내에서 중괄호의 위치 if (expression) { statement1; } else { statement3; statement4;
제 3 절 중첩 if 문 하나 이상의 if-else 문이 또 다른 if-else 문의 if 부분이나 else 부분에 포함된 if 문 마지막 else는 가장 가까운 짝이 없는 if 문과 짝이 된다 if (expression1) if (expression2) statement1; else statement2; 마지막 else는 1번째 if와 짝을 이루는 것처럼 보이지만 2번째 if와 짝을 이룬다. 해결 방법은 아래와 같이 중괄호로 묶는다. if (expression1) { if(expression2) statement1; } else statement2;
제 3 절 중첩 if 문 if-else 체인 if (expression_1) statement_1; ... else if (expression_n) statement_n; else last_statement; 수식들은 차례대로 검사되고 일단 참인 수식을 만나면 그에 해당하는 문장을 실행한 후 체인을 탈출한다.
제 4 절 switch 문 switch 문은 정수 수식의 값과 특정 값을 비교하는 경우 if-else 체인을 대신해서 쓰일 수 있다 switch (expression) { case value_1: statement_1; break; case value_2: statement_2; break; … case vaule_n: statement_n; break; default: statement_m; } expression은 정수 수식, value들은 상수이어야 한다.
제 4 절 switch 문 switch는 switch 문의 시작을 알리고 expression이 평가된 후 그 값이 case 각각의 값과 비교된다. 매치되는 값이 없을 경우 default 이하의 문장들이 실행된다. 문장들을 실행하다 break를 만나면 switch 문을 탈출한다 switch (ch) { case ‘0’: case ‘1’: case ‘2’: case ‘3’: case ‘4’: case ‘5’: case ‘6’: case ‘7’: case ‘8’: case ‘9’: printf(“digit\n”); break; default: printf(“not digit\n”); }
제 5 절 일반적인 프로그래밍 오류 관계 연산자 == 대신에 치환 연산자 = 를 사용하는 것 if (num = 1) printf(“num is 1\n”); else printf(“num is not 1\n”); num의 값에 관계 없이 항상 num is 1을 출력, num = 1 수식의 결과는 num에 할당되는 값이기 때문에 항상 참 if 문이 틀린 선택을 하는 것처럼 보는 것. 즉, if 문의 수식 부분이 틀렸다고 생각하는 것. 실제로는 수식 내에 사용되는 변수의 값이 틀린 경우가 많다. 이 때, 수식 앞에 printf() 함수를 사용하여 변수를 출력해 본다 중괄호 없이 중첩 if 문을 사용하는 것. if와 else가 잘못 짝이 될 수 있다
제 6 절 요약 관계식은 연산항을 비교하는 데 쓰인다. 관계식이 참이면 관계식의 값은 1이고 거짓이면 0이다. 관계 연산자에는 <, >, <=, >=, ==, != 등이 있다 논리 연산자 &&(AND), ||(OR), !(NOT)을 이용하면 좀더 복잡한 관계식을 구성할 수 있다 if-else 문은 수식의 값에 기초하여 2개의 문장 중 하나를 선택한다 if-else 문은 또 다른 if-else 문을 포함할 수 있고 각각의 else는 짝이 없는 가장 가까운 if와 짝을 이룬다
제 6 절 요약 if-else 체인 if (expression_1) statement_1; else if (expression_2) statement_2; … else if (expression_n) statement_n; else statement_m 수식은 차례대로 검사되며 일단 참인 수식을 만나면 그에 해당하는 문장을 수행하고 더 이상 수식을 검사하지 않는다 복합문은 중괄호 {, } 내에 개수에 상관없이 여러 개의 문장들로 구성되고 단일 문장이 요구되는 어느 곳에도 사용될 수 있다
제 6 절 요약 switch 문 switch (expression) { case value_1: statement_1; break; case value_2: statement_2; break; … case value_n: statement_n; break; default: last_statement; } 수식은 정수 수식이어야 하고 vaule들은 상수이어야만 한다. 수식의 값과 일치하는 value를 가진 case 문의 문장들을 수행하며 break 문을 만나면 switch 문을 탈출한다
제 7 절 오류, 시험, 디버깅 컴파일 시 오류와 실행 시 오류 오류 검출 방법 컴파일 시 오류: 컴파일러가 검출하는 오류 실행 시 오류: 프로그램이 실행하는 동안 발생하는 오류 오류 검출 방법 데스크 체킹: 프로그램이 컴파일 되기전에 오류를 검출하는 방법 프로그램 검증과 시험: 프로그램이 실행된 후 오류를 검출하는 방법
제 7 절 오류, 시험, 디버깅 구문 오류와 논리 오류 구문 오류: 문장의 구조 또는 철자의 오류 if (a lt b { pintf(“There are five syntax errors here\n”) printf(“ Can you find tem); } 모두 컴파일러에 의해 검출 논리 오류: 프로그램의 잘못된 논리의 결과로 발생하는 오류 컴파일러에 의해 검출되지 않음 데스크 체킹이나 디버깅이 필요
제 7 절 오류, 시험, 디버깅 시험 그리고 디버깅 완벽한 시험은 모든 문장의 실행 조합을 요구 일부 작은 프로그램에만 이것이 가능 10개의 모듈로 구성되고 각각 5개의 if문을 포함하는 응용프로그램은 각각의 모듈에 대해 2의 5승, 모듈 전체에 대해서는 2의 50승 가지의 문장 조합이 존재하여 시험 불가능 “오류가 없는 프로그램은 없다” 한번의 시험이 오류의 존재를 지적할 수는 있지만 오류가 존재하지 않는다는 것을 말하지 않는다 버그 오류를 말함 오류를 격리시키고 수정하고 검증하는 과정을 디버깅이라한다
제 7 절 오류, 시험, 디버깅 오류를 격리시키는 기교들 오류 예방: 데스크 체킹을 실시함으로써 컴파일되기 전에 많은 오류를 제거할 수 있음 프로그램 추적: 각각의 문장을 손으로 실행 진단적인 printf() 함수의 사용: 의심이 가는 변수들을 선택해 값을 직접 출력해 확인해 본다. 반향 인쇄라고도 함