C 언어의 변수, 데이터 타입들,const,c언어 타입 한정자
사실 다른 언어에서 변수란걸 배웠을 것으로 예상 됩니다.
쉽게 말하자면 컴퓨터 메모리 주소값에 우리가 이름을 붙여준 것이나 다름 없습니다.
그리고 C 언어는 메모리 관리가 아주 중요합니다.
옛날엔 메모리를 적게쓰고 코드를 작성하는 사람이 코딩을 잘하는 사람이라고 했다고 합니다. ( 수십년 전 )
하지만 자바와 파이썬, 그리고 성능 좋은 컴퓨터 메모리들이 나와 더 이상 메모리를 크게 신경 쓸 필요가 없어졌다고 합니다만
IOT 제어를 할 땐 C 언어가 필수 입니다. PC 메모리 환경이 좋지 못한 곳에선 C 언어는 강점입니다. 현재도 정말 많이 쓰이고 있습니다.
✔️변수를 정의해보자
#include <stdio.h>
int main()
{
int a;
printf("a의 주소: %p", &a);
}
여기서 변수 앞에 & 를 붙이면 메모리 주소를 출력 할 수 있습니다.
✔️변수를 초기화 하고 대입해보자
#include <stdio.h>
int main()
{
int a = 1;
a =2;
}
위에 코드에선 처음에 정수 a 변수명에 1이라는 초기값을 주었습니다.
그리고 a를 2로 대입해주었습니다.
그럼 3이 되느냐? 아닙니다. 1위에 2가 덮어 씌워진다고 보면 됩니다.
결론은 a 는 2가 된다는 것입니다.
✔️변수 여러개 지정하기
#include <stdio.h>
int main()
{
int a = 3, b = 2; // 정수형 변수 a와 b를 선언하고 각각 3과 2로 초기화
int c, d; // 정수형 변수 c와 d를 선언 (초기화되지 않음)
int x1, x2 = 5; // 정수형 변수 x1과 x2를 선언, x2는 5로 초기화되고 x1은 초기화되지 않음
}
위에서 초기화 되지 않은 변수들은 나중에 따로 값을 주어 초기화 해주어야 합니다.
#include <stdio.h>
int main()
{
int c, d; // 초기화되지 않음
printf("c = %d, d = %d, x1 = %d\n", c, d, x1); // 쓰레기 값 출력 가능
c = 10; // 값 할당
d = 20; // 값 할당
x1 = 15; //값 할당
printf("c = %d, d = %d, x1 = %d\n", c, d, x1); // 이제 정상적인 값 출력
}
printf("c = %d, d = %d, x1 = %d\n", c, d, x1); // 쓰레기 값 출력 가능
위에 쓰레기 값이라는건 제가 임의로 하는 말이나 욕이 아니라 변수가 초기화되지 않았을 때, 메모리에 남아 있는 임의의 값(랜덤 값)이 출력되는 현상을 뜻합니다. 따라서 원하지 않는 값이 출력 될 수 있습니다.
✔️타입 한정자 const
변수의 타입은 코드를 작성하는 사람이 지정해주어 타입 지정자라고도 합니다. 하지만 타입 한정자도 있습니다.
const 가 타입에 한정 될 경우 해당 타입의 변수는 정의된 이후에 값을 대입할 수 없습니다. ( 변수의 정의와 초기화는 가능)
#include <stdio.h>
int main() {
const int a = 10; // const 변수 선언 및 초기화
printf("a = %d\n", a);
// a = 20; // 오류! const 변수는 값을 변경할 수 없음
return 0;
}
헷갈릴 수 있으나 처음에 변수를 초기화 할 땐 가능하나 이후에 수정할 수 없습니다. 변수 a 에 값을 변경 할 수 없다고 보면 됩니다.
그렇다면 const 는 언제 사용하는지 예시를 보여드리겠습니다.
보통 변하지 않는 상수값, 함수 매개 변수를 보호 할 때 사용합니다. ( 그 외에도 다양함 )
#include <stdio.h>
int main() {
const double PI = 3.14159; // 원주율은 변하지 않음, PI 라는 변수 명엔 이미 원주율이 고정되어 있음
printf("PI = %f\n", PI);
// PI = 3.14; // 오류! const 변수는 값을 변경할 수 없음
return 0;
}
주석과 코드를 자세히 보면 PI 라는 변수 명에 상수값인 원주율이 고정되어 있기에 PI = 3.14; 값을 따로 줄 수 없습니다.
#include <stdio.h>
void printMessage(const char *message) {
// message[0] = 'H'; // 오류! const로 인해 문자열 변경 불가
printf("%s\n", message);
}
int main() {
char str[] = "Hello, world!";
printMessage(str);
return 0;
}
const char *message는 "이 포인터가 가리키는 문자열을 변경하지 못하게 하겠다"는 의미입니다.
"Hello, World!" 같은 문자열 리터럴을 가리키는 경우, 해당 문자열은 읽기 전용이므로 수정하려 하면 오류 발생합니다.
char str[] = "Hello, World!";는 문자열을 배열에 복사하는 것이므로, 값을 변경할 수 있습니다.
👌즉, 포인터가 문자열 리터럴을 가리키면 수정할 수 없고, 배열이면 수정할 수 있다!
제가 코드를 알아가면서 배움에 어려움이 많았던 이유가 "왜?" 였습니다.
const char *message 이런것도 왜? 라는 질문을 하면서 이해를 못했었습니다. 그러다보니 느리고 금방 지치기도 했습니다.
그러나 물론 하나하나 뜯어보면 수학의 원리처럼 이유라는게 존재 할 수도 있지만 제가 생각하기엔 그냥 사과를 보고 영어권 사람들이 apple 라고 부르기로 했다는 것 처럼, 그냥 이러한 역할을 하는 것을 이렇게 부르기로 했구나 하고 넘어가니 한결 편해졌습니다.
포기하지 말고 느려도 천천히 하면 될 것이라고 믿습니다.
감사합니다.❤️