이번엔 저번보다는 조금 어려울 수도 있다. 하지만 내가 아는 지식 안에서 최대한 쉽게 설명해 보겠다.
어려워도 지금은 굳이 이걸 다? 안 이해해도 괜찮다. 나중에 조금 더 익숙해지면 다시 알아가면 되는 것이다.
만약 이해가 안 된다면 괜찮다, 나도 이런 거 이해하기까지 영겁의 시간이 걸렸기 때문이다.

변수 이름 짓는 방법
가정을 해보자 내가 중요한 프로그램에 키 값을 결정하는 변수를 만들 것이다.
char asdf[] = "7J2066CH6rKMIO2VmOuptCDsoobrkKnri4jri6Qu"; // 물론 실무에서 코드에 대놓고 키 값을 박아놓는 일은 드물다.
printf("%s", asdf);
이렇게 목적이 불분명하고 무엇을 하는지 알 수 없는 변수명은 코드 가독성을 떨어뜨리고 유지보수에 어려움을 초래한다.
쉽게 말해 저렇게 쓰면 팀원에게 싸대기를 불러온다.
이런 경우에는 변수명을 더 명확하게 바꾸는 것이 좋다. 예를 들면, 아래와 같이 수정할 수 있다.
char encryptionKey[] = "7J2066CH6rKMIO2VtOyVvCDtlanri4jri6Q="; // 실무에서는 일반적으로 보안을 위해 키 값을 별도로 관리한다.
printf("%s", encryptionKey);
이처럼, 변수명을 목적에 맞게 바꾸면 코드를 읽는 사람이 이해하기 쉽고, 유지보수에도 도움이 된다.
변수명은 해당 변수가 어떤 값을 담고 있는지, 어떤 목적으로 사용되는지를 명확하게 표현해야 한다.
이렇게 하면 코드의 가독성이 향상되고, 실수를 줄일 수 있다.
또한 이 세상 나 혼자 코딩하는 일은 드물다. 같이 일하는 팀을 위해서라도 지키도록 하자
bool 자료형이란?
간단히 참과 거짓을 구별하는 것이다. 이때 참은 1 , 거짓은 0으로 표현한다.
다시 말해 True 라면 1 False 라면 0을 반환하는 것이다.
예시 코드를 보자
#include <stdio.h>
#include <stdbool.h>
int main() {
bool typeTrue = true;
if (typeTrue) {
printf("Is True\n");
}
else {
printf("Is not True\n");
}
return 0;
}
bool 자료형인 typeTrue에 true를 삽입하여 결과는 Is true가 출력되는 간단한 코드이다.
사실은 0이 아닌 모든 양수는 true이다 보편적으로는 1을 사용하지만 이러한 특성을 잘 이용한다면
#include <stdio.h>
int main() {
int num = 5;
if (num) {
printf("변수 num은 0이 아닙니다.\n");
}
else {
printf("변수 num은 0입니다.\n");
}
return 0;
}
이렇게 문자가 0인지 아닌지도 구분할 수 있는 코드를 만들 수 있다.
재밌는 사실은 자료형 중 bool형이 별도에 라이브러리인 stdbool을 사용하는 이유다.
라이브러리 : 함수와 매크로를 포함하는 미리 컴파일된 코드 ex) #include <stdio.h>
사실 C언어에서 bool 자료형은 사실상 int 자료형과 동일하게 처리된다. 이는 C언어에서 참(true)을 정수 1, 거짓(false)을 정수 0으로 표현하기 때문이다.
이러한 점 때문에 라이브러리가 나오기 전에는
#define bool int
#define true 1
#define false 0
또는
typedef int bool;
#define true 1
#define false 0
이런 식으로 정의하여 사용하였다.
아까 전 코드를 변환하면
#include <stdio.h>
typedef int bool;
#define true 1
#define false 0
int main() {
bool typeTrue = true;
if (typeTrue) {
printf("Is True\n");
} else {
printf("Is not True\n");
}
return 0;
}
이런 식이 된다.
Signed와 Unsigned
signed와 unsigned는 정수 자료형의 부호를 나타내는 데 사용된다.
signed 정수 자료형 : 음수와 양수 값을 모두 저장할 수 있다. C 언어에서 기본적으로 정수 자료형은 signed로 설정된다. 그러므로 정수형 변수를 선언할 때 signed를 명시적으로 지정할 필요는 없다.
unsigned 정수 자료형 : 음수 값을 저장할 수 없으며, 양수 값만 저장할 수 있다. unsigned 정수형은 동일한 메모리 공간에서 더 큰 양수 값을 저장할 수 있다.
#include <stdio.h>
int main() {
unsigned int num1 = 5;
unsigned int num2 = -5;
printf("num1: %u, \nnum2: %u\n", num1, num2);
return 0;
}
코드를 실행하면 num2에 값이 5를 2^32(int = 32bit) 빼서 얻은 4294967291 가 출력된다. 이는 4바이트 int에 최댓값이 출력된 것이다.
num2는 Unsigned 인 상태에서 - 부호를 사용하였기 때문이다.
이렇게 숫자가 커지는 현상 이를 언더 플로우 라고한다.
언더 플로우는 시스템의 안정성 또는 보안 문제를 일으키기에 알 맞은 자료형을 사용하여 예방하자
왜 자료형을 나눠서 사용하는가?
여러 언어에서 여러 가지 자료형을 제공해 주는 이유는 목적에 맞게 사용하라는 것이다.
각 자료형은 다른 크기의 메모리를 차지하고 다양한 값의 범위를 표현할 수 있다.
자신이 작성하는 프로그램의 목적과 요구 사항에 따라 적절한 자료형을 선택할 수 있는 것이다.
예를 들어 메모리 사용을 취적화 하기 위해 큰 정수를 다룰 필요가 없다면 int 대신 short를 사용하여 메모리를 절약할 수 있다.
하지만 파이썬은 이런 데이터 타입을 자동으로 맞춰서 제공해 준다 우리가 int, float, double 등을 직접 사용하지 않는다는 것이다. 이러한 동적 데이터 타입은 성능이 저하되고 메모리도 기존보다 더 차지하는 등 여러 가지 문제가 있다.
하지만 겁나 편하다.
C언어처럼 데이터 타입을 직접 정의하여 사용하는 것을 정적 데이터 타입이라 한다.
sizeof에 쓰임
변수나 데이터 타입에 크기를 반환할 때 사용한다. 바이트 단위로 반환되며 최적화나 효율적인 자료 구조 생성에서 유용하게 사용할 수 있다.
#include <stdio.h>
int main() {
printf("int 크기: %zu\n", sizeof(int));
printf("flaot 크기: %zu\n", sizeof(float));
printf("double 크기: %zu\n", sizeof(double));
printf("char 크기: %zu\n", sizeof(char));
return 0;
}
또는
#include <stdio.h>
int main() {
int a = 10;
float b = 3.14f;
double c = 6.283;
char d = 'A';
printf("a 크기 %zu\n", sizeof(a));
printf("b 크기: %zu\n", sizeof(b));
printf("c 크기: %zu\n", sizeof(c));
printf("d:크기 %zu\n", sizeof(d));
return 0;
}
이런 식으로 사용 가능하다.
char도 정수형인데 숫자를 사용해도 되는가?
결론은 가능하다. 하지만 값의 최대 범위인 -128 ~ 128 은 너무 적다.
#include <stdio.h>
int main() {
char num = 129;
printf("%d", num);
return 0;
}
이렇게만 하여도 언더플로우에 반대인 오버플로우가 나는 것을 확인할 수 있다.
재밌는 부분은
#include <stdio.h>
int main() {
char asciiA = 65; // 아스키코드 65는 대문자 A
printf("%c", asciiA);
return 0;
}
아스키코드 65는 대문자 A인 점을 이용하여 %c로 포맷하면 A가 출력된다.
아스키코드 : 알파벳, 숫자, 기호 및 제어 문자 등 총 128개의 문자를 포함하며, 각 문자에 고유한 정수 값이 할당되어 있다. 이를 통해 컴퓨터가 문자를 이해하고 처리할 수 있다.
여러 개의 문자를 사용하고 싶다면?
C언어는 문자열 배열 이란 것으로 표기한다.
보통 " " 은 문자열 ' ' 은 단일 문자를 나타낸다.
하지만 지금 배우긴 아직 배열이라는 개념이 잡혀 있지 않기에 배열 파트에서 설명하겠다.
C언어에는 별도의 string 자료형이 없지만, 문자열을 저장하고 처리하기 위해 문자열 배열과 포인터를 사용한다.
다른 프로그래밍 언어들, 예를 들어 파이썬이나 자바에서는 문자열을 다루기 위한 string 자료형이 존재한다.
string : 문자들로 구성된 데이터 자료형
컴퓨터에 숫자는 0부터?
컴퓨터는 0과 1로 구성된 2진수 체계를 사용하기에 숫자는 보통 0부터 시작한다.
SQL 같은 데이터베이스에서는 기본 키값이 1부터 시작되는 경우가 있으니 조심하자
0도 없는 경우는? Null이다.
NULL : 컴퓨터에서 값이 없거나 공백(empty)인 경우를 나타내기 위해, NULL이라는 자료형을 사용한다.
float(실수) 뒤에 f를 사용하는 이유
실수형 변수를 선언할 때, float와 double 두 가지 형태가 있다.
float는 4byte , double 은 8byte 서로 다른 메모리 크기를 가지고 있다.
그래서 float 형 상수에는 'f' 또는 'F' 접미사를 사용하여 컴파일러에게 이 값이 float 형임을 명시해야 한다. 그렇지 않으면, 컴파일러는 기본적으로 double 형으로 인식한다.
컴파일러 : 프로그래밍 언어로 작성된 소스 코드를 기계어로 변환해 주는 소프트웨어 ex) C언어 gcc
형변환이란?
하나의 데이터 타입을 다른 데이터 타입으로 변환하는 프로세스다.
프로그래밍 언어에서 자료형 간의 연산이나 할당을 수행할 때, 형변환이 필요한 경우가 많이 발생한다.
형변환은 두 가지 종류가 있는데
명시적 형변환 : 개발자가 직접 코드를 작성하여 데이터 타입을 변환한다. 이를 캐스팅이라고 한다.
#include <stdio.h>
int main() {
int int_num = 3;
float flo_num = 3.14f;
float sum;
sum = int_num + (int)flo_num; // int로 형변환
printf("합계 : %f\n", sum);
return 0;
}
암시적 형변환 : 컴파일러가 자동으로 형변환을 수행하는 경우다. 보통 더 넓은 데이터 타입으로 변환된다.
#include <stdio.h>
int main() {
int int_num = 3;
float flo_num = 3.14f;
float sum;
sum = int_num + flo_num;
printf("sum : %f\n", sum);
return 0;
}
부동 소수점 표현


도저히 쉽게 설명할 자신도 없고 나조차 잘 모른다.
사실 이거 몰라도 코딩하는데 안 죽는다.
자료형의 크기는 절대적인가?
아니다 컴파일러, 운영체제, 하드웨어 아키텍처 등에 따라 자료형의 크기가 다를 수 있다,
32bit 시스템에서 int는 4byte이지만 64bit 시스템에선 8byte일 수 있다.
또한 java에서는 char가 2byte이다.
이번엔 변수와 데이터 타입에 이론과 예제 코드를 살펴보았다.
이해가 가지 않는다면 괜찮다. 처음 접하는 사람은 당연히 어려울 수 있기 때문이다.
하지만 중요한 부분이기 때문에 언젠가는 꼭.. 이해가 가길 바란다.....
다음은 서식 지정자, 세미콜론, 주석, 중괄호, 들여쓰기, 주석을 알아보도록 하겠다
사실 다음이 훨씬 쉽다.

'쉽게 쓰여진 C' 카테고리의 다른 글
| [C언어 4강] 연산자 + 이진수 체계 (0) | 2023.04.29 |
|---|---|
| [C언어 3강] 서식 지정자, 세미콜론, 주석, 중괄호, 들여쓰기 (0) | 2023.04.17 |
| [C언어 2-0강] 변수와 데이터 타입 (기초) (2) | 2023.04.09 |
| [C언어 1강] printf (0) | 2023.04.07 |
| C언어 세팅 Visual Studio 2022 (0) | 2023.04.07 |