과제 #1 입출력,연산자

언어로그/C/C++ 2011. 6. 13. 23:01



#1 온도변환 : 화씨, 섭씨
화씨 온도(F)를 입력 받은 후 섭씨 온도(C)로 계산하여 출력하는 프로그램
C = 5/ 9 * (F -32)

화씨 온도를 입력하세요 : 85
섭씨 온도는 29.4도 입니다.

1_temperature.c


#2 원의 넓이 구하기
사용자 입력으로 원의 반지르을 입력받고, 원의 넓이를 구하는 프로그램
원의 넓이 = 반지름 * 반지름 * 3.14159

원의 반지름을 입력하세요 : 10.5
원의 면적 346.36

2_circle_breadth.c


 
#3 신체질량지수(BMI)
몸무게와 키를 입력받고, 신체질량지수(BMI)를 구하는 프로그램 작성. BMI는 비만도를 측정하는 한가지 방법.
BMI = 몸무게(kg) / 키(m)의 제곱

몸무게를 입력하세요( kg) : 62
키를 입력하세요(m) : 1.75
당신의 BMI는 : 20.2입니다.

3_bmi.c


#4 거리 및 속력계산
거리(km)와 속력(km/h)을 입력받고, 해당 거리를 속력으로 달릴 때 걸리는 시간 출력 프로그램 작성.
거리, 속력은 실수. 시간은 시간, 분까지 계산 출력. 초는 소수점 이하 셋째 자리까지 출력

거리(km)을 입력하세요 : 100
속력(km/h)을 입력하세요 : 85

걸리는 시간은 : 1시간, 10분, 35.294초 입니다 

4_velocity.c


#5 자판기 잔돈계산
커피 자판기에 입력받은 돈으로 거스름돈 계산 하는 프로그램 작성
커피 값은 150원
지폐는 1000단위만 입력가능.
거스름 돈은 500원, 100원, 50원, 10원.
자판기가 내주는 동전의 종류와 수를 계산하시오

돈을 입력하세요 : 1000

잔돈 드릴게요 ..
500원짜리 동전 1개
100원짜리 동전 3개
 50원짜리 동전 1개
 10원짜리 동전 0개

5_vending_machine.c

라인 입출력 함수

언어로그/C/C++ 2011. 3. 27. 21:07



라인단위로 입출력을 다루는 함수들에 대해서 알아보자.  널문자를 삽입해주는지 여부와 버퍼에서 개행문자를
제거하는지 여부에 주목하여 보자. 


scanf(const char *TEMPLATE, ...)
scanf 함수를 사용하여, 한 라인의 문자열을 읽을 수 있지만, 개행문자를 표준입력버퍼에 남겨놓는다.  
연이은 읽기 동작에 오동작을 초래할 수 있기때문에, 입력버퍼에서 개행문자를 제거하는 것을 잊지 말자!



char* fgets(char *S, int COUNT, FILE *STREAM)
지정한 입력버퍼에서 최대 COUNT-1 개의 문자를 읽되, 엔터를 칠때까지  배열  S에 저장하는 함수이다. 
배열의 공간이 충분하다면, 개행문자와 함께 널문자를 삽입한다. (엔터에 의해 종료) 
하지만 공간이 충분하지 않다면,  COUNT-1개의 문자와 널문자를 삽입하고 종료한다. (사이즈 제약의 의해 종료)



int fputs(const char *S, FILE *STREAM)
버퍼 S의 내용을 지정한 출력버퍼에 출력하는 함수로, 널문자를 개행문자로 변환하지 않는다.  




fgets와 fputs 보다는 덜 사용되지만 라인단위로 입출력을 할 수 있는 다음과 같은 함수가 있다. 
char* gets(char *S)
표준 입력버퍼에서 개행문자를 만날 때까지 읽는 함수로,  개행문자는 S에 저장하지 않지만, 입력퍼버에서는 제거한다




int puts(const char *S)
S 문자열을 표준출력버퍼에 출력하는 함수로 널문자를 만나면 개행문자로 변환하여 출력한다. 

'언어로그 > C/C++' 카테고리의 다른 글

음수의 표현  (0) 2011.06.13
문자열 조작함수 직접 구현하기  (2) 2011.04.29
라인 입출력 함수  (0) 2011.03.27
배열의 이해  (0) 2011.03.27
기억부류(Storage Class) / 변수  (0) 2011.03.27
전역변수와 지역변수  (0) 2011.03.27

함수의 이해

언어로그/C/C++ 2011. 3. 27. 20:10




함수가 필요한 이유?
중복된 작업을 함수로 분리하면,  한번 작성으로 여러번 사용할 수 있어서 효율적인 프로그램이 된다.
또한 큰 문제를 작은 문제들로 나누어 이해하기 쉬워지며, 수정사항이 발생하면 함수 부분만 수정하면
되기 때문에 유지보수도 용이해진다. 


 
함수의 원형(프로토타입)과 정의
C언어에서 함수는 원형(프로토타입)과 정의로  분리된다.  함수의 원형(프로토타입)은 보통 헤더파일이나
메인함수 이전에 선언이 되며,  컴파일러에게 이러 이러한 함수를 아래에 정의했으니까 메인함수 또는 특정함수에서 
이 함수를 사용해도 됨을 알려주는 것이다. 
함수의 정의는 실제적으로 함수가 하는 일을 기술하는 부분이다.  C언어에서는 함수의 시그니처로 함수의 이름만을
사용하기 때문에, 파라미터의 타입과 반환값의 타입이 달라도 동일한 이름의 함수를 사용 할 수  없다.


#include <stdio.h>
 
void swap(int , int);// 함수원형(프로토타입)   

int main() {
...
return 0;
}

void swap(int a, int b) {   // 함수의 정의         
...
}





Call By Value vs Call By Reference
함수 호출시 파라미터를 넘기는 방식에 따라  Call By Value 또는 Call By Reference 라고 구분한다.
함수 호출시 변수들의 데이터(값)가 복사되는데, 함수 내에서 이 복사된 변수에  대한 조작은 원본 변수에
에  아무런 영향을 미치지 못하는데 이러한 호출방식을 Call By Value라고 부른다.   
파라미터로 변수의 주소를 넘기면, 피호출자 쪽에서는 이 주소를 조작하여 원본 변수의 데이터를 변경 할
수 있다. 이러한 호출방식을 Call By Pointer 또는 Call By Reference 라고 부른다.

 
Call By Value
#include <stdio.h>

main() {
    int a = 1, b = 5;
    swap(a, b);// 변수의 값을 전달함 
}

void swap(int a, int b)  {// main함수의 a, b는 변경되지 않음    
    int temp = a;
    a = b;
    b = temp      
}


Call By Reference 
#include <stdio.h>

main()  {
    int a = 1, b = 5;
    swap(&a, &b);// 변수의 주소를 전달함    
}
 
void swap(int *a, int *b)  { // main함수의 a, b가 변경됨    
    int temp = *a;
    *a = *b;
    *b = temp;
}

'언어로그 > C/C++' 카테고리의 다른 글

기억부류(Storage Class) / 변수  (0) 2011.03.27
전역변수와 지역변수  (0) 2011.03.27
함수의 이해  (0) 2011.03.27
포인터의 이해  (0) 2011.03.11
매크로, 연산자  (3) 2011.03.10
표준입출력함수 getchar() / putchar()  (0) 2011.02.22

C 언어 학습에 핵심. 변수와 상수

언어로그/C/C++ 2011. 2. 22. 11:18


 

C언어를 학습하는데 있어서 중요한 요소는 

  • 운영체제에게 어떻게 메모리를 확보해서 쓸 것인가?
  • 프로그램을 어떻게 효율적으로 작성할 것인가?
  • 어떻게 파일을 모듈화 할 것인가?

 

C언어는 빠른 실행속도를 장점으로 하는 언어이다. java 언어와 같은 객체지향 언어는 그 나름대로의
장점을 가지고 있지만,  낮은 성능과 제약된 자원을 갖는 시스템 혹은 빠른 속도를 필요로 하는 프로그램에

적합한 언어이다. 직접적으로 메모리에 접근할 수 있기 때문에 빠른 속도를 낼 수 있는 만큼, 메모리를 얼마나

잘 다루느냐가 C언어 프로그래밍의 중요한 화두이다.  효율적인 프로그래밍은 C언어 자체뿐 아니 컴퓨터에 대한

구조를 정확히 이해하고 있을 때 이루어질 수 있다.  효율적인 프로그램을 작성하는 것 만큼, 중요한 것이

어떻게 구조적으로 프로그램을 작성하는냐 이다. 요즘과 같은 규모가 대형화된 프로젝트에서는 프로그램에 대한

복잡도 감소와 관리를 용이하게 하는 것이 비용 절감에 중요한 요소이다. 

 

 

변수의 선언 , 상수?

변수란 프로그램에서 사용할 데이터를 담을 메모리 혹은 그릇을 의미하며, 변수를 선언한다는 것은 

이러한 메모리를 생성한다는 것을 의미한다.  변수 의미 자체는 '변하는 수' 로 이 메모리는 운영체제의 의해

할당되지만, 사용은 사용자가 하기 때문에 그 데이터가 변할 수 있다. 반면 상수는 운영체제가 메모리에 대한 

제어권을 가지고 있어서 사용자에 의해 변경될 수 없는 메모리 혹은 데이터를 의미한다.  

 

int a;

다음과 같은 문장은 정수형 데이터를 저장할 수 있는 4바이트의 메모리 공간을 할당하고, 그 메모리 공간을
a 라는 이름으로 접근하겠다고 운영체제에 말하는 것이다.

 

변수의 타입

변수의 타입에는 정수형, 실수형,  문자형 등... 다양한 타입들이 존재한다. 하지만 운영체제 입장에서 이것들은

수치값을 저장할 수 있는  크기가 다른 메모리 블럭에 해당할 뿐이다.  프로그래머들이 좀더 용이하게 프로그램을 작성할 수 있게

실세계에서 다루는 데이터의 유형을 나누고, 크기를 부여하고, 다르게 해석하도록 컴파일러에게 장치를 한 것이다. 

 

 

변환코드

char ch = 'A';
printf("%d %c", ch, ch);

위의 문장을 실행하면  65  'A' 라는 결과가 나온다. 

먼저 char 형은 문자를 저장하기 위한 1바이트 크기의 데이터 타입이다. 자주 사용하는 문자들의 표를 구성하고, 각 문자에 해당
하는 숫자(ASCII 코드)를 부여했다.   char 형은 사실 작은 범위를 수를 저장할 수 있는 정수형과 다름이 없다.

%d , %c는 변환코드라 부르며, 우측에 일치하는 쌍의 값이 어떻게 해석되야 하는지를 나타낸다. %d를 decimal, %c는 character를 

의미하며 이 변환코드에 의해 'A' 라는 값이 65라는 정수(아스키값)로 혹은 문자 'A'로 해석이 되었다. 


 

 





'언어로그 > C/C++' 카테고리의 다른 글

표준입출력함수 printf() / scanf()  (0) 2011.02.22
음수의 표현  (0) 2011.02.22
C 언어 학습에 핵심. 변수와 상수  (0) 2011.02.22
C 프로그램 실행과정  (0) 2011.02.22
C 언어란?  (0) 2011.02.22
비트필드  (0) 2010.12.10

C 프로그램 실행과정

언어로그/C/C++ 2011. 2. 22. 11:17



C프로그램 컴파일 - 실행

C언어로 작성된 프로그램은 .c 라는 확장자를 갖는다. 이를 소스파일이라 부르며 이 소스파일이

실행파일로 최종적으로 변환이 된다.  소스파일은 먼저 전처리기(preprocess)에 의해 읽혀지어, 컴파일 전에

특정한 작업이 수행된다. (소스 일부분이 삽입되거나 대체되는 것 같은...) 전처리기에 의해 읽혀진 컴파일러에 의해

머신에 맞는 기계어 (혹은 어셈블리어)로 변환이 되어 목적파일을 생성하게 된다. 이 목적파일은 링커에 의해

 해당 프로그램에서 참조하고 있는 파일들을 삽입하여 완전한 실행파일을 생성하게 된다. 
실행파일은  사용자가 실행을 하는 순간 운영체제에서 지원하는 Loader(적재기)에 의해 메모리가 올라가 실행되게 된다.

 

소스파일(.c)  > [Preprocessor, Translator] > 목적파일 (.o) > [Linker] > 실행파일(.exe) > [Loader]

 

이와 같이 C 프로그램이 생성되는 코딩, 디버깅, 컴파일, 배포 과정을 통일된 하나의 툴에서 제공해주는

프로그램이 IDE(통합개발환경)이다. 대표적인 IDE로 Visual Studio 가 있다.


Visual Studio6.0 단축키

컴파일 : Ctrl + F7

실    행:  Ctrl + F5

코드정렬 : Alt + F8

에러메시지 : F4

 

다음은 컨솔에 "Hello world!" 라는 문구를 출려가는 프로그램이다

#include <stdio.h>    // 표준 입출력 라이브러리를 사용하겠음
 
int main() // 프로그램 시작점 
{
    printf("Hello world!\n");  // 표준 출력에 문자열 출력 
    return 0;
}


#이 붙어 있는 명령을 전처리 지시자 라고 한다. 컴파일전에 전처리기에 의해 소스파일에 특정한 작업을

수행하는 명령이다. 위에서는 표준입출력 라이브러리를 사용하겠다고 알리고,  표준출력(컨솔)에 출력하는

printf 라는 함수를 사용하였다.  main은 C  프로그램에서 항상 시작점이 되는 함수로,  운영체제에 의해 처음으로

읽혀질 메모리 주소를 나타낸다.   

'언어로그 > C/C++' 카테고리의 다른 글

음수의 표현  (0) 2011.02.22
C 언어 학습에 핵심. 변수와 상수  (0) 2011.02.22
C 프로그램 실행과정  (0) 2011.02.22
C 언어란?  (0) 2011.02.22
비트필드  (0) 2010.12.10
함수의 이해 / 데이터 전달  (0) 2010.12.10

C 언어란?

언어로그/C/C++ 2011. 2. 22. 11:17



컴퓨터를 동작시키기 위해서는 컴퓨터가 이해할 수 있는 언어로 프로그램을 작성해야 한다.

컴퓨터가 이해할 수 있는  언어가 0과 1의 조합으로 이루어진 기계어이다.  하지만 기계어는  

컴퓨터가 잘 이해할 수 있을지는 몰라도, 결국 프로그램을 작성하는 사람이 이해하기에는 너무

어렸다는 단점을 가지고 있다. 특정 기계어 명령에 심볼로 대체하여 좀더 가독성이 좋은 형태로 만든것이 

어셈블리어이다. 하지만 이 이 어셈블리어는  Intel,  AMD 등 컴퓨터 CPU 머신마다 서로 달라, 각 머신맞게

프로그램을 재작성해야 하는 문제가 생기게 된다. 이러한 문제점을 극복하고자 탄생한 언어가  C 언어이다.
C 언어는 Bell 연구소에서 B언어를 기반으로 데니스 리치에 의해 생겨났다.  

C언어가 생겨남으로 소스수준에서의 독립성을 가지게 되었다.  C언어를 사용하여 프로그램을 작성하면,

다른 머신에서도 (컴파일러에 의해) 각 머신에 맞는 실행파일을 생성할 수 있게  되었다.

 

C언어가 널리쓰이게 되면서, 다양한 버전들이 생겨나게 됐다. 호환성 문제가 대두되어, C언어를 표준화하고자

하는 움직임이 생기게 되었다.  1989년  미국 규격협회(ANSI) 에서 표준화된를 승인하게 됐다.(ANSI C라고 함 : C89)

90년에는 국제 표준화 기구(ISO)에 의해 ANSI C가 표준으로 채택되었다. (ISO C 또는 표준C : C90)

이후 C++와 유니코드의 발전 등을 수용하기 위한 C99 등이 생겨나게 되었다.

(이 블로그에서는 표준C 를 기초로 함)



'언어로그 > C/C++' 카테고리의 다른 글

C 언어 학습에 핵심. 변수와 상수  (0) 2011.02.22
C 프로그램 실행과정  (0) 2011.02.22
C 언어란?  (0) 2011.02.22
비트필드  (0) 2010.12.10
함수의 이해 / 데이터 전달  (0) 2010.12.10
과제 #3 함수, 포인터의 사용  (0) 2010.12.10

과제#4 배열과 문자열

언어로그/C/C++ 2009. 10. 3. 21:50

1. 윤년계산

  • 해당년도의 1월 1일부터 몇 번째 날인지를 계산하고 그 결과를 출력하는 프로그램
  • 입력은 년월일 형태로 형태로 처리 (예: 2009 10 15)
  • 2월의 경우 윤달여부를 판별하여 일수를 계산한다.
  • 윤년은 4로 나누어 떨어지는 해이며, 그중 100으로 나누어 떨어지는 해는 평년. 하지만 400으로 나누어 떨어지는 해는 다시 윤년임
입력

오늘 날짜는? (예: 2009.10.15 -> 2009 10 15) : 2008 3 1

출력

현재 61째 되는 날입니다.

문제해결
  • 매년 매월의 날수는 동일하지만, 윤년의 2월은 1일이 더 많다는 것에 주의!

코드
/*
    입력 : 년 월 일 (2009 10 15) 
    출력 : 해당년도 1월 1일 부터 몇번 째 날인지를 출력  
    조건 : 윤년 고려 
*/

#include <stdio.h>

// 1~12월까지 날수를 담는 배열 , 인덱스 0 는 무시. 
int month_days[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

int IsEmptyYear(int year);
int HowManyDays(int year, int month, int day);

int main (int argc, char const* argv[])
{
    int year, month, day, days;

    printf("오늘 날짜는 ? (예: 2009.10.15 -> 2009.10.15) : ");
    scanf("%d %d %d", &year, &month, &day);

    days = HowManyDays(year, month, day);

    printf("\n 현재 %d째 되는 날입니다. \n", days);

    return 0;
}

// 윤년인지 여부 반환 
int IsEmptyYear(int year) {
    if ( (year % 4 == 0) && ((year % 100) || (year % 400 == 0)) ) {
        return 1;
    } else {
        return 0;
    }
}


int HowManyDays(int year, int month, int day) {
    int i, days;

    days = 0;
    for (i = 1; i <= month - 1; i++) {
        days += month_days[i];
    }
    days += day;
    // 윤년이면 1 을 더함 
    if (IsEmptyYear(year)) {
        days += 1;
    }
    return days;
}  


2. 진법 변환

  • 임의의 정수와 변환될 진법을 입력 받아 출력하는 프로그램 작성.
입력

변환될 수(decimal)는 ? 12345
변환할 진법( base)은 ? 16

출력

변환된 수 = 1E240

문제해결
  • 십진수를 진법수로 나눈 나머지들의 역순이 해당 진법으로 변경된 수이다. 이 때 9진법 이상에서는 10부터는 알파벳 문자 A로 표기된다

코드
/*
    입력 : 십진수, 변환할 진법 
    출력 : 변환된 수 
    조건 : 8진수, 16진수 변환문자 사용금지, 배열 사용 
*/

#include <stdio.h>
#include <string.h>

#define MAX_SIZE 100

void base_conversion(char *num, int decimal, int base);
void reverse_str(char *s);

int main (int argc, char const* argv[])
{
    int decimal, base;
    char num[MAX_SIZE]; 

    printf("변환할 수(decimal) 는? ");
    scanf("%d", &decimal);

    printf("변환할 진법(base)은 ? ");
    scanf("%d", &base);

    base_conversion(num, decimal, base);

    printf("변환된 수 =  %s \n", num);

    return 0;
}

// 십진수 decimal을 base진수로 변환하여 문자배열 num에 담는 함수  
void base_conversion(char *num, int decimal, int base) {
    int i, share;
    char *p = num;

    i = 0;
    while (decimal > 0) {
        share = decimal % base;
        if (share > 9) {
            p[i++] = 'A' + share - 10;
        } else {
            p[i++] = '0' + share;
        }
        decimal /= base;
    }
    p[i] = '\0';

    reverse_str(num);
}

// 문자열을 거꾸로 뒤집는 함수 
void reverse_str(char *s) {
    char ch, *pre, *rear;
    pre = s;
    rear = s + strlen(s) - 1;

    while (pre < rear) {
        ch = *pre;
        *pre++ = *rear;
        *rear-- = ch;
    }
}


3. 배열에서 최대값과 최소값 구하기

  • 정수 값을 갖는 배열에서 최대값과 최소값을 찾는 프로그램을 작성
  • 배열의 초기값: 45, -12, 67, 30, 81, -3, 13, 74, 3, 20
  • 최소값과 최대값의 위치, 최소값과 최소값의 위치 구하기.
입력

array[] = { 45, -12, 67, -30, 81, -3, 13, 74, 3, 20}

최대값 : 81, 위치 : 5
최소값: -30, 위치 : 4

출력

변환된 수 = 1E240

문제해결
  • 배열에서 최대값, 최소값이 있는 인덱스를 알면 최대값과 최소값을 알수 있다.

코드
/*
    입력 : 배열 초기값 
    출력 : 최소값과 최대값의 위치, 최소값과 최대값의 위치 
*/

#include <stdio.h>

#define BUF_SIZE 10

void array_printf(int *arr, int size);
void max_min_finder(int *arr, int size, int *idx_max, int *idx_min);

int main (int argc, char const* argv[])
{
    int array[BUF_SIZE] = { 45, -12, 67, -30, 81, -3, 13, 74, 3, 20 };
    int max_index, min_index;

    array_printf(array, BUF_SIZE);

    max_min_finder(array, BUF_SIZE, &max_index, &min_index);

    printf(" 최대값 : %d , 위치 : %d \n", array[max_index], max_index+1);
    printf(" 최소값 : %d , 위치 : %d \n", array[min_index], min_index+1);

    return 0;
}

void array_printf(int *arr, int size) {
    int i;

    printf("array[] = { ");
    for (i = 0; i < size; i++) {
        printf("%d ", arr[i]);
    }
    printf("} \n\n");
}


void max_min_finder(int *arr, int size, int *idx_max, int *idx_min) {
    int i, max, min;
    min = max = arr[0]; 

    for (i = 0; i < size; i++) {
        if (arr[i] > max) {
            max = arr[i];
            *idx_max = i;
        }
        if (arr[i] < min) {
            min = arr[i];
            *idx_min = i;
        }
    }
}


4. 대소문자 변환

  • 임의의 문자열을 입력받아, 소문자는 대문자로, 대문자는 소문자로 변환하는 함수 작성 (제어문, 포인터 사용)
void change(char *to_str, const char *from_str);
문제해결
  • 대문자 -> 소문자 / 소문자 -> 대문자로 변경하고, 이외의 문자의 그대로 복사가 되어야 한다.

코드
/*
    입력 : 임의의 문자열 
    출력 : 소문자는 대문자로, 대문자는 소문자로 변환된 문자열 
    조건 : 제어문과 포인터 사용 
*/

#include <stdio.h>

#define MAX_SIZE 100

void change(char *to_str, const char *from_str);

int main (int argc, char const* argv[])
{
    char to_str[MAX_SIZE], from_str[MAX_SIZE];

    printf("문자열 입력 : ");
    fgets(from_str, MAX_SIZE, stdin);

    change(to_str, from_str);

    printf("변환된 문자열 : %s", to_str);

    return 0;
}

// 대소문자 상호 변환 
void change(char *to_str, const char *from_str) {
     while (*from_str != '\0') {
        if (*from_str >= 'a' && *from_str <= 'z') {
            *to_str++ = *from_str++ - ('a' - 'A');
        } else if (*from_str >= 'A' && *from_str <= 'Z') {
            *to_str++ = *from_str++ + ('a' - 'A');
        } else {
            *to_str++ = *from_str++;
        } 
    }
}  




'언어로그 > C/C++' 카테고리의 다른 글

C 프로그램 실행과정  (0) 2011.02.22
C 언어란?  (0) 2011.02.22
비트필드  (0) 2010.12.10
함수의 이해 / 데이터 전달  (0) 2010.12.10
과제 #3 함수, 포인터의 사용  (0) 2010.12.10
과제#4 배열과 문자열  (0) 2009.10.03