'c언어'에 해당되는 글 2건

  1. 2013.08.04 1. 입력과 출력
  2. 2013.07.07 0. 들어가면서
Hello world!

프로그래밍 언어를 배울 때 처음 하는 일은?

바로 Hello world!를 찍는 일이다.

#include <stdio.h>

int main()
{
	printf("Hello world!\n");
	return 0;
}

다음과 같이 하면 콘솔창에 Hello world가 찍힌다.


사실 입력과 출력은 다양한 곳에서 일어난다. 파일에서 읽으면 파일입력이 되는 것이고, 네트워크 통신에서 소켓을 통해 데이터가 들어온다면 외부로부터의 입력이 되는 것이다.


c를 처음 배울 때 콘솔에서 입력과 출력을 다루는 것은 바로 표준입출력을 사용하는 것이다.


표준입력을 받을 때 보통 scanf를 이용한다.


#include <stdio.h>

int main()
{
        int num;
        char str[128];

        scanf("%d", &num);
        printf("num=%d\n", num);

        scanf("%s", str);
        printf("str=%s\n", str);

        return 0;
}

여기서 보면 어떤 데이터 타입을 입력/출력 하느냐에 따라 입력/출력 형식이 약간 달라진다는걸 볼 수 있다.


예를들어 정수형 변수를 입력 받을 때는 %d를, 문자열을 입력 받을 때는 %s를 사용한다.


마찬가지로 문자를 입력받을 때는 %c를 사용하고, 부동소수점 형식을 표현할 때는 %f를 사용한다.


이런 형식지정은 일종의 약속이다. 저 형식에 따라 입력/출력을 처리하는 방식에 차이가 있기 때문이다.


예전에 게시판에 왜 정수형을 받을 때는 &을 붙이고 문자열을 받을 때는 &를 안붙이냐는 질문이 올라왔었다.


간단히 말해서 scanf에는 변수의 주소 값을 넘겨줘야 한다. 변수앞에 &를 붙이면 그 변수의 주소값이 된다.


그럼 문자열은? 배열형태로 변수를 선언하면 문자열 변수이름 자체가 주소값을 갖게 된다. 그러니까 &를 붙일 필요가 없는 것이다.


이렇게 명시적으로 메모리 주소값을 표현하는 것 또한 c언어의 특징이다.


이런 사용법을 보면 내부적으로 어떻게 처리하는지 대충 짐작이 가능하다.


%d로 형식을 지정한 경우 넘겨진 메모리 주소부터 +4바이트까지 입력된 값을 저장할 것이다.


%s로 형식을 지정한 경우 넘겨진 메모리 주소부터 차례로 1바이트씩 값을 저장하고 마지막에 '0'을 넣어줄 것이다.


scanf의 위험


예제에서, 만약 사용자가 배열의 크기를 벗어난만큼 입력을 하면 어떻게 될까?


배열의 크기를 작게하고 테스트 해보면 알겠지만 Segmentation fault가 발생한다. 허용한 메모리의 범위를 넘어갔기 때문이다.


fgets처럼 최대 입력 길이를 지정할 수 있는 함수를 사용하면 이런 문제를 피할 수는 있을 것이다.


문자열로부터 입력, 문자열로 출력


sscanf(), sprintf() 라는 함수가 있다.


프로그래밍 하다보면 문자열에서 어떤 값을 취하거나, 일련의 값들을 문자열 형태로 출력하고 싶은 경우가 있다.


이 때 유용하게 사용되는 함수들이다. 다음 예제를 참고하자.

#include <stdio.h>

int main()
{
        int num;
        char inputStr[]="10 test", str[16];
        char outputBuff[128];

        sscanf(inputStr, "%d %s", &num, str);
        printf("%d,%s\n", num, str);

        sprintf(outputBuff, "num[%d],str[%s]", num, str);
        printf("%s\n", outputBuff);

        return 0;
}


출력형식 지정


printf() 함수를 잘 보면, 출력형식을 지정하는 부분 또한 문자열이라는 것을 알 수 있다.


printf("%d %s", ....) 


예전에 프로젝트를 진행할 때 저 출력형식을 동적으로 변경시키고 싶었던 적이 있다.

(컴파일 과정 없이 실행중에)


예를들어, 어느 파일에 출력형식을 적어놓고 프로그램에서는 파일에 기술된 형태로 출력하게 하려는 것이었다.


그래서 출력형식 부분을 변수로 지정해보았는데 잘 되었다. 저 부분도 역시 변수라는 것이다.


다음 예제를 보자.


#include <stdio.h>

void formatTest(char *format, int num)
{
        printf(format, num);
}

int main()
{
        formatTest("num=%d\n", 10);
        formatTest("num[%d]\n", 10);
        formatTest("count per second[%d]\n", 10);
        return 0;
}


'프로그래밍언어 > C' 카테고리의 다른 글

0. 들어가면서  (0) 2013.07.07
Posted by DevMoon
,

나는 몇 개월전 까지 C언어에 익숙했다. 


대학때도 주로 C를 사용했고, 취업한 후에도 근 3년간 C언어를 사용했다.


이제는 알고리즘 문제를 풀때를 제외하고는 거의 사용하지 않아 정리를 해보려 한다.


그래서,


다루고 싶은 주제만, 경험에 맞추어 쓰려고 한다.


사실 아주 자세한 내용은 널리고 널렸다. 여기서까지 굳이 그런 내용을 써야할까 싶다.


그냥 떠오르는데로, 주로 사용했거나 강조하고 싶었던 내용들을 정리하고싶다.


누군가가 포스팅을 보고 문제를 해결하거나 이해하는데 도움이 된다면 그걸로 족하다.


나중에 다루고 싶은 주제가 나타나거나 누군가의 질문인데 중요한 것이라면 추가로 기술할 생각이다.


들어가면서 하고 싶은 이야기가 있다.


우리는 왜 컴퓨터 언어를 배우는가?


당연한 이야기지만 컴퓨터에게 무언가 시키기 위해 배운다.


(가장 좋은 방법은 컴퓨터가 사람이 하는 말을 알아먹는 것 아닐까?)


이런 면에서 컴퓨터 언어는 마치 번역기와도 같다고 볼 수 있을 것같다. 


컴퓨터가 알아먹는 0101010.. 을 입력하지 않고 사람이 알아볼 수 있는 표현을 기술하면 대충 알아먹으니 말이다.


C 언어 역시 직관적인 표현이 존재한다.


가정 - if 문

반복 - for, while

숫자 - int, double, float

문자 - char

...


이런 것들을 조합해서 프로그램을 만들 수 있다. 


갑자기 이런 이야기를 꺼낸 이유는 C언어(를 비롯한 다양한 고차원 언어)가 


어느정도 자연어와 직관적으로 연관되어 있다는걸 강조하고 싶어서다.


그냥 사용법만 바로 알아서 사용하는 것보다 한 번 짚고 넘어가는게 아무래도 이해하는데 좋지않아서랄까..


(아님 말고)


'프로그래밍언어 > C' 카테고리의 다른 글

1. 입력과 출력  (0) 2013.08.04
Posted by DevMoon
,