C언어 2일차

정혜창·2024년 12월 14일

독학

목록 보기
3/28
post-thumbnail

변수

변수 선언을 통해 메모리에 저장 공간을 확보한다. 변수는 데이터의 종류에 따라 각각 다른 형태를 사용한다.

변수선언 방법

int a; // int는 자료형, a는 변수명

변수를 초기화 하는 이유
변수명은 메모리에 붙이는 임시 주소와 같은 개념.
변수를 선언하면 메모리에 저장 공간이 생긴다. 그 안에는 어떤 값이 들어 있는지 알 수 없다. 컴퓨터의 공간은 재활용 되는데 프로그램이 종료되면 사용하던 메모리를 반납하고 그 자리를 새로 들어온 프로그램이 사용한다. 이때 종료된 프로그램이 어떤 값을 메모리 공간에 남겨 놓았는지 알 수 없는데, 새 프로그램에서는 이 값은 의미가 없으므로 이를 쓰레기값 이라고 한다. 이 쓰레기값으로 인해 프로그램에 오류가 생길 수 있으므로 반드시 원하는 값으로 초기화하는 과정이 필요하다.

#include <stdio.h>

int main(void)
{
	int a;		// int형 변수 a 선언
    int b, c;	// 2개의 int형 변수 b, c를 동시에 선언
    double da;	// double형 변수 da 선언
    char ch;	// char형 변수 ch 선언
    
    a = 10;		// int형 변수 a에 정수 10을 대입
    b = a;		// int형 변수 b에 변수 a의 값 대입
    c = a + 20;	// int형 변수 c에 변수 a의 값과 정수 20을 더한 값 대입
    da = 3.5;	// double형 변수 da에 실수 3.5 대입
    ch = 'A';	// char형 변수 ch에 문자 'A' 대입
    
    printf("변수 a의 값 : %d\n", a);		// 변수 a의 값 : 10
    printf("변수 b의 값 : %d\n", b);		// 변수 b의 값 : 10
    printf("변수 c의 값 : %d\n", c);		// 변수 c의 값 : 30
    printf("변수 da의 값 : %.1lf\n", da);	// 변수 da의 값 : 3.5
    printf("변수 ch의 값 : %c\n", ch);		// 변수 ch의 값 : A
    
    return 0;
}

변수 선언과 대입 규칙

  • 중괄호 안에 { } 변수를 선언하며 선언한 위치부터 블록 끝까지 사용할 수 있다. 하나의 중괄호 안에서 같은 이름의 변수가 중복 선언이 될 수 없다.
  • 변수의 자료형이 같으면 동시에 둘 이상의 변수를 선언할 수 있다.
  • 대입 연산자는 왼쪽의 변수에 오른쪽 값을 저장한다.
    변수를 선언하면 메모리에 일정한 크기의 저장공간이 생기는데 이 공간에 데이터를 넣을 땐 대입 연산자를 사용한다. 대입 연산자 왼쪽에는 저장 공간을 뜻하는 변수만 사용할 수 있고 오른쪽에는 상수, 변수, 수식을 모두 사용할 수 있다.
  • 변수는 대입 연산자 왼쪽에서는 저장 공간이 되고, 오른쪽에서는 값이 된다.

정수 자료형

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

  • char
    정수 자료형 char의 저장공간은 1바이트 이다. == 8비트 (값의 저장범위가 -128 ~ 127)
    char형은 주로 문자를 저장하는 용도로 사용이 된다.
    프로그램에서 사용하는 모든 문자를 0~127 사이의 정수(아스키 코드 값)으로 바꾸어 처리
#include <stdio.h>

int main(void)
{
	char ch1 = 'A'	// 정수 자료형 char형의 변수 ch1를 선언하고 문자로 초기화. 저장된 값은 문자의 아스키 코드값.
    char ch2 = 65;	// 정수 자료형 char형의 변수 ch2를 선언하고 정수로 초기화. A의 아스키코드 값은 65
    
    printf("문자 %c의 아스키 코드 값 : %d\n", ch1, ch1);  
    printf("아스키 코드 값이 %d인 문자 : %c\n", ch2, ch2); // 어떻게 출력하느냐는 변환문자가 결정한다.
    
    return 0;
}
  • 여러가지 정수형 변수
    short, int, long, long long
    각 자료형은 저장 값의 범위가 다르지만 출력할 때는 모두 %d를 사용한다. 단 long형은 소문자 l을 붙여 %ld로 출력하고 long long형은 ll 을 붙여 %lld로 출력한다.
#include <stdio.h>

int main(void)
{
	short sh = 32767;					// short형의 최댓값 초기화
    int in = 2147483647; 				// int형의 최댓값 초기화
    long ln = 2147483647;				// long형의 최댓값 초기화
    long long lln = 123456123456123;
    
    printf("short형 변수 출력 : %d\n", sh);
    printf("int형 변수 출력 : %d\n", in);
    printf("long형 변수 출력 : %ld\n", ln);
    printf("long long형 변수 출력 : %lld\n", lln);
    
    return 0;
}

각 자료형의 크기는 컴파일러나 버전에 따라 달라질 수 있지만 기본적으로
char <= short <= int <= long <= long long
의 기준으로 구현된다.

  • unsigned 정수 자료형
    정수형은 보통 양수와 음수를 모두 저장하지만 양수만 저장하면 두 배 넓은 범위의 값을 저장할 수 있다. 따라서 나이와 같이 음수가 없는 데이터를 저장할 때는 unsigned를 사용하곤 한다. unsigned가 없으면 자동으로 signed 으로 선언된다.
    unsigned 자료형을 사용할 때는 출력 시 변환 문자 사용에 주의해야 한다. 큰 양수를 저장하고 %d로 출력하면 음수로 출력될 가능성이 있다. 음수를 저장하고 %u로 출력하면 양수가 출력 된다.
#include <stdio.h>

int main(void)
{
	unsigned int a;
    
    a = 4294967295;		// 큰 양수 저장
    printf("%d\n", a);	// %d 로 출력 ( -1)
    a = -1;				// 음수 저장
    printf("%u\n", a);	// %u 로 출력 (4294697295)
    
    return 0;
}

%d는 부호까지 생각해서 10진수로 출력하는 변환문자,
%u는 부호 없는 10진수로 출력하는 변환문자이다.
??? 아니 근데 unsigned는 음수가 없는 데이터라면서 왜 음수를 저장도 하고 출력도 하는것인가?
--> 저장하고 출력하는것이 가능하긴하지만 연산하거나 대소를 비교할 때 부호 비트를 고려하지 않고 항상 양수로 처리하기 때문에 결과가 예상과 달라질 수 있다. 따라서 unsigned 자료형을 사용할 때는 항상 양수만 저장하고 %u로 출력하는 것을 권장한다.

실수 자료형

실수는 데이터를 구현하는 방법이 정수와 다르므로 별도의 자료형을 사용한다.
크기에 따라 float, double, long double로 구별
실수형은 저장하는 값에 따라 숫자가 정확하게 표현될 수도 있고 그렇지 않을 수도 있다. float 형은 유효숫자 7자리, double형은 15자리 범위 내의 값을 사용하는 것이 좋다.
1. 정수형을 기본으로 사용하고 꼭 필요한 경우에만 실수형을 사용한다.
2. 실수형은 유효 숫자가 많은 double 형을 기본으로 사용한다.

문자열 저장

문자열을 변수에 담아야 할 때가 있는데 이런 경우 char 형을 배열 형태로 만들어 저장

char 배열명[문자열길이+1] = 문자열;
char fruit[6] = "apple";

문자열의 길이보다 배열의 크기를 하나 더 크게 잡는 이유는 컴파일러가 문자열의 끝에 \0(널 문자,null character)을 자동으로 추가하기 때문이다. 널문자는 추후 자세히. 이렇게 자료형을 여러 개 묶어 사용하는 것을 배열(array) 라고 한다. 배열도 추후에 자세히.

#include <stdio.h>

int main(void)
{
	char fruit[20] = "strawberry";
    
    printf("딸기 : %s\n", fruit);
    printf("딸기잼 : %s %s\n", fruit, "jam");
    
    return 0;
}

배열명은 주소 상수 이므로 대입연산자의 왼쪽에 쓸 수 없다. 위의 소스에서 fruit = "banana"; 이렇게 사용할 수 없다.
그럼 char 배열에 새로운 문자열을 저장하려면 어떻게 해야 할까

char 배열에 초기화 이외의 문자열을 저장할 때는 strcpy(string copy) 함수를 사용한다.
strcpy 함수를 사용하려면 소스코드에 string.h 헤더 파일을 포함시켜야 한다.

#include <stdio.h>
#include <strcpy.h>

int main(void)
{
	char fruit[20] = "strawberry";	// strawberry로 초기화
    
    printf("%s\n", fruit);			// strawberry 출력
    strcpy(fruit, "banana");		// fruit에 banana 복사
    printf("%s\n", fruit);			// banana 출력
    
    return 0;
}

const를 사용한 변수

변수는 저장 공간이므로 언제든지 그 값을 바꿀 수 있다. 그러나 const를 사용한 변수는 예외. 변수를 선언할 때 그 앞에 const를 붙이면 초기화된 값을 바꿀 수 없다.

#include <stdio.h>

int main(void)
{
	int income = 0;							// income 변수선언, 초기화
    double tax;								// 실수형 변수 tax 선언
    const double tax_rate = 0.12;			// 실수형 변수 tax_rate 초기화, 상수처럼
    
    income = 456;							// income에 456저장
    tax = income * tax_rate;				// tax 계산
    printf("세금은 : %.1lf입니다. \n", tax);	// 세금은 : 54.7입니다.
    
    return 0;
}

const를 사용한 변수는 다음과 같은 형식으로 선언

  • const 자료형 변수명 = 값;

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

  • 기초예제
    국어, 영어, 수학 점수를 저장할 변수 (kor, eng, mat)를 선언하고 각각 70, 80, 90점으로 초기화 합니다. 총점을 저장할 변수(tot)를 선언해 세 과목의 합을 구하고 세 과목의 점수와 총점을 출력하는 프로그램을 작성하세요.
#include <stdio.h>

int main(void)
{
	int kor = 70;
    int eng = 80;
    int mat = 90;
    int tot;
   	
    tot = kor + eng + mat;
    
    printf("국어 : %d\n", kor);
    printf("영어 : %d\n", eng);
    printf("수학 : %d\n", mat);
    printf("총점 : %d\n", tot);
    
    return 0;
}
profile
Unreal 1기

0개의 댓글