C 언어(9) - 입력하기, 메모리 구조

C 언어 강의, 입력하기 및 메모리 구조 이해

Featured image

🔚 짧게 하는 복습

✅ 1. 형 변환, 명시적 형 변환을 알자

✅ 2. 주석을 알자

혹시 기억이 안 난다면, 다시 돌아가자


이때까지 자료형 및 연산자들에 대해서 정말 깊게 배웠다.

오늘은 본격적인 프로그램을 만들기 위해 입력하는 방법에 대해서 배워보겠다.


입력하기

우선 visual studio를 이용하시는 분들은 아래 코드가 실행이 안 될 수 있는데, 여기를 참고하자.

그리고 실행 화면에서 원하는 값을 입력하고 Enter를 눌러보자.

(아래 코드 실행을 할 때는 오른쪽 아래 ⚙️를 누르면 custom input을 통해 입력값을 넣을 수 있다.)

우리가 무슨 짓을 한 걸까??


scanf란?

scanf()는 어떤 값을 입력받아서 변수에 대입하는 함수이다.

쓰는 방법은 scanf(“원하는 format”, &변수 이름)이다.

예를 들면

int a;
char b;
float c;

scanf("%d", &a);
scanf("%c", &b);
scanf("%f", &c);
//이렇게 할 수도 있고

scanf("%d %c %f", &a, &b, &c);
// 이렇게 formatting에 맞게 pairing해 줄 수도 있다.

printf는 대충 변수의 값을 형식에 맞게 가져오는 느낌이라 이해가 되는데, scanf는 왜 형식지정자가 필요한지 &는 무엇인지 아직 이해하기 어렵다.

여기는 심화 내용이라 간단하게만 짚고 넘어가겠다.


메모리의 구조와 원리

우선 컴퓨터는 메모리라는 곳에 값을 저장한다. 바이트니 비트니 했던 것들은 메모리의 단위이고, 특히 비트는 0 아니면 1 둘 중 하나를 넣는 메모리의 최소 단위이다.

메모리는 비트들이 사는 아파트라고 생각하면 좋다. 예를 들어, 아파트도 몇 동 몇 호 주소가 있듯이 메모리도 각각의 주소를 가진다.

이런 느낌인 것이다. 아파트 안은 비어있지 않고 항상 어떤 값으로 차 있다.

그러다가 우리가 만약

int a;

라는 코드를 작성하면 a라는 변수를 위한 랜덤하게 4바이트의 공간이 설정된다. (편의상 1칸을 1바이트로 하겠다.)

이런 식으로 말이다.

그래서 만약 어떤 값으로 초기화시켜주지 않은 변수를 넣으면 0이 나오는 것이 아니라 예측할 수 없는 값이 나온다. (이를 쓰레깃값이라고도 한다.)

만약 8바이트의 공간이 필요한 자료형이라면 아래와 같이 역시 랜덤하게 공간이 설정된다.

그리고 int 자료형 a 변수에 값을 대입하는 순간,

int a;
a = 7;

7은 아래 그림과 같이 메모리에 0000 0000 0000 01112, 이진수의 형태로 저장된다. (실수라도 각각의 메모리에 배웠던 부동소수점의 형태로 저장된다.)

바로 이것이 우리가 배웠던 변수의 선언과 대입의 원리이다.


scanf의 원리

scanf를 다시 한번 보자.

첫 번째 입력하는 것은 “format”이었다. 입력받은 값을 어떤 형식으로 저장할지, 즉 몇 바이트에 집어넣을지를 알려주는 것이다.

두 번째는 &변수인데, 이는 변수가 시작되는 주솟값을 나타낸다..

즉 변수에 값을 넣기 위해, 변수가 시작되는 주소에 가서 입력받은 값을 형태에 맞게 집어넣는 것이다.

주의할 점은 format과 변수의 자료형이 다른 경우 컴퓨터가 오류를 내거나, 오류가 안 나도 자료형과 맞지 않는 값이 입력될 수 있다.


이때까지 배운 것 응용

이제 여러분은 필요한 변수를 만들고, 입력을 받고 연산하고 출력하는 것을 모두 배웠다.

즉 가장 기본적인 유용한 프로그램을 만들 수 있게 되었다는 것이다.

우리는 간단하게 원의 반지름(실수)을 입력받으면 둘레(실수)와 넓이(실수)를 출력하는 프로그램을 짜보겠다.

모든 프로그램은 입력 -> 연산 -> 출력의 과정을 가진다.

어떤 변수를 입력해야 할까? 문제를 다시 한번 보면 “원의 반지름”이라고 적혀있다.

다음은 출력은 어떻게 해야 할까? “둘레와 넓이”라고 되어있다.

그럼 이제 어떤 연산이 필요할까?

원의 넓이 = 반지름 _ 반지름 _ 3.14

원의 둘레 = 반지름 _ 2 _ 3.14

이를 사고의 흐름에 맞게 의사 코드(진짜로 만들어진 코드는 아니고 논리의 흐름만 대강 적은 코드)로 짜보면

double 반지름;//

scanf(반지름);

double 둘레 = 반지름 * 2 * 3.14;
double 넓이 = 반지름 * 반지름 * 3.14;

printf(둘레, 넓이)

이렇게 작성할 수 있고, 이를 자세하게 코드로만 옮기면 된다.


📖 오늘의 핵심(다 알기 전까지는 넘어가지 말자❗)

✅ 1. scanf로 입력받는 법을 알자

✅ 2. 메모리에 값이 저장되는 과정을 알자

✅ 3. 문제해결을 위한 프로그램을 작성하는 데는 입력 -> 연산 -> 출력이 필요하고, 의사 코드를 통해 어떻게 할지 먼저 생각하는 습관을 지니자

⚠️ 의사 코드를 작성하는 것을 시간 낭비라고 생각하는 사람들이 종종 있는데, 무작정 실제 코드부터 작성하면 오히려 시간이 낭비될 가능성이 크다.

💣 과제,

  1. 섭씨온도를 입력받아 화씨온도로 바꾸어 출력하는 프로그램을 짜보자. (난이도 下)

  2. 10%의 이자를 매년 복리로 주는 은행이 있다. 초기 자금 n원을 넣고, 3년이 지났을 때 돈이 얼마가 될지 계산하고 싶다. n을 입력받아 3년 후 돈을 출력하는 프로그램을 짜보자. (난이도 下) - (형식지정자를 이용하면 반올림의 자리를 설정할 수 있다. 검색해보자)

  3. A와 B가 투표를 했다. 각각의 득표수를 입력받아, A가 이겼다면 1, B가 이겼다면 2를 출력해보자. (난이도 下)

🔜 더 공부해보기,

백준(BOJ) 1000번 - A+B

정답 보기
#include<stdio.h>

int main(){
    int a, b;
    scanf("%d %d", &a, &b);

    printf("%d", a+b);

    return 0;
}

백준(BOJ) 1001번 - A-B

정답 보기
#include<stdio.h>

int main(){
    int a, b;
    scanf("%d %d", &a, &b);

    printf("%d", a-b);

    return 0;
}

백준(BOJ) 10998번 - AxB

정답 보기
#include<stdio.h>

int main(){
    int a, b;
    scanf("%d %d", &a, &b);

    printf("%d", a*b);

    return 0;
}

백준(BOJ) 1008번 - A/B (소수점 format으로 9자리까지만 나오게!, 형변환!)

정답 보기
#include<stdio.h>

int main(){
    int a, b;
    scanf("%d %d", &a, &b);

    printf("%.9f", 1.0*a/b);//저번 강의에 나왔던 형변환 스킬

    return 0;
}

백준(BOJ) 10869번 - 사칙연산

정답 보기
#include<stdio.h>

int main(){
    int a, b;
    scanf("%d %d", &a, &b);

    printf("%d\n", a+b);
    printf("%d\n", a-b);
    printf("%d\n", a*b);
    printf("%d\n", a/b);
    printf("%d\n", a%b);

    return 0;
}

백준(BOJ) 18108번 - 1998년생인 내가 태국에서는 2541년생?!

정답 보기
#include<stdio.h>

int main(){
    int x;
    scanf("%d", &x);

    printf("%d", x - 543);

    return 0;
}

백준(BOJ) 10430번 - 나머지 (굉장히 교육적인 문제임)

정답 보기
#include<stdio.h>

int main(){
    int A, B, C;
    scanf("%d %d %d", &A, &B, &C);

    printf("%d\n%d\n%d\n%d", (A+B)%C, ((A%C) + (B%C))%C, (A*B)%C, ((A%C) * (B%C))%C);

    return 0;
}

백준(BOJ) 2588번 - 곱셈

정답 보기
#include <stdio.h>

int main()
{
	int var1, var2;
	scanf("%d", &var1);
	scanf("%d", &var2);

	int c = var2 % 10;
	int b = (var2 % 100 - c) / 10;
	int a = var2 / 100;

	printf("%d\n%d\n%d\n%d", var1 * c, var1 * b, var1 * a, var1 * var2);

    return 0;
}

백준(BOJ) 11382번 - 꼬마 정민(혹시 자료형과 출력 범위를 확인하셨나요?)

정답 보기
#include<stdio.h>

int main(){
    long long A, B, C;
    scanf("%lld %lld %lld", &A, &B, &C);

    printf("%lld", A+B+C);

    return 0;
}