C언어 복습하기 3회차 - 서식 입출력


이 글은 C programming : a modern approach를 바탕으로 공부한 내용을 정리한 것입니다.

오늘 공부할 내용은 서식 입출력에 관한 내용이다. printfscanf에 관한 내용을 다룰 것이다. 이번 챕터에서는 해당 함수들의 간단한 부분만 공부하고 나중에 다시 입출력에 관한 내용을 다룰 예정이다.

목차

  1. 서식입출력
    3.1 printf
    3.2 scanf
    Q & A

3.1 printf


printf 함수는 서식 문자열_format string_이라고 불리는 문자열을 문자열의 특정 부분에 추가된 값과 함께 출력하는 기능을 수행한다.

printf(string, expr1, expr2, ...);

printf가 호출되려면 서식 문자열과 출력을 할 때 삽입되어야하는 값을 공급해주어야 한다.
출력되는 값들은 상수일 수도, 변수일 수도, 혹은 매우 복잡한 표현식일 수도 있다. 서식 문자열은 일반 문자열과 %로 시작되는 변환 규격_conversion specification_을 둘 다 포함할 수 있다. 변환 규격은 출력할 때 채워져야 하는 값을 대신하는 기호나 텍스트의 일부이다.

예시

int i = 10;
int j = 20
float x = 43.2892f;
float y = 5527.0f;

printf("i = %d, j = %d, x = %f, y = %f\n", i, j, x, y);

// 출력
// i = 10, j = 20, x = 43.289200, y = 5527.000000

주의할 점

C 컴파일러들은 서식 문자열에서의 변환 규격의 개수와 출력되는 것들의 개수가 같은지를 반드시 확인하지 않는다.
printf(%d %d\n", i);i`의 값은 제대로 출력하고 아무런 의미없는 정수값을 출력할 것이다.
변환 규격의 개수보다 출력할 값의 개수가 더 많은 경우에는 변환 규격 개수만큼만 출력이 일어난다.

2.2 프로그램의 일반적 구조

Q & A


GCC의 약자는 뭔가요?

GNU C Compiler의 약자였는데 현재는 GNU Compiler Collection의 약자로 바뀌었다. GCC가 C 외에도 Ada, C, C++, Fortran, Java, Objective-C 같은 언어를 컴파일 하기 때문에

컴파일러는 주석을 어떻게 인식하나요?

a/**/b = 0;
예전에는 ab = 0;으로 해석했지만 현재에는 a b = 0으로 해석한다. 컴파일러는 주석을 공백으로 인식한다.

부동소수점 상수 끝에 f를 붙이는 이유

소수점을 포함하지만 f가 붙지 않은 상수는 double 형이 될 수 있습니다. double은 float 보다 2배 정밀도를 갖는 type으로 float이 저장할 수 없는 수가 할당되려고 할 수도 있기 때문

C언어 복습하기 2회차 - C 기초**


이 글은 C programming : a modern approach를 바탕으로 공부한 내용을 정리한 것입니다.

오늘 공부할 내용은 전처리 지시자, 함수, 변수, 구문 등 기본적인 내용이다. 이번 챕터의 내용은 간단히 알면 되는 것이고 변수형과 scanf 같은 함수는 이후에 다시 나올 것이므로 자세하게 설명하지 않고 넘어간다.

목차

  1. C 기초
    2.1 프로그램 컴파일과 링크
    2.2 프로그램 일반적 구조
    2.3 주석
    2.4 변수
    2.5 scanf
    2.6 상수 이름 정의하기
    2.7 식별자
    2.8 프로그램의 레이아웃
    Q & A

2.1 프로그램 컴파일과 링크

문장 출력하는 프로그램


To C, or not to C: that is the question.
위의 문장을 출력하는 프로그램을 만들 것이다. 이 프로그램은 pun.c에 쓰여진다.

#include <stdio.h>

int main(void)
{
printf("To C, or not to C: that is the question.\n");

return 0;
}

#include는 라이브러리 정보를 불러오기 위함이다. 여기서는 stdio.h라는 표준 입출력 라이브러리 정보를 가져온다. 이 안에 printf가 있다.
프로그램에서 사실상 실행되는 코드는 main에 존재한다. \\n 은 다음 줄로 넘긴다는 의미가 된다. 마지막 줄의 return 0;은 프로그램이 종료될 때 운영체제에 0이라는 값을 반환하는 것을 의미한다.

컴파일과 링크


pun.c파일을 컴퓨터는 바로 실행하지 못한다. c 언어의 경우 보통 전처리, 컴파일, 링크의 과정이 필요하다.

전처리Preprocessing **
#으로 시작하는 지시어directive로 알려진 줄들의 지시를 먼저 따른다.

컴파일Compile *
전처리를 거친 프로그램은 컴파일러를 통해 오브젝트 파일로 번역이 된다.
*링킹Linking
**
오브젝트 파일이 완벽하게 실행하기 위해 라이브러리 내부의 명령문 같은 추가적인 코드를 합친다.

UNIX에서는 C 컴파일러를 cc라고 부른다.

% cc pun.c

위의 명령문으로 pun.c를 컴파일과 링킹까지 완료된다. 이 경우 a.out이라는 실행 파일이 만들어진다.

GCC 컴파일러


GCC 컴파일러는 가장 유명한 C 컴파일러이다. 리눅스에서는 기본 제공되고 다른 환경에서도 사용할 수 있다.

통합개발환경 IDE


하나의 프로그램에서 코드를 수정, 컴파일, 링킹과 디버깅까지 해주는 개발환경을 말한다.

2.2 프로그램의 일반적 구조


C 프로그램의 기본 구조

*directive*

int main(void)
{
*statements*
}

지시자directive


C 프로그램이 컴파일되기 직전 전처리기에 의해 처음으로 수정된다. 전처리기가 수행하는 명령문들을 지시자라고 한다.
지시자에서는 ;를 사용하지 않는다.

함수function


반환형 함수명(parameter){
statement
}
인자를 받아와서 구문에 따라서 동작한 후 정해진 반환형을 반환한다.

구문statement


프로그램이 실행될 때 실행되어야 하는 명령들이다.
pun.c에서는 printf("문장");return 0;가 구문이다. C언어에서 구문은 ;로 끝나야 한다.

2.3 주석comment


주석은 프로그램 안에서 프로그램에 대한 설명이나 명령들에 대한 설명을 적는 것이다.
한 줄 주석은 //로 작성할 수 있고 여러 줄의 주석은 /* */로 작성한다.
주석은 실행되지 않는다.
(//로 주석을 적는 건 C99를 사용하는 경우이다.)

/* 
주석1    
주석2
주석3
*/
// 주석4

2.4 변수와 할당

type


모든 변수들은 반드시 type을 가져야 한다. 데이터를 저장하는 형태와 크기가 type에 따라 달라진다.

선언declare


변수들은 반드시 선언 과정이 필요하다.

type name;

구식 컴파일러에서는 구문들 사이에서 선언을 할 수 없으므로 주의해야한다.
하지만 C99를 사용한다면 변수가 필요한 순간 직전에 변수를 선언하는 것이 보편적이다.

할당assignment


할당은 변수에 값을 저장하는 것을 의미한다.

int height;    // 선언
height = 8;    // 할당

초기화initializaion


기본 설정값이 없는 변수는 초기화되지 않았다고 한다. 컴파일러에 따라 프로그램이 중단되기도 한다. 초기값을 부여하는 방법은 변수에 값을 할당해주는 것이다.

int height = 8;
int height = 8, length = 12;    // 여러 변수에 각기 여러 값 할당이 가능
int height, length = 10;    // length만 10으로 초기화되고 height는 선언만 되었다.

2.5 scanf


printf()는 출력하는 함수라면 scanf()는 입력을 받는 함수이다. 두 함수에서 f는 formatted의 약자이다.

scanf("%d", &i); // 정수를 입력받아 i에 저장

%d 는 int 형을 의미하고 &는 나중에 알아보도록 하겠다.

2.6 상수 이름 정의하기


프로그램 내에서 절대 값이 변하지 않는 상수를 사용한다면 상수에도 이름을 지어주는 것이 좋다. 예를 들어서 일한 시간에 따른 임금을 구할 때 사용할 수 있다.

#define money_per_hour 8720

int main(void){
    int hour = 8
    money = hour * money_per_hour
}

위와 같이 상수도 이름을 정해주게 되면 코드의 가독성이 높아지게 된다. 시급을 모르는 사람이 보더라도 이해하기 쉬워진다.

2.7 식별자identfier


프로그램을 작성할 때 변수, 함수, 매크로의 이름들을 식별자라고 부른다. C에서는 문자, 숫자, _ 를 사용 가능하고 숫자로 시작할 수는 없다.

가능 불가능
times10 10times
get_next_char get-next-char
_done  

C에서는 식별자를 대부분 소문자로만 작성하고 가독성을 위해 언더바 _ 를 사용한다. Jave나 C#, C++ 같은 경우에는 언더바보다는 첫 번째 글자를 대문자로 적어준다.
어떤 방법을 선택하던지 항상 통일 시키는 것이 중요하다. 식별자 글자 수에 제한이 없으므로 최대한 구체적으로 사용하는 것이 좋다.

키워드keyword


auto enum restrict unsigned
break hextern return void
case float short volatile
char for signed while
const goto sizeof _Bool†
continue if static _Complex†
default inline† struct _Imaginary†
do int switch
double long typedef
less register union

위의 표에 있는 키워드들은 식별자로 사용이 불가능하다. 컴파일러에 따라 error나 경고가 뜰 수도 있다.
( 나는 ATmega128과 관련해 프로그램을 만들 때 mode라는 변수를 사용했고 에러가 나지도 않았지만 원하는 대로 프로그램이 동작하지 않았고 디버거로 한 줄씩 실행을 하면서 발견한 경험이 있다.)

2.8 C 프로그램의 레이아웃


이 책에서 C 프로그램은 토큰token의 연속이라고 표현한다. 토큰은 의미를 가진 최소 단위이다.

printf("Height: %d\n", height);
printf ( "Height: %d\n" , height ) ;

이렇게 7개의 토큰으로 구성되어 있다. 토큰 사이의 공백은 가독성을 높여준다. 같은 이유로 연산자마다 줄을 띄워 주는 것도 좋은 방법이다.
빈 줄은 프로그램을 잘게 쪼개어 주어서 이해하기 편하게 만들어 주기도 한다.

int main(void)
{
    float fahrenheit;    // 변수의 선언
    float celsius;

    printf("Enter Fahrenheit temperature: ");    // 화씨 값 입력받기
    scanf("%f", &fahrenheit);

    celsius = (fahrenheit - FREEZING_PT) * SCALE_FACTOR;    // 섭씨로 변환하기

    printf("Celsius equivalent: %.1f\n", celsius);    // 섭씨 값 출력

    return 0;
}

Q & A


GCC의 약자는 뭔가요?

GNU C Compiler의 약자였는데 현재는 GNU Compiler Collection의 약자로 바뀌었다. GCC가 C 외에도 Ada, C, C++, Fortran, Java, Objective-C 같은 언어를 컴파일 하기 때문에

컴파일러는 주석을 어떻게 인식하나요?

a/**/b = 0;
예전에는 ab = 0;으로 해석했지만 현재에는 a b = 0으로 해석한다. 컴파일러는 주석을 공백으로 인식한다.

부동소수점 상수 끝에 f를 붙이는 이유

소수점을 포함하지만 f가 붙지 않은 상수는 double 형이 될 수 있습니다. double은 float 보다 2배 정밀도를 갖는 type으로 float이 저장할 수 없는 수가 할당되려고 할 수도 있기 때문

이 포스팅은 K.N.King의 C programming : a modern approach를 참고하여 만들었습니다.

  C 언어의 유래

C언어는 Bell Lab의 Ken Thompson, Dennis Ritchie 등이 만들었다.

당시의 다른 운영체제들 처럼, UNIX도 어셈블리어로 제작됨

어셈블리어로 제작된 프로그램들은 디버깅과 성능 업그레이드가 힘들어서 고급 언어가 필요했고 B언어를 만들었다.

B언어는 PDP-11이라는 컴퓨터에 잘 맞지 않았고 조금 더 발전된 New B(NB)를 만들었는데 B와는 형태가 많이 달라서 C언어라고 부르게 되었다.

1973년이 되자 UNIX전체를 C로 프로그래밍 했고 당시 C의 가장 큰 장점은 확장성이었다.

 


 C 기반 언어들

C++ 은 C의 특징을 많이 가지고 있는 언어이다.

Java는 C++을 베이스로 만든 언어이기 때문에 C의 특징을 많이 물려받았다.

C# 은 C++과 Java를 본 떠 만들었다.

이러한 언어들을 배울 때 C의 특징을 알면 조금 더 이해하기 쉽다는 장점이 있다.


 C의 특징과 장단점

C언어의 본 용도는 운쳥체제나 시스템 소프트웨어를 제작하는 것이다. C는 Low level language이다.

운영체제처럼 시스템을 제어하는 언어들은 바이트 단위와 메모리 주소 값 등의 기계 수준의 개념까지 다룰 수 있어야 한다.

대부분의 다른 언어에서는 직접 제어하지 않고 미리 짜인 알고리즘에 의해 작동한다.

C로 짠 프로그램들은 매우 빨라질 수 있다.

C는 작은 언어. 다른 언어들에 비해 매우 한정된 특징들을 제공한다. C언어는 표준 함수들로 이뤄진 라이브러리에 매우 크게 의존한다.

C는 관대한 언어이다. C는 다른 언어들에 비해 좀 더 큰 자유를 선사한다. 에러가 발생했을 때 구체적으로 무엇이 일어났는지에 대해 알려주지 않는다.

 장점

1. 효율성 - 어셈블리어를 대체하기 위해 만들어 졌기 때문에 한정된 메모리 내에서 빠르다.

2. 확장성 - 다양한 컴퓨터에서 프로그램이 실행 가능하다. 규격화 되어있다.

3. 강력함 - 다양한 자료형들과 연산자들은 C를 강력한 언어로 만들어 주었다.

4. 유연성 - 시스템 프로그램을 위해 만들어졌지만 임베디드 시스템이나 데이터 처리등 여러 응용프로그램을 제작하는데 사용된다. 다른 언어에서는 허용되지 않는 기능이 C 언어에서는 대부분 허용된다.

표준 라이브러리

UNIX와의 통합 - UNIX의 기능들은 사용자가 C를 할 줄 안다는 전제하에 제공되기도 한다.

 

단점

에러가 쉽게 난다.

실행하기 전까진 에러가 있는지 없는지 모른다. 

이해하기 어려울 수 있다.

수정하기 어려울 수 있다. 다른언어들은 클래스나 패키지로 잘게 나누어서 관리가 용이한데 C는 그런 기능이 없다.

+ Recent posts