C 명령어
C 명령어는 C 언어에서 사용하는 명령어이다. C언어에서 사용 가능한 명령문의 종류는 크게 전처리 지시어, 선언문, 연산문, 함수, 제어문의 5가지로 나눌 수 있다.
명령문[편집]
전처리 지시어[편집]
전처리 지시어는 #으로 시작하며 컴파일러에 포함되어있는 전처리기에게 전달하는 정보다. 이 지시어는 코드에서 사용하는 함수에 관한 정보를 제공하는 역할을 한다. '#include <stdio.h>'가 대표적인 예다.[1]
종류[편집]
#include[편집]
파일 처리를 위한 전처리문으로 C언어로 작성된 특정파일을 소스에 포함시키기 위해 사용하며 크게 두가지분류로 나눌 수 있다. 첫번째는 화살괄호(<>) 사이에 파일명을 넣어서 사용하는 방법이다. 파일명은 C에서 제공하는 표준 헤더파일들이 있는 디렉토리에서 그 파일을 찾아 사용하게 된다.
#include <stdio.h>
두번째는 큰따옴표("") 사이에 파일명은 사용자가 C 언어로 정의한 파일을 기본경로에서 찾아 사용하게 된다. 파일 경로는 전체 경로를 작성해도 상관없다.[2]
#include "test.h"
#define[편집]
상수값을 지정하기 위한 예약어로 매크로라고 부르며 사용문법은 #define [매크로명] [실제값] 이다. 단순히 매크로명을 실제 값을 치환해주는 역할을 한다. 함수/변수명과 구분하기 위해 주로 대문자로 매크로 명을 쓰는 것이 관례이다. 함수나 서브루틴과는 다르게 분기하여 실행되는 것이 아니라, define 에 의해 정의된 코드가 해당 위치로 치환된다. 이는 함수 호출과 관련한 오버헤드를 줄일 수 있어 어느정도 속도의 향상을 꾀할 수 있지만, 최종 실행파일의 크기는 커지게 된다.
사용법은 크게 2가지로 단순하게 매크로명을 대응 문자열 또는 상수로 치환하는 방법과 매크로 함수를 만들어 사용하는 방법 두가지가 있다.
#define CARNAME "porsche" printf(CARNAME); //단순하게 매크로 명을 치환 #deinfe PAYCALC(a, b) ((a) * (b) * 4000) printf("My Pay? : %d\n",PAYCALC(8,30)); //매크로 함수 제작 후 사용
define 사용시, 문자열이나 문자 정수 속에는 치환이 발생하지 않으며, 매크로 함수 사용시 인자를 정의하는 괄호를 매크로함수명 다음에 공백을 두지 않고 바로 사용해야 한다. 일반적으로 define의 사용은 프로그램의 명확성과 이식성을 증대시켜준다.[2]
#undefine[편집]
'#define'으로 이미 정의된 매크로를 무화화한다.
#define ADD(a,b)(a+b) #undef ADD(a,b)
'#undef' 으로 무효화된 메크로를 재사용을 할경우에는 'undefined symbol' 에러처리된다.[2]
#if, #else, #elif, #endif[편집]
조건부 컴파일을 위해서 사용되는 전처리문이다. 특정한 조건이 성립될때나 또는 성립되지 않을때에만 지정된 범위내의 문장을 컴파일하거나 또는 그냥 무시하고 컴파일하지 않는것을 말한다. 조건부 컴파일의 주목적은 프로그램의 호환성을 높이는데 있다. C에서는 '0'이 아닌 정수는 모두 참 값으로 간주한다.[2]
#ifdef, #ifndef[편집]
매크로가 정의 되어 있는지를 판단한다.
#ifdef [매크로명] #ifndef[매크로명]
'#ifdef'는 'if define'의 약자로 매크로가 정의되있을 경우 참으로, 정의가 되어있지 않을경우 거짓으로 평가한다. #ifndef는 'if not define'의 약자로 매크로가 정의되어있을 경우 거짓으로, 정의되어 있지 않을 경우 참으로 평가한다.[2]
#error[편집]
소스 라인에 직접 에러 메세지를 출력한다. 전처리기가 #error 문을 만나면 그 즉시 컴파일을 중단하고 다음과 같은 에러 메시지를 출력한다.[2]
ERROR : XXXXX.c ########: Error directive: 내용
'XXXXX.c'는 현재 컴파일 중인 파일명이며 '#######'은 전처리기가 #error문을 만난 시점에서의 행 번호이다.
#line[편집]
이 명령은 소스 코드의 행번호를 지정하기 위한 것으로 주로 컴파일러에 의해 미리 정의된 '__LINE__'과 함께 사용된다. C에서는 베이식과 같은 행번호를 사용하지 않는다. 하지만 디버깅 시 행번호를 미리 알고 있으면 편한 경우가 있다. 예를 들어 어떤 표현들이 있고, 그 표현들 중의 어딘가에 잘못된 부분이 있는 것 같은데 정확히 그 표현이 있는 행을 찾지 못한다면 "#line"을 사용함으로써 그 일을 보다 수월하게 할 수 있게 된다.[2]
#pragma[편집]
컴파일 옵션의 지정을 하는데 사용한다. 컴파일러 작성자에 의해서 정의된 다양한 명령을 컴파일러에게 제공하기 위해서 사용되는 지시어이다. 컴파일러의 여러가지 옵션을 명령행 상에서가 아닌 코드상에서 직접 설정한다. #pragma는 함수의 바로 앞에 오며, 그 함수에만 영향을 준다. 터보C는 9개의 #pragma문을 지원하고 있다.[2]
선언문[편집]
코드에서 사용하는 변수를 신고하기 위해서 사용한다. 모든 변수는 사용하기 전에 반드시 선언되어야 하며 컴파일러는 이 선언문을 보고 변수를 만든다. 변수를 선언할 때는 변수이름 앞에 int와 같은 데이터 형을 지정하며 초기값을 설정할 수도 있다. int num; 또는 int num = 10;과 같이 사용한다.[1]변수 선언의 기본형에는 정수형, 문자형, 실수형, 열거형, void형 등이 있다.
정수형[편집]
C/C++에서 정수형 변수는 정수를 처리하기 위한 변수이다. 정수형 변수를 마이크로프로세서가 처리할 때, 부호와 숫자범위를 결정해야 한다. C/C++로 작성 된 코드는 결국 해당 마이크로프로세서의 기계어 코드로 변환하는데, 마이크로프로세서의 숫자체계를 사용하기 때문이다. 숫자 범위는 2진수의 몇비트로 처리할 것인가를 결정 해야 한다. 이것은 곧 정수 처리 범위를 결정된다. 마이크로프로세서 내에서 레지스터와 ALU의 비트수가 결정 되었기 때문이다. 숫자 범위는 char, int, short, long을 사용해 변수선언을 하면 된다. 부호는 unsigned을 이용한다. 음수와 양수를 표현하기 위해서는 signed과 unsigned를 사용한다. 음수를 사용할 경우 보통 signed를 생략 한다. int나 char 만을 선언하면 양수와 음수를 같이 사용한다. 양수 만을 사용하려면 unsigned 붙이면 된다. 중앙처리장치에서 음수는 2진수 체계중에 논리 공학의 2의보수를 사용한다. unsigned를 사용할 경우는 정해진 비트 수 내에서 이진수와 같다. 그러나 음수를 사용할 경우, 양수와 음수는 2의 보수 체계를 사용하여 숫자를 배치 한다. 이것은 연산자로 코딩 될 때 수월하게 숫자를 표현하거나 계산할 수 있기 때문이다. 정수 연산은 중앙처리장치 내의 ALU에서 처리 한다. 사칙연산, 논리연산, 비트 쉬프트 등의 연산이 가능하다. 많은 중앙처리장치의 경우 부동소수점 연산(FPU) 모듈이 없지만, 정수형 연산은 모든 중앙처리장치가 실행한다. 정수는 정수형 ALU을 사용하여 연산한다. 경우에 따라 저속의 8비트 중앙처리장치는 나누기 기계어 코드가 없지만, 현재의 중앙처리장치 들은 거의 모두 사칙연산을 할 수 있다. 보통의 중앙처리장치 ALU는 정수형의 나누기의 연산 시, 나누기 기계어 코드가 실행되고 몫과 나머지로 분리하여 레지스터에 저장함으로써 결과를 얻는다.[3]
실수형[편집]
C/C++에서 실수형은 실수를 처리하기 위해 사용한다. 실수를 2진수를 표현할 때 부동소수점 방식과 고정 소수점 방식이 있는데, C/C++에서는 부동소수점 방식을 사용한다. 이것은 국제표준 전기전자기술자협회 754 규격에 따른다. float와 double을 사용하여 변수 선언을 한다. 이것은 중앙처리장치의 구조와 상관이 없이 국제 표준에 의한 규정에 따른 변수이므로 int처럼 변수 길이(비트 수)가 변하지 않는다. 보통 마이크로프로세서는 정수형 ALU을 사용한다. 그러나 실수형 처리를 위한 부동소수점 처리 모듈은 많은 중앙처리장치에 존재하지 않는다. 이렇게 실수형 ALU가 없다면 실수형 처리 함수를 사용한다. 정수형과 실수형 연산 모듈이 같은 중앙처리장치 안에 따로 존재하기도 한다. 이렇게 따로 존재한다면 각각의 기계어 코드를 나누어, C/C++가 각각의 기계어를 사용하도록 컴파일한다. 고성능의 중앙처리장치 경우 별도의 FPU 연산 모듈로 구성하는 것이 일반적이다. 인텔의 x86 계열은 80386의 경우 80387이라는 칩이 별도로 구성하였다. 다른 칩이므로 컴퓨터 설계과정에서 PCB 상에서 결합되어 있었다. 80486에서 이 두 칩이 하나의 칩으로 합쳐졌다. 결국 80486은 정수형 ALU와 FPU(Floating-point unit)가 한 칩 내에 만들어져 있다. 실수형 변수는 FPU을 이용하여 연산할 수 있다. 프로그램 개발도구에 따라 FPU가 존재하는 중앙처리장치라도 FPU을 사용하지 않고 정수형 계산 함수를 사용할 수 있도록 컴파일 옵션을 설정할 수 있다. FPU가 없는 중앙처리장치라면 함수로 실수 계산을 할 수밖에 없다. 정수형 ALU을 사용하여 계산하는 것이기 때문에 속도에 부담이 될 수도 있다. 실수형의 각 부분을 나누어 복잡한 정수계산을 통해 실행되도록 함수를 구성한다. 보통 8비트 중앙처리장치는 거의 FPU가 없기 때문에 대부분 함수를 사용한 실수 연산을 한다. 동시에 컴파일러가 어디까지 실수형을 지원하는지 확인해야 한다. 보통 float만을 지원하는 컴파일러가 많다.[4]
문자형[편집]
C 및 C++ 프로그래밍 언어에서의 char는 8비트 정수형 처리 변수로 'character'의 약자이다. C언어 정수형의 처리에서 부호가 있는 sign형과 부호가 없는 unsigned형으로 선언하여 사용할 수 있다. 부호가 있는 변수는 signed와 결합하여 선언하고, 부호가 없는 경우는 unsigned와 결합하여 선언 한다. signed나 unsigned의 결합 없이 char로만 선언하면 이행에 따라 signed와 unsigned 중 하나로 결정된다. 부호가 있는 정수형은 2의 보수 체계를 사용하여 +와 -로 나누어 숫자를 표현할 수 있다. char는 8비트 변수 이므로 부호형 변수는 -128~127까지의 숫자를 취급할 수 있다. 중앙처리장치가 해당변수를 처리할 때는 해당 변수의 메모리 위치의 숫자를 중앙처리장치의 레지스터로 가져와 ALU를 통해 계산할 수도 있다. 계산 결과는 레지스터로 저장되고 다음 프로그램 코드에 따라 사용 된다. 모든 중앙처리장치는 8비트 단위의 처리가 가능하므로 중앙처리장치의 레지스터 및 ALU을 통해 한번의 계산에 의해 이루어진다. 계산의 종류는 사칙연산 뿐아니라 논리연산, 비트 쉬프트 등 다양한 연산을 ALU을 통해 이루어진다. 글자에서의 의미로 보면 아스키(ASCII)의 문자형을 취급하여 계산하거나 처리 한다.[5]
부호지정[편집]
부호지정에는 signed와 unsigned가 있다. signed는 C/C++ 프로그램 언어에서 정수형 변수 중 부호를 갖는 변수를 선언 한다. 정수형 중 음수는 2의 보수 체계를 사용하므로 이 키워드에 의해 부호를 사용할 수 있도록 변수 선언할 수 있다. 그러나 정수형의 변수에서 unsigned가 없으면 음수를 사용할 수 있는 부호를 갖는 정수형이 된다. 따라서 프로그램에서는 이 키워드는 많이 사용은 하지 않는다. unsigned는 C/C++ 언어에서 사용되는 지정자로 정수형과 같이 사용되어 부호 비트를 제거해 저장 가능한 양수 범위를 두배로 늘이는 역할을 한다. char와 int의 signed 정수형 변수에서 MSB가 부호 비트이다. 1이면 음수이고 0이면 양수이다. 그러나 unsigned을 사용하면 음수를 사용하지 않겠다는 의미 이므로 부호 비트가 필요 없다. 따라서 이진수와 같은 십진수가 된다.[6]
연산문[편집]
사칙연산자(+, -, *, /)나 할당연산자(=)와 같은 연산자를 사용하여 계산을 하고 값을 할당하는 명령문이다. 연산문은 가장 많이 사용하는 명령문 형식이며, i = i +1; 이나 num3 = num1 - num2; 와 같은 명령문이 연산문이다.[1]
함수[편집]
함수는 뒤에 괄호가 있으며 그 괄호 안에 인수를 기술할 수 있다. 우리가 사용했던 printf() 함수가 대표적인 예다. C 언어가 제공하는 이런 함수를 사용할 수도 있고, 내가 직접 함수를 만들어서 사용할 수도 있다.[1] 호출된 함수를 나타내는 표현식은 함수에 대한 유형 포인터를 가져야한다. 보이드(void)를 반환하거나 배열 유형이 아닌 객체 유형을 반환한다. 호출된 함수를 나타내는 표현식에 프로토타입을 포함하는 유형이있는 경우, 인수는 매개 변수의 수와 일치해야한다. 해당 값이 규정되지 않은 버전의 매개 변수 유형은 객체에 할당시킬 수 있는 유형이다. 호출된 함수를 나타내는 표현식에 프로토 타입, 정수 승격은 각 인수에 대해서 수행된다. float 유형은 double로 승격된다. 이를 기본 인수라고합니다. 인수 개수가 매개 변수 개수와 같지 않으면 동작하지 않는다. 함수가 프로토 타입을 포함하는 유형으로 정의 된 경우 프로토타입이 줄임표로 끝나거나 다음 인수 유형이 매개 변수 유형과 호환되지 않으면 동작하지 않는다. 함수가 프로토 타입을 포함하지 않는 유형으로 정의되고 승격 후의 인수는 다음 매개 변수의 인수와 호환되지 않는다.[7]
제어문[편집]
제어문에는 조건에 따라 명령문의 실행여부를 결정하는 조건문과 일정한 명령문들을 반복해서 실행하는 반복문이 있다. 조건문은 if, switch 등이 있으며, 반복문은 for, while, do while 등이 있다.[1]
조건문[편집]
c언어의 조건문의 종류에는 주로 사용하는 것이 if문과 switch ,case문이 있다.
if[편집]
if 문의 제어 표현식은 스칼라 유형을 가져야한다. 두 형식 모두 식이 0과 같지 않은 경우 첫 번째 하위 문이 실행된다. else 형식에서 표현식이 0과 같으면 두 번째 하위 문이 실행된다. 레이블을 통해 첫 번째 하위 문에 도달하면 두 번째 하위 문이 실행되지 않는다.[7]
if(조건식) {} if(조건식) { } else { }
switch[편집]
switch문의 제어 표현식은 정수 유형이어야한다. switch문이 가변적으로 수정된 유형의 식별자 범위 내에서 연관된 case 또는 기본 레이블을 갖는 경우 전체 switch 문은 해당 식별자의 범위 내에 있어야한다. 각 case 레이블의 표현은 정수, 상수 표현이어야하며 동일한 switch 문에서 두 개의 case 상수 표현은 변환 후 동일한 값을 가져서는 안된다. switch 문에는 최대 하나의 기본 레이블을 가질 수 있다. switch 문은 제어 표현식의 값과 기본 레이블의 존재 여부 및 스위치의 모든 케이스 레이블 값에 따라 스위치 본문인 명령문으로 제어를 이동 시키거나 넘길 수 있게 한다. 케이스 또는 기본 레이블은 가장 가깝게 둘러싸인 switch 문 내에서만 액세스할 수 있다. 정수 승격은 제어 표현식에서 수행된다. 각 케이스 레이블의 상수 표현식은 제어 표현식의 승격 유형으로 변환된다. 변환된 값이 승격 된 제어 표현식의 값과 일치하면 제어는 일치하는 케이스 레이블 다음의 명령문으로 이동한다. 변환된 대소 문자 상수 표현식이 일치하지 않고 기본 레이블이 없으면 스위치 본문의 일부가 실행되지 않는다.[7]
반복문[편집]
for문의 선언 부분은 스토리지 클래스 auto 또는 register를 갖는 객체에 대한 식별자만 선언해야한다. 반복문은 제어 표현식이 0과 같을 때까지 루프 본문이라는 문이 반복적으로 실행되도록 한다. 반복문에서 루프 본문이 입력되었는지 또는 점프에 의해 입력되는지에 관계없이 반복이 발생한다. 반복 문은 범위가 둘러싸는 블록 범위의 엄격한 하위 집합인 블록이다. 루프 본문은 범위가 반복 문의 범위의 엄격한 하위 집합인 블록이기도 하다.[7]
for(조건식) { }
while[편집]
while문은 조건식이 true일 경우에 계속해서 반복하는 문법이다. 조건식에는 비교 또는 논리 연산식이 줄로 오는데 조건식이 false가 되면 반복을 멈추고 while문을 종료한다. while문은 조건식이 true라면 실행문을 실행시킨다. 블록안에 증감문은 넣어주어도 되고 안넣어주어도 되는데 증감식을 넣어주지않게 되면 무한루프에 빠지게 된다. while문의 가장 큰 장점은 무한루프를 만들기 쉽다는 것이다. 프로그램을 작성하다보면 일단 무한루프를 만들어놓고 어떤 특정 입력이나 조건이 들어왔을 때 무한루프를 빠져나오게하는 방식으로 프로그램을 작성할 때가 있다. 이 때, for문보다 while문이 유용하다.[8]
while(조건식) {}
do~while[편집]
do ~ while문은 while문과 비슷하지만 한 가지 차이점이 있는 반복문이다. do를 한 후 while을 한다. while의 경우 조건식을 검사하여 반복을 실해하지만, do~ while의 경우에는 do 안에 있는 코드를 적어도 한 번 실행한 후 조건식을 검사하여 반복을 실행하게 된다. [9]
do { } while(조건식){ }
각주[편집]
- ↑ 1.0 1.1 1.2 1.3 1.4 담담, 〈2.4 C 명령문의 종류(C 언어)〉, 《네이버 블로그》, 2019-04-05
- ↑ 2.0 2.1 2.2 2.3 2.4 2.5 2.6 2.7 hsyun, 〈전처리(preprocessor)〉, 《티스토리》, 2010-03-22
- ↑ C 언어 정수형 변수 위키백과 - https://ko.wikipedia.org/wiki/C_%EC%96%B8%EC%96%B4_%EC%A0%95%EC%88%98%ED%98%95_%EB%B3%80%EC%88%98
- ↑ C 언어 실수형 변수 위키백과 - https://ko.wikipedia.org/wiki/C_%EC%96%B8%EC%96%B4_%EC%8B%A4%EC%88%98%ED%98%95_%EB%B3%80%EC%88%98
- ↑ char 위키백과 - https://ko.wikipedia.org/wiki/Char
- ↑ signed와 unsigned 위키백과 - https://ko.wikipedia.org/wiki/Signed%EC%99%80_unsigned
- ↑ 7.0 7.1 7.2 7.3 ISO/IEC 9899:TC3, 〈WG14/N1256〉, 《Committee Draf》, 2007-09-07
- ↑ 코딩팩토리, 〈(C언어) While문 사용법 & 예제 총정리〉, 《티스토리》, 2019-07-23
- ↑ 반복문 do while goormedu - https://edu.goorm.io/learn/lecture/201/%EB%B0%94%EB%A1%9C-%EC%8B%A4%ED%96%89%ED%95%B4%EB%B3%B4%EB%A9%B4%EC%84%9C-%EB%B0%B0%EC%9A%B0%EB%8A%94-c%EC%96%B8%EC%96%B4/lesson/5983/%EB%B0%98%EB%B3%B5%EB%AC%B8-do-while
참고자료[편집]
- 담담, 〈2.4 C 명령문의 종류(C 언어)〉, 《네이버 블로그》, 2019-04-05
- hsyun, 〈전처리(preprocessor)〉, 《티스토리》, 2010-03-22
- C 언어 정수형 변수 위키백과 - https://ko.wikipedia.org/wiki/C_%EC%96%B8%EC%96%B4_%EC%A0%95%EC%88%98%ED%98%95_%EB%B3%80%EC%88%98
- C 언어 실수형 변수 위키백과 - https://ko.wikipedia.org/wiki/C_%EC%96%B8%EC%96%B4_%EC%8B%A4%EC%88%98%ED%98%95_%EB%B3%80%EC%88%98
- char 위키백과 - https://ko.wikipedia.org/wiki/Char
- signed와 unsigned 위키백과 - https://ko.wikipedia.org/wiki/Signed%EC%99%80_unsigned
- ISO/IEC 9899:TC3, 〈WG14/N1256〉, 《Committee Draf》, 2007-09-07
- 코딩팩토리, 〈(C언어) While문 사용법 & 예제 총정리〉, 《티스토리》, 2019-07-23
- 반복문 do while goormedu - https://edu.goorm.io/learn/lecture/201/%EB%B0%94%EB%A1%9C-%EC%8B%A4%ED%96%89%ED%95%B4%EB%B3%B4%EB%A9%B4%EC%84%9C-%EB%B0%B0%EC%9A%B0%EB%8A%94-c%EC%96%B8%EC%96%B4/lesson/5983/%EB%B0%98%EB%B3%B5%EB%AC%B8-do-while
같이 보기[편집]