클라이언트/ 서버/ 엔지니어 " 게임 개발자"를 향한 매일의 공부일지

변수와 데이터 입력 1 - 변수 본문

프로그래밍 언어/C 언어

변수와 데이터 입력 1 - 변수

huenuri 2024. 7. 30. 04:39

이제 변수와 데이터 입력를 출력하는 방법에 대해서 배워보기로 하자. 어제 하루 프로그래밍 공부를 쉬었지만 다시 마음을 잡고 공부하는 중이다. 밤 늦게 공부를 시작해서 오늘은 늦게까지 열공에 임해볼 생각이다.

프로그램이 처리하는 데이터(자료)의 형태는 다양하고 형태별 연산 방법도 다르다. 이런 특징을 잘 이해하면 효율적이고 신뢰성 있는 프로그램을 만들 수 있다. 여기서는 데이터의 종류에 따른 변수 선언과 사용 방법에 대해서 알아보기로 한다.

 

시작하기 전에

 

프로그램에서 데이터를 메모리에 저장해 놓으면 필요할 때마다 꺼내 사용할 수 있다. 이때 변수 선언을 통해 메모리에 저장 공간을 확보한다. 변수는 데이터의 종류에 따라 각각 다른 형태를 사용하는데, 정수는 int, 실수는 double, 문자는 char, 문자열은 char 배열을 사용한다.

 


 

1. 변수 선언 방법

 

int a;

a = 10;

 

변수를 선언하면 메모리에 저장 공간이 생기는데 처음에는 어떤 값이 들어있는지 알 수 없다. 컴퓨터의 메모리 공간은 재활용된다. 프로그램이 종료되면 사용하던 메모리 공간을 반납하고 새로 실행된 프로그램이 그 공간을 사용한다. 이때 종료된 프로그램이 남겨놓는 값을 쓰레기 값이라고 한다.

이 쓰레기 값 때문에 프로그램에 오류가 생길 수 있으므로 반드시 원하는 값으로 바꾸는 초기화 과정이 필요하다.

  • 대입 연산자 : 오른쪽의 값을 왼쪽에 저장

 

🐱 변수 선언과 대입 규칙

줄괄호의 블록 안에 변수를 선언하며, 선언한 위치부터 블록 끝까지 사용할 수 있음

변수의 자료형이 같으면 동시에 둘 이상의 변수 선언 가능

대입 연산자는 연산자 왼쪽의 변수에 오른쪽의 값을 저장

변수는 대입 연산자 왼쪽에서는 저장 공간이 되고, 오른쪽에는 값이 됨

  • l-value : 저장 공간으로 사용하는 변수
  • r-value : 값으로 사용하는 변수

 

변수의 선언과 사용

#include <stdio.h> 
int main(void) 
{ 
  int a, b, c; 
  double da; 
  char ch; 
  a = 10; 
  b = a; 
  c = a + 20; 
  da = 3.5; 
  ch = 'A'; 

  printf("변수 a의 값 : %d\n", a); 
  printf("변수 b의 값 : %d\n", b); 
  printf("변수 c의 값 : %d\n", c); 
  printf("변수 da의 값 : %.1lf\n", da); 
  printf("변수 ch의 값 : %c\n", ch); 
  return 0; 
}

 

 

2. 정수 자료형

 

변수는 데이터를 저장하는 메모리의 공간이며, 데이터 종류에 따라 다양한 형태를 사용한다. 이와 같은 변수의 형태를 자료형 혹은 데이터형이라 하며, 크게 정수형과 실수형으로 구분된다.

같은 정수형이라도 메모리 저장 공간의 크기에 따라, char, short, int, long, long long으로 구분된다. 크기가 큰 자료형이 더 많은 범위의 값을 저장할 수 있으며 그 범위는 다음 공식에 따라 계산된다.

 

 

char형 변수의 사용

#include <stdio.h> 
int main(void) 
{ 
  char ch1 = 'A'; 
  char ch2 = 65; 
  printf("문자 %c의 아스키 코드 값 : %d\n", ch1, ch2); 
  printf("아스키 코드 값이 %d인 문자 : %c\n", ch2, ch2); 
  return 0; 
}

char형은 작은 범위의 정수를 저장할 수 있지만, 주로 문자를 저장하는 용도로 쓰인다. 컴파일러는 프로그램에서 사용하는 모든 문자를 0~127 사이의 정수(아스키 코드값)으로 바꾸어 처리하므로 char형 변수를 사용하면 문자를 가장 효과적으로 저장할 수 있다.

 

여러 가지 정수형 변수

#include <stdio.h> 
int main(void) 
{ 
  short sh = 32767; 
  int in = 214333234; 
  long ln = 234233433; 
  long long lln = 1232432435435435; 
  printf("short형 변수 출력 : %d\n", sh); 
  printf("int형 변수 출력 : %d\n", in); 
  printf("long형 변수 출력 : %ld\n", ln); 
  printf("long long형 변수 출력 : %lld\n", lln); 
  printf("long long형의 크기 : %d바이트\n", sizeof(long long)); 
  return 0; 
}

 

 

🤠 자료형 사용 방법

특별한 경우가 아니면 정수형을 표현할 때는 int를 사용

long형은 큰 값을 저장할 때 사용

 

자료형의 크기 알아보기

#include <stdio.h> 
#include <limits.h> 
#include <float.h> 
int main(void) 
{ 
  printf("char형 크기 : %zdbyte\n", sizeof(char)); 
  printf("int형 크기 : %zdbyte\n", sizeof(int)); 
  printf("int max : %d, int min : %d\n", INT_MAX, INT_MIN); 
  printf("unsigned int max : %u\n", UINT_MAX); 
  printf("short형 크기 : %zdbyte\n", sizeof(short)); 
  printf("short max : %d, short min : %d\n", SHRT_MAX, SHRT_MIN); 
  printf("unsigned short max : %u\n", USHRT_MAX); 
  printf("long형 크기 : %zdbyte\n", sizeof(long)); 
  printf("float형 크기 : %zdbyte\n", sizeof(float)); 
  printf("double형 크기 : %zdbyte\n", sizeof(double)); 
  printf("double max : %g, double min : %g\n", DBL_MAX, DBL_MIN); 
  printf("long double 크기 : %zdbyte\n", sizeof(long double)); 
  return 0; 
}
 

 

3. unsigned 정수 자료형

정수형은 보통 양수와 음수를 모두 저장하지만, 양수만 저장하면 두 배 더 넓은 범위의 값을 저장할 수 있다. 따라서 나이와 같이 음수가 없는 데이터를 저장할 때는 unsigned를 사용한다.

unsigned가 없으면 자동으로 signed로 선언된다.

 

unsigned를 잘못 사용한 경우

#include <stdio.h> 
int main(void) 
{ 
  unsigned int a; 
  a = 4294967295; 
  printf("%d\n", a); 

  a = -1; 
  printf("%u\n", a); 
  return 0; 
}

%d는 부호까지 생각해서 10진수로 출력하는 변환 문자이고, %u는 부호 없는 10진수로 출력하는 변환 문자이다.

 

 

 

 

4. 실수 자료형

 

 

유효숫자 확인

#include <stdio.h> 
int main(void) 
{ 
  float ft = 1.2344556678783488; 
  double db = 1.233455565656546; 
  printf("float형 변수의 값 : %.20f\n", ft); 
  printf("double형 변수의 값 : %.20f\n", db); 
  return 0; 
}

 

 

출력한 값이 초기값과 다르다. 실수형은 저장하는 값에 따라 숫자가 정확하게 표현될 수도 있고 그렇지 않을 수도 있다. 이렇게 값이 달라지는 이유는 컴퓨터에서 실수를 표현하는 방식이 오차를 갖고 있기 때문이다. 따라서 float형은 유효 숫자 7자리, double형은 15자리의 범위 내의 값을 사용하는 것이 좋다.

 

🤠 실수형 사용 방법

정수형을 기본으로 사용하고, 꼭 필요한 경우에만 실수형을 사용

실수형은 유효 숫자가 많은 double형을 기본으로 사용

 

 

5. 문자열 저장

 

 

문자열의 길이보다 배열의 크기를 하나 더 크게 잡아야 할까? 바로 컴파일러가 문자열의 끝에 /0(널 문자)을 자동으로 추가하기 때문이다.

이렇게 기본 자료형을 여러 개 묶어 사용하는 것을 배열이라고 한다.

 

char 배열에 문자열 저장

#include <stdio.h> 
int main(void) 
{ 
  char fruit[20] = "strawberry"; 
  printf("딸기 : %s\n", fruit); 
  printf("딸기쨈 : %s %s\n", fruit, "jam"); 
  return 0; 
}
 
 

 

배열의 크기가 크더라도 문자열의 끝에는 항상 널 문자가 있으므로 printf 함수는 널 문자 이전까지 저장된 문자열을 출력한다.

 

배열에는 대입연산자를 사용할 수 없다

대입 연산은 대상 자료형의 크기가 일정해야 수행할 수 있는데, 선언에 따라 크기가 달라지는 char 배열을 사용하면 대입 연산을 할 수 없다.

배열명은 주소 상수이므로 대입연산자 왼쪽에 쓸 수 없다.

char 배열에 새로운 문자열을 저장하려면 초기화 외에 strcpy 함수를 사용한다

 

char 배열에 문자열 복사

#include <stdio.h> 
#include <string.h> 
int main(void) 
{ 
  char fruit[20] = "strawberry"; 
  printf("%s\n", fruit); 
  strcpy(fruit, "banana"); 
  printf("%s\n", fruit); 
  return 0; 
}
 

 

6. const를 사용한 변수

 

변수를 선언할 때 그 앞에 const를 붙이면 초기화된 값을 바꿀 수 없다.

const를 사용한 변수

#include <stdio.h> 
int main(void) 
{ 
  int income = 0; 
  double tax; 
  const double tax_rate = 0.12; 
  income = 456; 
  tax = tax_rate * income; 
  printf("세금은 %.1lf입니다.\n", tax); 
  return 0; 
}

const double tax_rate = 0.12;

 

const를 사용하면 이후에는 값을 바꿀 수 없으므로 반드시 선언과 동시에 초기화를 해야 한다. 초기화하지 않으면 변수의 쓰레기 값이 계속 사용되며, 만약 초기화 이후에 값을 바꾸고자 하면 컴파일 과정에서 에러 메시지가 나타난다.

 

 

7. 예약자와 식별자

 

예약어는 컴파일러와 사용 방법이 약속된 단어이며, 식별자는 필요에 따라 만들어 사용하는 단어이다. 예를 들어 변수 선언문에서 자료형 이름은 예약어이고, 변수명은 식별자이다.

 

식별자는 프로그램에서 이름이 필요할 때 언지든지 만들어 사용하면 된다. 변수명이나 배열명, 함수명, 구조체명 등에서도 식별자를 사용한다. 알기 쉬운 프로그램을 작성하려면 용도에 맞는 이름을 식별자로 쓰는 것이 좋다.


 

학습 내용 정리

 

 

 

 

 

 

연습문제

 

국어, 영어, 수학 점수를 저장할 변수(kor, eng, mat)를 선언하고 각각 70, 80, 90점으로 초기화한다. 총점을 저장할 변수(tot)를 선언해 세 과목의 합을 구하고 세 과목의 점수와 총점을 출력하는 프로그램 만들어라.

 

#include <stdio.h> 
int main(void) 
{ 
  int kor = 70, eng = 80, mat = 90; int tot; 
  tot = kor + eng + mat; 
  printf("국어 : %d, 영어 : %d, 수학 : %d\n", kor, eng, mat); 
  printf("총점 : %d\n", tot); 
  return 0; 
}

 

오늘의 학습을 마치고

왜 변수를 선언하고 값을 초기화해야 하는지 이번 학습을 통해 확실히 알게 되었다. 자료형의 종류와 크기에 대해서도 개념이 정립되었고, 문자열 저장을 하는 출력하는 예시도 살펴볼 수 있었다.

아직 문자열 함수는 여기서는 깊이 다루지 않아서 지금은 바로 사용할 수는 없겠지만 앞으로 곧 배우게 될 것 같다.

이제 바로 다음 단원에서 데이터 입력하는 부분에 대해서 학습해볼 것이다.