입출력과 전처리
표준 입출력 함수
scanf()
를 이용한 표준 입력
scanf()
함수는 키보드로부터 데이터를 입력받기 위한 표준 입력 함수이다. 이 함수를 사용하기 위해서는 stdio.h
헤더 파일이 필요하다.
scanf()
는 변환 명세(Conversion Specification)를 포함하는 제어 문자열과 입력받을 값을 저장할 변수의 주소를 인자로 받는다. 변수의 주소를 전달하기 위해 변수 이름 앞에 주소 연산자 &
를 붙여야 한다.
int age;
scanf("%d", &age); // 키보드로 입력한 정수를 age 변수에 저장한다.
scanf()
에서 사용하는 주요 변환 명세는 다음과 같다.
%d
: 10진수 정수 (int)%o
,%x
: 8진수, 16진수 정수 (int)%u
: 부호 없는 10진수 정수 (unsigned int)%f
: 단정밀도 실수 (float)%lf
: 배정밀도 실수 (double)%c
: 단일 문자 (char)%s
: 문자열 (string)
문자 입력 시 주의사항: scanf()
로 여러 데이터를 연속으로 입력받을 때, 숫자 등을 입력한 후 누른 Enter키(\n)가 입력 버퍼에 남아 다음 문자 입력(%c
)에 영향을 줄 수 있다. 이를 방지하려면 %c
앞에 공백을 추가하여 scanf(" %c", &variable);
형태로 사용해야 한다. 이 공백은 버퍼에 남아있는 공백 문자(스페이스, 탭, 개행 등)를 무시하는 역할을 한다.
printf()
를 이용한 표준 출력
printf()
함수는 화면에 데이터를 출력하기 위한 표준 출력 함수이다. scanf()
와 마찬가지로 제어 문자열과 출력할 값(표현식)들을 인자로 받는다.
출력 형식 지정
printf()
의 변환 명세에 추가적인 정보를 결합하여 출력 형식을 제어할 수 있다.
- 필드 폭(Field Width): 출력할 전체 자릿수를 지정한다.
%5d
: 5칸을 확보하고 오른쪽 정렬로 정수를 출력한다.%-5d
: 5칸을 확보하고 왼쪽 정렬로 정수를 출력한다.%+5d
: 부호를 항상 표시하며 5칸에 오른쪽 정렬로 출력한다.
- 정밀도(Precision): 실수를 출력할 때 소수점 이하 자릿수를 지정한다.
%5.2f
: 전체 5칸 중 소수점 이하 2자리까지 출력한다.%10.4e
: 전체 10칸을 확보하고 지수 형태로 소수점 이하 4자리까지 출력한다.
출력 제어 문자 (Escape Sequence)
printf()
의 제어 문자열 안에서는 특수한 기능을 하는 출력 제어 문자를 사용할 수 있다.
\n
: 줄 바꿈 (Newline)\t
: 수평 탭 (Horizontal Tab)\"
: 큰따옴표 출력\\
: 역슬래시() 출력\a
: 경고음 (Alert)
getchar()
와 putchar()
getchar()
와 putchar()
는 한 번에 문자 하나만을 입출력하기 위한 함수이다. 사용법은 다음과 같다.
char c;
c = getchar(); // 문자 하나를 입력받아 c에 저장한다.
putchar(c); // c에 저장된 문자를 출력한다.
전처리기 (Preprocessor)
전처리기는 소스 코드가 컴파일러에 의해 번역되기 전에 특정 작업을 먼저 수행하는 프로그램이다. 전처리기 지시자는 #
문자로 시작한다.
#include
와 헤더 파일
**Header File(헤더 파일)**은 확장자가 .h
인 텍스트 파일로, 주로 함수 원형, 매크로 정의, 자료형 재정의 등을 포함한다. #include
지시자는 이러한 헤더 파일을 소스 코드에 포함시키는 역할을 한다.
#include <stdio.h>
: 시스템 헤더 파일을 포함할 때 사용한다.#include "myheader.h"
: 사용자가 직접 작성한 헤더 파일을 포함할 때 사용하며, 현재 소스 파일이 있는 폴더부터 검색한다.
주요 시스템 헤더 파일은 다음과 같다.
stdio.h
: 표준 입출력 함수 (printf, scanf 등)math.h
: 수학 관련 함수 (pow, sqrt 등)string.h
: 문자열 처리 함수 (strcpy, strlen 등)stdlib.h
: 메모리 할당, 유틸리티 함수 (malloc, exit 등)
#define
과 매크로
#define
지시자는 특정 식별자(기호 상수 또는 매크로)를 지정된 문자열로 치환하는 역할을 한다.
-
기호 상수: 값에 이름을 부여하여 가독성과 유지보수성을 높인다.
#define PI 3.141592
-
인자가 있는 매크로: 함수처럼 동작하는 코드를 정의한다.
#define SQUARE(x) ((x) * (x))
매크로 정의 시, 인자와 전체 식을 괄호로 감싸는 것이 중요하다.
괄호가 없으면 연산자 우선순위에 의해 예기치 않은 결과가 발생할 수 있다.
typedef
를 이용한 자료형 재정의
typedef
키워드는 이미 존재하는 자료형에 새로운 이름을 부여하는 기능이다. 이는 코드의 가독성을 높이고, 다른 시스템으로 코드를 이식할 때 자료형의 크기 차이로 인한 문제를 쉽게 해결할 수 있게 도와준다.
typedef int myint; // int 자료형을 myint라는 이름으로도 사용할 수 있다.
myint salary; // int salary; 와 동일하다.
기본 연산자
연산자의 기본 개념
- Operator(연산자): 덧셈(
+
), 곱셈(*
)과 같이 특정 연산을 수행하도록 정의된 기호나 키워드이다. - Operand(피연산자): 연산의 대상이 되는 변수나 값이다.
연산자는 피연산자의 수에 따라 단항, 이항, 삼항 연산자로 분류된다.
주요 연산자
대입 연산자 (Assignment Operator)
Assignment Operator(대입 연산자) =
는 오른쪽 피연산자의 값을 왼쪽 피연산자(변수)에 저장하는 역할을 한다. 연산자들 중 우선순위가 매우 낮아 대부분의 다른 연산이 끝난 후 마지막에 수행된다.
관계 연산자 (Relational Operators)
**Relational Operator(관계 연산자)**는 두 피연산자의 값을 비교하는 데 사용된다. 연산 결과는 참(true)이면 1, 거짓(false)이면 0의 정수 값을 가진다.
>
,<
,>=
,<=
,==
(같다),!=
(같지 않다)
증감 연산자 (Increment/Decrement Operators)
Increment/Decrement Operator(증감 연산자) ++
와 --
는 피연산자의 값을 1 증가시키거나 감소시킨다. 연산자의 위치에 따라 평가 결과가 달라진다.
- 전위(Prefix):
++a
,--a
. 변수의 값을 먼저 증감시킨 후, 그 결과를 수식의 값으로 사용한다. - 후위(Postfix):
a++
,a--
. 변수의 현재 값을 먼저 수식의 값으로 사용한 후, 변수의 값을 증감시킨다.
논리 연산자 (Logical Operators)
**Logical Operator(논리 연산자)**는 논리적인 관계를 평가하는 데 사용된다. C언어에서는 0을 거짓으로, 0이 아닌 모든 값을 참으로 간주한다.
&&
(AND): 두 피연산자가 모두 참일 때만 1(참)을 반환한다.||
(OR): 두 피연산자 중 하나라도 참이면 1(참)을 반환한다.!
(NOT): 피연산자가 참이면 0(거짓)을, 거짓이면 1(참)을 반환한다.
단축 평가 (Short-circuit Evaluation)
논리 연산자 &&
와 ||
는 **Short-circuit Evaluation(단축 평가)**를 수행한다.
&&
연산에서 첫 번째 피연산자가 거짓(0)이면, 전체 결과는 무조건 거짓이므로 두 번째 피연산자를 평가하지 않는다.||
연산에서 첫 번째 피연산자가 참(1)이면, 전체 결과는 무조건 참이므로 두 번째 피연산자를 평가하지 않는다.
이러한 특성은 b++
와 같은 증감 연산자가 논리 연산식 내에 있을 때 예기치 않은 동작의 원인이 될 수 있으므로 주의해야 한다.