학습목표

  • for 루프
  • 증가 연산자와 감소 연산자(++--)
  • 복합 구문(블록)
  • 관계 연산자(>, >=, ==, <=, <, !=)
  • typedef 기능
  • 문자 입력 메서드 get()
  • 중첩 루프와 2차원 배열
  • 표현식과 구문
  • 조합 대입 연산자
  • 콤마 연산자
  • while 루프
  • do while 루프
  • 파일 끝 조건

5.1 for 루프

// forloop.cpp

#include <iostream>

int main()
{
	using namespace std;
	int i;

	for (i = 0; i < 5; i++)
		cout << "C가 루프를 사용합니다.\n";
	cout << "루프를 언제 끝내야하는지 C++은 알고있습니다.\n";
	return 0;
}

for 루프 : 반복적인 작업 처리
루프 초기화(loop initialization) / 루프 몸체(loop body) / 루프 갱신(loop update) 으로 이루어져있음
C++에서는 일반적으로 for과 같은 제어 구문과 괄호 사이에는 공백을 넣고, 함수 이름과 괄호 사이에는 넣지 않음

++ : 증가 연산자(increment operator), 피연산자의 값을 1만큼 증가시킴

for 루프의 각 부분

for (initialization; test=expression; update-expression)
	body
  1. 조건 검사에 사용할 카운터 값을 초기화
  2. 루프를 진행할 것인지 조건을 검사
  3. 루프 몸체를 수행
  4. 카운터 값을 갱신

몸체 안에 여러 구문이 사용되었을 때에도 for 루프 전체를 하나의 구문으로 간주

  • 초기화는 처음에 한번만 수행, 일반적으로 변수에 시작값을 설정함
  • 조건식은 일반적으로 두 값을 비교하는 관계식을 사용하며, 참 거짓 관계식 등 어떠한 표현식도 사용할 수 있음
  • 조건식이 참이면 루프 진행, 거짓이면 루프 종료
// num_test.cpp

#include <iostream>

int main()
{
	using namespace std;

	cout << "카운트 시작값을 입력하십시오 : ";
	int limit;
	cin >> limit;
	int i;
	for (i = limit; i; i--)
		cout << "i = " << i << endl;
	cout << "i = " << i << "이므로 루프를 종료합니다.\n";
	return 0;
}

C++에는 bool형이 있기 때문에 조건식이 참이면 true, 거짓이면 false로 평가되며 이는 정수값 요구시 각각 1과 0으로 변환됨
반대로 bool형 값이 요구될 때는 0이 false로, 0이 아닌 수들은 true로 변환됨
for 루프는 진입 조건(entry-condition) 루프이기 때문에 조건을 먼저 검사하고, 통과시에만 루프 몸체를 수행함
update-expression은 루프 몸체가 수행되고 난 후인 각 루프 주기의 끝에서 평가되며, 어떠한 표현식도 사용할 수 있음

// express.cpp

#include <iostream>

int main()
{
	using namespace std;
	int x;

	cout << "대입 표현식 x = 100의 값은 ";
	cout << (x = 100) << endl;
	cout << "현재 x의 값은 " << x << endl;
	cout << "관계 표현식 x < 3의 정수값은 ";
	cout << (x < 3) << endl;
	cout << "관계 표현식 x > 3의 정수값은 ";
	cout << (x > 3) << endl;

	cout.setf(ios_base::boolalpha);
	cout << "관계 표현식 x < 3의 bool값은 ";
	cout << (x < 3) << endl;
	cout << "관계 표현식 x > 3의 bool값은 ";
	cout << (x > 3) << endl;
	return 0;
}

x = 100이라는 표현식을 평가하기 위해 x에는 100이 대입되어 메모리에 있는 데이터 값을 부수적으로 변경하는 부수 효과(side effect)가 발생함
모든 표현식에 세미콜론을 붙여 구문으로 만들 수 있음
단, 아무런 의미가 없을 수 있으며 역은 성립하지 않음

C++에서는 for (int i = 0; i < 5; i++)과 같이 for루프의 초기화 부분에서 변수를 선언하고 초기화할 수 있음
이 때의 변수는 for 구문 안에서만 존재하게되며, for 루프를 벗어날시 소멸됨
단, 시스템에 따라 구식 규칙을 따를 경우 해당 변수를 루프 앞에서 선언된 것으로 인식하여 삭제하지 않을 가능성이 있음


for 루프에 대한 보충

// formore.cpp

#include <iostream>
const int ArSize = 16;

int main()
{
	long long factorials[ArSize];
	factorials[1] = factorials[0] = 1LL;
	for (int i = 2; i < ArSize; i++)
		factorials[i] = i * factorials[i-1];
	for (int i = 0; i < ArSize; i++)
		std::cout << i << "! = " << factorials[i] << std::endl;
	return 0;
}

배열의 원소 개수를 const 값으로 정의하는 것이 좋은 습관임
외부 상수로 선언되면 프로그램이 실행되는 동안에 계속 존재하기 때문에 프로그램의 모든 함수가 해당 상수를 사용할 수 있음


갱신 크기 변경

// bigstep.cpp

#include <iostream>

int main()
{
	using std::cout;
	using std::cin;
	using std::endl;
	
	cout << "정수를 하나 입력하십시오 : ";
	int by;
	cin >> by;
	cout << "갱신 크기 " << by << "s:\n";
	for (int i = 0; i < 100; i = i + by)
		cout << i << endl;
	return 0;
}

갱신 표현식을 변경하면 루프 카운터가 갱신되는 크기를 바꿀 수 있음
갱신 표현식에는 어떠한 표현식도 사용 가능함


for 루프를 사용한 문자열 처리

// forstrl.cpp

#include <iostream>
#include <string>

int main()
{
	using namespace std;
	cout << "단어 하나를 입력하십시오 : ";
	string word;
	cin >> word;

	for (int i = word.size() - 1; i >= 0; i--)
		cout << word[i];
	cout << "\n종료.\n";
	return 0;
}

string클래스의 size()메서드로 문자열을 구성하는 문자 수를 구하고, 이를 초기화 표현식에 사용함
인덱스에 해당하는 i가 NULL 문자 전을 가리키도록 하고, 인덱스를 하나식 줄여가며 출력


증가 연산자(++)와 감소 연산자(--)

// plus_one.cpp

#include <iostream>

int main()
{
	using std::cout;
	int a = 20;
	int b = 20;

	cout << "a   = " << a << " :   b = " << b << "\n";
	cout << "a++ = " << a++ << " : ++b = " << ++b << "\n";
	cout << "a   = " << a << " :   b = " << b << "\n";
	return 0;
}

접두어(prefix) 방식 : 피연산자 앞에 사용, 적용되는 시점이 표현식의 값을 평가하기 전임
접미어(postfix) 방식 : 피연산자 뒤에 사용, 적용되는 시점이 표현식의 값을 평가한 후임

내장 데이터형에 대해서는 두 방식의 효율 차이가 거의 없음
사용자 정의 데이터형에 대해서는 복사본을 만드는 접미어 방식보다 접두어 방식이 좀 더 효율적


부수 효과와 시퀀스 포인트

시퀀스 포인트 : 프로그램의 실행이 다음 단계로 넘어가기 전에 모든 부수 효과들이 확실하게 평가되는 포인트

  • C++에서 구문에 있는 세미콜론이 시퀀스 포인트를 표시
  • 따라서 연산자에 의해 일어나는 모든 변화는 다음 구문으로 넘어가기 전에 반드시 일어나야 함
  • 몇몇 연산자들도 시퀀스 포인트를 가지며, 완전 수식(더 커다란 수식의 부분이 아닌 수식)의 끝도 시퀀스 포인트임
    • while (guests++ < 10)에서 guests++ < 10은 완전수식으로 조건 확인 후 guests가 증가됨
    • y = (4 + x++) + (6 + x++);에서 4 + x++6 + x++은 완전 수식이 아니므로 해당 구문이 시퀀스 포인트를 만나기 전에는 x의 증가가 보장되지 않음

증가/감소 연산자와 포인터

증감 연산자는 포인터에도 사용 가능
포인터에 사용할 시 포인터가 지시하는 데이터형의 바이트 수만큼 값을 증가시킴

접두형 증감과 내용 참조 연산자는 우선순위가 같으며 오른쪽에서 왼쪽으로 결합

  • *++pt의 경우 ++pt가 먼저 적용된 후 pt의 새로운 값에 *가 적용됨
  • ++*pt의 경우 *pt로 값을 먼저 참조한 후 해당 값이 ++에 의해 증가됨

접미형 증감은 우선순위가 같으며 접미어보다 우선순위가 높음

  • *pt++의 경우 pt++이 먼저 적용된 후 pt의 새로운 값에 *가 적용됨

조합 대입 연산자

조합 대입 연산자 : 산술 연산과 대입 기능이 하나로 결합된 연산자
두 피연산자를 산술 연산한 후, 그 결과를 왼쪽 피연산자에 대입함
이때 왼쪽 피연산자는 실제로 값을 대입할 수 있는 것이여야 함
+= / -= / *= / /= / %=


복합 구문 또는 블록

// block.cpp

#include <iostream>

int main()
{
	using namespace std;
	cout << "값 5개의 합계와 평균을 구합니다.\n";
	cout << "값 5개를 입력하십시오.\n";
	double number;
	double sum = 0.0;
	for (int i = 1; i <= 5; i++)
	{
		cout << "값 " << i << " : ";
		cin >> number;
		sum += number;
	}
	cout << "값 5개가 모두 입력되었습니다.\n";
	cout << "입력한 값 5개의 합계는 " << sum << "입니다.\n";
	cout << "입력한 값 5개의 평균은 " << sum / 5 << "입니다.\n";
	cout << "감사합니다.\n";
	return 0;
}

한 쌍의 중괄호를 사용한 복합 구문(compound statement) 또는 블록(block)으로 루프 몸체 안에서 여러 개의 구문을 사용할 수 있음 블록은 중괄호와 그 안에 포함된 구문들로 구성되며, 모두 합해 하나의 구문으로 간주됨
블록 안에서 정의된 변수는 해당 블록의 구문들을 실행하는 동안에만 존재하여 그 블록 안에서만 사용할 수 있음
블록 안에서 블록 밖에있는 변수와 같은 이름의 변수를 선언했을 경우 해당 블록의 끝에 도달할때 까지만 변수가 덮어씌워짐


콤마 연산자

// forstr2.cpp

#include <iostream>
#include <string>

int main()
{
	using namespace std;
	cout << "단어를 하나 입력하십시오 : ";
	string word;
	cin >> word;

	char temp;
	int i, j;
	for (j = 0, i = word.size() - 1; j < i; --i, ++j)
	{
		temp = word[i];
		word[i] = word[j];
		word[j] = temp;
	}
	cout << word << "\n종료.\n";
	return 0;
}

콤마 연산자를 사용하여 여러 개의 표현식을 하나의 표현식으로 간주할 수 있음

  • 콤마 연산자를 사용할 경우 첫 번째 표현식이 먼저 평가된 후 그 다음 표현식을 평가함
  • 두 번째 표현식이 콤마 표현식 전체의 값이 됨
  • 연산자 중에서 우선순위가 가장 낮음

관계 표현식

C++는 수를 비교할 수 있는 6개의 관계 연산자(relational operator)를 제공 < / <= / == / > / >= /!=

  • 문자도 ASCII 코드로 구현되므로 관계 연산자를 적용할 수 있음
    단, C 스타일의 문자열에는 사용할 수 없으며 string 클래스 객체에는 사용할 수 있음
  • 관계 표현식은 비교 결과에 따라 참이면 ture, 거짓이면 false가 됨
  • 관계 연산자는 산술 연산자보다 우선순위가 낮음
// equal.cpp

#include <iostream>

int main()
{
	using namespace std;
	int quizscores[10] =
		{ 20, 20, 20, 20, 20, 19, 20, 18, 20, 20 };
	cout << "올바른 방법 : \n";
	int i;
	for (i = 0; quizscores[i] == 20; i++)
		cout << i << "번 퀴즈의 점수는 20입니다.\n";
	cout << "잘못된 방법 : \n";
	for (i = 0; quizscores[i] = 20; i++)
		cout << i << "번 퀴즈의 점수는 20입니다.\n";
	return 0;
}

위 코드의 실행 결과 segmentation fault가 발생
===는 다름에 유의해야함


C 스타일 문자열 비교

// compstr1.cpp

#include <iostream>
#include <cstring>

int main()
{
	using namespace std;
	char word[5] = "?ate";

	for (char ch = 'a'; strcmp(word, "mate"); ch++)
	{
		cout << word << endl;
		word[0] = ch;
	}
	cout << "루프가 끝난 후에 단어는 " << word << "입니다.\n";
	return 0;
}

strcmp() : 매개변수로 두개 문자열의 주소를 취함

  • 두 개 문자열이 같으면 0을 리턴
  • 시스템 조회 순서(system collating sequenc)로 보았을 때 첫번째 문자열이 두번째 문자열보다 앞에 오면 음수를 리턴하고, 그 반대이면 양수를 리턴
  • NULL 문자까지만 비교하기 때문에 서로 크기가 다른 배열이라도 상관 없음

string 클래스 문자열 비교

// compstr2.cpp

#include <iostream>
#include <string>

int main()
{
	using namespace std;
	string word = "?ate";

	for (char ch = 'a'; word != "mate"; ch++)
	{
		cout << word << endl;
		word[0] = ch;
	}
	cout << "루프가 끝난 후에 단어는 " << word << "입니다.\n";
	return 0;
}

클래스 설계는 문자열 비교에 관계 연산자를 사용하는 것을 허용
이는 연산자들을 오버로딩 또는 재정의하는 클래스 함수를 정의할 수 있기 때문



5.2 while 루프

while (test-expression)
	body

for루프에서 초기화 부분과 갱신 부분을 없애고 루프 몸체와 조건 검사 부분만 남겨놓으면 while 루프가 됨
루프가 끝나려면 조건 검사 표현식에 영향을 주는 것이 루프 몸체 안에 들어있어야 함

// while.cpp

#include <iostream>
const int ArSize = 20;

int main()
{
	using namespace std;
	char name[ArSize];

	cout << "영문 이름을 입력하십시오 : ";
	cin >> name;
	cout << "귀하의 영문 이름을 한 줋에 한 자씩\n";
	cout << "ASCII 코드와 함께 표시하면 이렇습니다.\n";
	int i = 0;
	while (name[i] != '\0')
	{
		cout << name[i] << " : " << int(name[i]) << endl;
		i++;
	}
	return 0;
}

i++;이 없을 시 계속 같은 배열 원소에 접근하며 루프하기때문에 무한 루프가 발생함
C 스타일 문자열과는 달리 string 클래스 객체는 문자열의 끝을 인식하기 위한 널 문자를 사용하지 않음

for과 while

C++에서의 for 루프와 while 루프는 사실상 같음

  • 루프 실행을 종료시키는 조건 파악
  • 첫번째 조건 검사를 하기 전 그 조건을 초기화
  • 조건 검사를 다시하기 전 매 루프 주기마다 해당 조건을 갱신

따라서 어느 것을 선택하는지는 사용자의 프로그래밍 스타일에 달림

  • 일반적으로 for 루프는 초기값, 종료값, 카운터 갱신을 한번에 할 수 있기 때문에 루프를 카운트해야할 때 주로 사용
  • while 루프는 루프의 반복 횟수를 미리 알 수 없을 때 주로 사용

시간 지연 루프

초창기에는 컴퓨터로 하여금 수를 카운트하게 하여 시간을 소모시켰음
그러나 이는 컴퓨터 프로세서의 성능에 따라 카운트해야하는 수의 한계가 달라짐
따라서 ANSI C와 C++ 라이브러리는 clock()이라는 함수를 제공함

// waiting.cpp

#include <iostream>

int main()
{
	using namespace std;
	cout << "지연 시간을 초 단위로 입력하십시오 : ";
	float secs;
	cin >> secs;
	clock_t delay = secs * CLOCKS_PER_SEC;
	cout << "카운트를 시작합니다. \a\n";
	clock_t start = clock();
	while (clock() - start < delay)
		;
	cout << "종료\a\n";
	return 0;
}

clock()함수가 제공하는 시간은 초 단위 시간이 아님
시스템마다 clock()함수가 리턴하는 데이터형이 다를 수 있음
이를 보완하기 위해 ctime 헤더 파일에서 초당 시스템 시간 단위 수를 뜻하는 CLOCKS_PER_SEC이라는 기호 상수를 정의하고, 데이터형으로 clock_t형을 정의함


데이터형의 대용 이름

전처리기 사용 : #define BYTE char *

  • 단, BYTE pa, pb;와 같이 여러 개의 변수 리스트를 선언하는 경우 원하는 결과를 얻을 수 없음

키워드 사용 : typedef char byte;

  • typedef를 사용하는 것이 #define보다 훨씬 좋은 선택임


5.3 do while 루프

do
	body
while (test-expression);

for 루프나 while 루프와는 달리 탈출조건(exit-condition) 루프임
루프 몸체가 먼저 실행되고, 조건을 나중에 검사하여 참인경우 루프를 실행함
따라서 루프 몸체가 최소한 한번은 실행됨

 // dowhile.cpp

#include <iostream>

int main()
{
	using namespace std;
	int n;

	cout << "1부터 10까지의 수 중에서 ";
	cout << "내가 좋아하는 수를 한번 맞추어 보십시오.\n";
	do
	{
		cin >> n;
	} while (n != 7);
	cout << "맞았습니다. 내가 좋아하는 수는 럭키 세븐 7입니다.\n";
	return 0;
}

일반적으로는 먼저 조건을 검사하는 루프가 더 나은 선택임
그러나 사용자로부터 입력을 받아야하는 등 do while 루프가 더 적당한 경우도 있음



5.4 Range 기반의 for 루프

C++11에는 Range 기반의 for 루프라고 불리는 새로운 형태가 추가됨

double prices[5] = { 4.99, 10.99, 6.87, 7.99, 8.49 };
for ( double x : prices )
	cout << x << std::endl;

x는 prices 배열의 첫 번째 요소로 초기화되며, 배열의 range 안에 포함되는 모든 값들이 루프를 돌면서 출력됨

for (double &x : prices)
	x = x * 0.8;

&x로 배열의 값을 참조하여 변경할 수 있음

for ( int x : {3, 4, 2, 8, 6})
	cout << x << " ";

Range 기반 for 루프를 초기화 리스트에도 사용할 수 있음



5.5 루프와 텍스트 입력

cin을 이용한 입력

// textin1.cpp

#include <iostream>

int main()
{
	using namespace std;
	char ch;
	int count = 0;

	cout << "문자들을 입력하시오; 끝내려면 #을 입력하시오 : \n";
	cin >> ch;
	while (ch != '#')
	{
		cout << ch;
		++count;
		cin >> ch;
	}
	cout << endl << count << " 문자를 읽었습니다.\n";
	return 0;
}

표지 문자(sentinel character)라고 부르는 특수 문자를 입력 중지 신호로 사용
위 예제에서는 #을 표지 문자로 사용함
cin은 공백이나 개행을 무시하기 때문에 입력으로 받은 띄어쓰기들을 에코하지 않으며, 읽은 문자 수에도 포함되지 않음
cin입력은 버퍼를 이용하므로 입력시에는 #문자를 쓰더라도 뒤에 더 입력할 수 있음


cin.get(char)를 이용한 입력

// textin2.cpp

#include <iostream>

int main()
{
	using namespace std;
	char ch;
	int count = 0;

	cout << "문자들을 입력하시오; 끝내려면 #을 입력하시오 : \n";
	cin.get(ch);
	while (ch != '#')
	{
		cout << ch;
		++count;
		cin.get(ch);
	}
	cout << endl << count << " 문자를 읽었습니다.\n";
	return 0;
}

cin.get(char)는 공백 문자도 입력받음
C 문법에서라면 cin.get()의 매개변수로 &ch를 받아야했겠지만, C++에서는 함수의 매개변수를 참조형(reference)으로 선언할 경우 그냥 변수명으로 사용 가능함

C++에서는 함수 오버로딩(function overloading)이라는 OOP기능이 제공되어 사용하는 매개변수가 다른 동일한 이름의 함수들을 만들 수 있음


파일 끝(End-Of-File) 조건

#와 같은 기호를 입력의 끝으로 나타낼 경우, 실제로 #을 적법하게 사용해야할 경우 문제가 생김
Unix와 MS-DOS를 비롯한 많은 운영 체제들이 리디렉션(redirection) 기능을 통해 키보드 입력을 파일으로 대체하기 때문에 키보드 입력을 받는 경우에도 그 끝을 인식할 수 있음
또는 EOF 조건을 키보드 입력을 통해 시뮬레이션하는 것도 가능함

  • Unix의 Ctrl+D
  • DOS의 Ctrl+Z + Enter 등
  • 일부 C++ 컴파일러에서도 유사한 기능을 지원
// textin3.cpp

#include <iostream>

int main()
{
	using namespace std;
	char ch;
	int count = 0;
	cin.get(ch);
	while (cin.fail() == false)
	{
		cout << ch;
		++count;
		cin.get(ch);
	}
	cout << endl << count << " 문자를 읽었습니다.\n";
	return 0;
}

cinEOF를 탐지할시 두개의 비트 eofbitfailbit를 1로 설정함

  • cin.eof() 멤버 함수에서 EOF가 탐지되었으면 true, 아니면 false를 리턴함
  • cin.fail() 멤버 함수에서는 eofbit 또는 failbit가 1로 설정되었을시 true, 아니면 false를 리턴함

cin 메서드가 EOF를 발견하면 cin 객체의 EOF 조건을 나타내는 플래그가 설정되고, cin은 더이상의 입력을 받아들이지 않음
그러나 키보드 입력시 더 입력이 필요할 수 있고, 이 때 cin.clear() 메서드로 EOF 플래그를 지울 수 있음

일반적으로는 while(!cin.fail())이나 while(!cin.eof()) 대신 while(cin)을 사용
또는 while(cin.get(ch))를 사용해 검사 조건에서 한번만 호출할 수도 있음


cin.get()의 또다른 버전

매개변수가 없는 cin.get() 멤버 함수는 C의 getchar() 함수와 유사하게 동작하며 문자 코드를 int형 값으로 리턴함
cout.put() 함수는 매개변수로 char형을 받는다는 것을 제외하면 C의 putchar()과 유사하게 동작함

// textin4.cpp

#include <iostream>

int main()
{
	using namespace std;
	int ch;
	int count = 0;

	while ((ch = cin.get()) != EOF)
	{
		cout.put(char(ch));
		++count;
	}
	cout << endl << count << " 문자를 읽었습니다.\n";
	return 0;
}

cin.get()EOF에 도달할 경우 기호 상수 EOF로 나타나는 특별한 값을 리턴함
일반적으로는 ASCII 코드값과 겹치지 않는 -1로 정의됨
단, 이 때 시스템에 따라 char형에 부호가 없을 수 잇기 때문에 int 형에 대입해야함

cin.get(char)는 리턴값이 istream 객체이기 때문에 객체 지향적인 접근에 사용하는 것이 적당함
get()getchar()putchar()함수를 iostreamcin.get()cout.put() 메서드로 변환하는데 주로 사용함


중첩 루프와 2차원 배열

2차원 배열을 나타내는 데이터형이 따로 존재하지는 않으나, 배열 자체를 원소로 사용하는 배열로 2차원 배열을 구현함

// nested.cpp

#include <iostream>
const int Cities = 5;
const int Years = 4;

int main()
{
	using namespace std;
	const char * cities[Cities] =
	{
		"Seoul",
		"Jeju",
		"Busan",
		"Gangneung",
		"Daegu"
	};

	int maxtemps[Years][Cities] =
	{
		{35, 32, 33, 36, 35},
		{33, 32, 34, 35, 31},
		{33, 34, 32, 35, 34},
		{36, 35, 34, 37, 35}
	};

	cout << "2009년부터 2012년까지의 연중 최고 온도\n\n";
	for (int city = 0; city < Cities; ++city)
	{
		cout << cities[city] << " : \t";
		for (int year = 0; year < Years; ++year)
			cout << maxtemps[year][city] << "\t";
		cout << endl;
	}
	return 0;
}

2차원 배열의 초기화시 1차원 배열의 초기화 값들이 나열된 중괄호들을 콤마로 분리하여 사용함
포인터 배열 대신 string 객체를 사용할 경우 자동 크기 조절 기능으로 인해 2차원 사용하기 훨씬 편리함



연습문제

  1. 진입 조건 루프는 루프 몸체에 들어가기 전 조건식을 평가, 탈출 조건 루프는 루프 몸체를 실행한 후 조건식을 평가
    for 루프와 while 루프는 진입 조건 루프, do while 루프는 탈출 조건 루프

  2. 01234

  3.  0369
     12
    
  4.  6
     8
    
  5. k = 8

  6.  for (int i = 1; i < 65; i *= 2)
         cout << i << " ";
    
  7. 중괄호를 사용해 블록을 생성한다

  8. a) 적법하다 - 1과 024의 두 표현식이 콤마 연산자로 결합되어 024가 전체 표현식의 값이 되고, 024는 십진수로 20이기 때문에 x에 20이 대입된다
    b) 적법하다 - y에는 1이 대입되며, 전체 표현식의 값은 024가 되지만 사용되지는 않는다

  9. cin >> ch는 공백 문자를 입력받지 않고 건너뛴다

Tags:

Categories:

Updated: