▶ 공백계 문자의 취급
C 프로그램에서 공백문자는 확대 해석된다. 말하자면
블랭크문자 탭문자 쪽 넘김 개행문자
와 같은 것은 모두 넓은 의미에서 공백문자로 취급된다. 공백문자가 여러 개 연속되어 있어도 1개의 공백과 같은 기능을 한다. C에서는 개행문자를 단순한 공백과 동일시함으로써 행의 개념을 없앤다.
▶ 행의 끝
파일 상에서 행의 끝은 개행문자로 표현된다. 그러나 C컴파일러는 이 개행문자를 단순한 공백으로 간주하므로 C에서는
- 그 행의 끝까지 유효
한 처리는 없다. 예를 들어 주석문도
- 그 행의 끝까지 주석문
으로 삼는 규칙은 없다. 어디까지나 주석문의 시작에서 주석문의 끝까지가 유효 범위인 것이다. 주석문이 여러 행에 걸쳐 있을 수도 있다.
단 C에도 행의 끝을 인식하는 기능히 하나 있는데, 그것이 바로 프리프로세서 명령이다. #define을 비롯한 프리프로세서는 '행의 끝까지'를 하나의 명령문으로 인식한다.
▶ 행의 연결(종단문자의 무효화)
프리프로세서는 행의 끝까지를 하나의 문장으로 판단하기 때문에 C의 본문과 같이 자유롭게 행을 나눌 수 없다. 프리프로세서에서는 2행에 걸쳐 쓸 수 없게 되어 있다. 그러나 행 끝에 '\'를 써넣음으로써 행을 나눌 수도 있다.
표준 장석법 #define beep( ) putchar(7);
'\'에 의한 행 나누기 #define beep( ) put\
char(7);
위의 두 가지 방법은 동일한 작용을 한다. 여기서는
-행 끝에 '\'가 있으면 그 '\' 자식과 이어지는 개행문자를 없는 것으로 간주
함으로써 2행을 1행으로 병합시킨다. 이 작업은 컴파일러가(엄밀하게 말하면 프리프로세서가)소스 프로그램을 읽어서 맨 처음에 처리한 후 컴파일한다. 이 때 개행한 후 공백문자들도 의미를 갖게 되므로 주의해야 한다. 예를 들어
#define beep( ) put\
char(7); ...앞의 공백문자들도 의미가 있으므로 에러
라고 하면 에러가 된다.
이 규칙은 프로 프로세세의 기술을 보다 유연하게 만들기 위해 고안된 것이며, 모든 C소스 프로그램 안에서 적용할 수 있다. C에서는 기본적으로 행 나누기를 자유롭게 할 수 있다. 하지만 한 가지의 경우는 주의해야 하는데, '토큰을 끊고 행 나누기' 하는 것이 그것이다. 이 때 '\'를 이용하면 '토큰을 끊고 행나누기'를 할 수 있게 된다.
▶ 토큰
토큰은 C프로그램 해석 상의 의미있는 문자 또는 문자열을 뜻한다. 실제로는
연산자 * / + - ...
분리자 ( ) { } [ ] , ; :
식별자 변수명이나 함수명 등
예약어 if for long ...
정수 100 12.345 0xff3a 'a' "abcde"
로 구성된다. 예를 들어
a = dt[pos]+100;
라는 문장은
a = dt [ pos ] + 100;
라는 토큰으로 식별된다.
▶ 특수문자의 역할
C에서는 다양한 특수문자(도형문자)를 이용한다. 다음은 특수문자와 그 용도(의미)이다.
문자 |
용도 |
! |
관계 연산 논리 부정 |
" |
문자열 정수 |
# |
프리프로세서 |
$ |
사용하지 않음 |
% |
나머지 서식 지정 |
& |
논리적 비트AND 포인터 연산 |
' |
문자정수 |
( |
함수 우선순위 설정 |
) |
함수 우선순위 설정 |
* |
곱셈 포인터 연산 |
+ |
+부호 덧셈 증가 |
, |
콤마 연산 |
- |
-부호 뺄셈 감소 멤버참조 연산 |
. |
멤버참조 연산 소수점 |
/ |
나눗셈 |
: |
조건 연산 |
; |
문장의 끝 |
< |
관계 연산 비트 쉬프트 |
= |
관계 연산 대입 |
> |
관계 연산 비트 쉬프트 멤버참조 연산 |
? |
조건 연산 |
@ |
사용하지 않음 |
[ |
배열 |
\ |
이스케이프문자 행 연결 |
] |
배열 |
^ |
비트XOR |
_ |
식별자 |
{ |
복합문 |
| |
논리화 비트 OR |
} |
복합문 |
~ |
비트반전(1의 보수) |
▶ 대문자와 소문자의 구별
C에서는 대문자와 소문자가 구별된다. 예를 들어
int data, DATA, Data;
라는 선언을 했을 때 3개의 변수는 서로 전혀 관계없는 독립된 것으로서 작동한다.
▶ 문자열 정수의 연결
서로 이웃한 문자열 정수는 연결할 수 있다. 예를 들어
"abc" "def"
라는 문자열은
"abcdef"
와 동일하다. 이 기능을 이용하면 너무 긴 printf문을 문자열의 중간에서 개행할 수도 있다. 예를 들어
printf("abc\n"
"def\n"
"ghi\n");
와 같이 쓸수도 있다. 이 문자열의 배치는 화면 출력 이미지와 일치시키기 위해 유효하다.
▶ 오브젝트
오브젝트라는 용어는 광범위하게 쓰이고 있다. 예를 들어 '오브젝트 코드'라고 하면 기계어의 형식이 된 코드를 말한다. 언어시스템이 세계에서는 보다 한정된 의미를 갖게 되는데 단순히 오브젝트라고 할 때는
- 데이터를 입력하거나 그 데이터를 참조할 수 있는 이름이 있는 기억 영역
을 가리킨다. 단 const오브젝트에는 입력할 수가 없다. 오브젝트가 있는 장소를 주소라고 하며 오브젝트를 식별하는 이름이 변수이다.
또한 C를 기능 강화한 C++의 세계에서는 단순히 오브젝트라고 칭했을 때 '클래스 오브젝트'를 의미할 수도 있다.
▶ 오퍼레이터와 오퍼랜드
오퍼레이터(operator : 연산자)는 연산을 지시하는 것이다. 오퍼레이터보다는 '연산자'라는 용어가 보다 보편적으로 쓰인다. 이에 대응하는 말이 오퍼랜드(operand : 작용 대상)로서 연산의 대상이 되는 것을 뜻한다. 예를 들어
a+2
라는 식이 있을 때 +는 오퍼레이터, a와 2는 오퍼랜드이다.
▶ 단항과 이항
단항은 오퍼랜드가 하나라는 것을 의미한다. 1항이면 단항, 2항이 있으면 이항이라고 한다. 이와 관련하여 다음과 같은 용어를 알아두자.
단항식
연산자와 하나의 오퍼랜드로 구성되는 다음과 같은 식을 말한다.
&a
!a
sizeof a
단항 연산자
하나의 오퍼랜드를 연산 대상으로 하는 연산자. 예를 들어
&p
b--
++c
안의 &, --, ++은 단항 연산자이다.
이항 연산자
2개의 오퍼랜드를 연산 대상으로 하는 연산자, 예를 들어
a*b
a/b
안의 *, / 는 이항 연산자이다.
▶ 좌변값과 우변값
좌변값과 우변값에서 방향은 기본적으로 대입기호 '='에 대해 어느 쪽에 위치하는지를 나타낸다. 좌변값과 우변값은 다음과 같은 의미를 갖고 있다.
좌변값
오브젝트를 참조하거나 변경하는 식 또는 그 식에서 계산한 결과, 대입식의 좌변에(우변에도) 쓸 수 있다.
우변값
값을 참조할 수는 있으나 변경할 수 없는 식. 대입식의 우변에는 쓸 수 있지만 좌변에는 쓸 수 없다.
예를 들어 다음과 같이 썻다고 하자.
#define DATA 100
int a, b[10];
int *p;
여기서 좌변값은 a,b[], p이고 우변값은 DATA, b이다. 좌변값은 우변에도 쓸 수 있으나 우변값은 좌변에 쓸 수 없다. 예를 들어 b[3]은
b[3]=100;
라고 쓸 수 있으므로 좌변값이다. 이에 대해 배열명 b자체는
p = b;
라고 쓸 수 있으나
b=...;
라고 쓸 수는 없으므로 우변값이다. 또한 ++ 연산자는 그 대상 오브젝트가 좌변값이어야 한다. 따라서
++a;
라고 쓸 수는 있지만
++DATA;
라고 쓸 수는 없다. const형 수식자를 사용한 변수도 우변값이 되는데 이유는 그 값을 변경할 수 없기(좌변에는 쓸 수 없음)때문이다.
▶ EOF와 NULL
EOF와 NULL은 데이터의 끝을 검출할 때 자주 쓰인다.
while((c=getchar()) != EOF) { ... } while(gets(st) != NULL) { ... } |
이 2개의 기호정수는 stdio.h 안에서
#define EOF (-1)
#define NULL (0)
으로 정의되어 있다. NULL은 환경에 따라 OL이 되거나
#define NULL ((void *)0)
이 될 때도 있다. 어쨌든 프로그래머가 기호정수의 값을 기억해 둘 필요는 없으며 프로그램의 맨 앞에
#include <stdio.h>
라고 쓰면 이 값을 이용할 수 있다. 그리고
- getchar는 입력 종료로 EOF를 리턴한다.
- gers는 입력 종료로 NULL을 리턴한다.
- fopen은 오픈 실패로 NULL을 리턴한다.
와 같은 약속을 알아두면 된다. 어떤 함수가 EOF, NULL에 대응하는지에 대해서는 메뉴얼의 라이브러리 함수의 설명 부분에 게재되어 있다.
'C언어 다시 다지기' 카테고리의 다른 글
DAY004 변수의 초기화 (0) | 2018.04.30 |
---|---|
DAY003 변수의 선언 (0) | 2018.04.30 |
DAY002 숫자를 저장하는 변수 (0) | 2018.04.26 |
DAY001 변수란? (0) | 2018.04.17 |
C의 기본적 지식(2) (0) | 2018.03.14 |