본문 바로가기

컴퓨터공학/C, C++

C,C++> 변수 이야기

변수

컴퓨터 주 기억 장치는 메모리(RAM)

결국 컴퓨터가 하는 일은 메모리에 있는 값을 연산, 조작하여 주변 장치에 보내는 동작의 조합일 뿐이다.   

컴퓨터는 메모리 위치를 구분하기 위해 번지(Address)를 사용한다.

예를 들어, 1234번지에서 1237번지까지 4바이트에 56을 기록한다. 

이런 식으로 동작한다.  하지만 주소값은 8자리 16진수로 표현이므로 사람이 기억하기 힘들다. 

그래서 숫자로 된 주소값에 별도 이름을 붙이는데 이것이 변수이다. 

컴파일러는 변수가 실제로 어떤 주소값을 가리키고 있는지 기억했다가

이 변수를 사용하면 실제 번지 값을 읽거나 쓰는 코드를 작성한다. 

 

변수의 종류

주소값은 변수의 시작 위치이다.

컴퓨터는 멤시작위치로부터 얼마나 메모리 양을 차지하고

메모리에 기억된 데이터를 어떤 종류로 해석할 지 정보가 필요하다. 

그래서 변수 선언에서 자료형과 이름을 쓰는 것이다. 

 

printf

표준 출력 함수로 프린트에프라고 읽는다. f는 Formatting의 약자이며 서식화된 출력을 한다는 뜻이다.

서식화는 조립이라고 생각. 

출력하기 전에 서식과 인수를 대응하여 조립하는 과정을 거친다. 

문자열 서식과 뒤 쪽의 인수는 1대1대응으로 갯수나 타입이 일치하지 않으면 Undefined 에러가 뜬다.

자주 쓰는 서식은 %d, %c, %s, %f 정도.

 

scanf

는 스캔에프라고 읽는다. printf와 동일한 서식.

printf와 다른 점이 있다면 실수 서식인 %f는 printf에서 float과 double 모두 대응하는데

scanf는 float만 대응하고 double은 %lf를 사용해야 한다. 

 

int와 long은 다른 타입이다. C언어 int형 정의는 CPU 레지스터와 동일한 크기를 가지는 타입으로 정의한다. 

레지스터는 CPU 내 임시 기억 장소이며 레지스터 크기에 따라서 CPU 비트 수를 정의한다. 

요즘은 64비트 CPU이므로 int형이 64비트(8바이트)이다. 

반면 long은 4바이트 고정이라서 어떤 플랫폼이든 4바이트이다. 

int와 long이 같은 경우는 32비트일 경우에만 같다. 

 

8진수는 0으로시작한다.

16진수는 0x로 시작한다. 

 

문자형은 문자 하나를 표현하는 자료형. 근데 컴퓨터는 원래 숫자밖에 몰라서 문자도 숫자로 기억한다.

그래서 어떤 숫자에 어떤 문자를 대응시킬 지 천차만별이다. 통상 아스키 코드 방식을 많이 사용한다.   

1바이트 고정이라 255가지 서로 다른 문자를 기억한다. 

문자형 변수에 'A'나 'B' 같은 문자형 상수를 대입할 수 있는데 

문자형 상수를 쓰는 대신 ch=65 또는 ch=0x41 처럼 아스키 코드값을 직접 대입할 수 있다.

문자나 숫자나 결과는 동일.

사실 문자형은 문자 하나를 저장할 수 있게 적당한 길이를 가진 변수라는 뜻이지 

오로지 문자만 저장하는게 아니다.

char 타입은 실제로 8비트 정수형이니까 작은 정수를 저장할 수 있다. 

즉, 문자든 정수든 어차피 정수값이 이 변수에 저장되는데,

문자 서식에 대응하면(%c) 문자가 출력되고 정수 서식(%d)에 대응하면 정수값이 출력된다. 

 

문자열 상수는 있지만 이걸 저장하는 문자열 타입은 없다. 자바에서는 있지만 C에선 없다. 문자형 변수 배열로 표현할 수 있고 포인터가 있기 대문에 굳이 필요 없는 것이다...

 

 

열거형

열거 멤버의 이름은 사람의 기억력을 도와주고 실수를 방지하기 위해 컴파일러가 사용하는 임시적이 값에 불과하다.

컴파일된 후에는 정수 상수와 같아진다.

즉 보이는 값은 문자열인데 사실 정수값이다. 

마치 변수 이름이 컴파일 중에만 사용되는 것과 같다.

실행 중에는 열거 멤버의 이름을 알 수 있는 방법은 없다. 

 

정수형, 문자형, 실수형, 열거형 

c언어가 제공하는 기본형 타입이다. 

void는 포인터와함수에서만 적용. 일반 변수에서는 사용 안 한다.

근데 사실 문자형과 열거형은 정수형의 변형이라고 볼 수 있다.

왜냐하면 문자형은 1바이트인 짧은 정수형이고,

열거형은 가능한 정수값의 집합이기 때문이다. 

결국 기본형은 정수 아니면 실수이다. 

 

배열

배열의 정의는 동일한 타입을 가지는 자료들의 집합.

다른 타입이 모이면 배열이 될 수 없다는 의미이다. 

다른 타입이 모이면 구조체가 되어야 한다. 

배열은 구조가 단순하여 속도가 빠르고 이해와 사용이 쉽기 때문에 단순 반복 작업과 아주 어울린다.

 

공용체는 구조체와 유사하지만 공용체는 멤버끼리 기억 공간을 같이 공유한다. 

 

포인터형

정수형과 실수형 변수는 수치값을 저장, 포인터형은 번지를 기억

메모리 위치를 기억하므로 직접 값을 조작할 수 있고 주변 값도 손댈 수 있다.

메모리 위치는 4바이트 주소이기 때문에 함수 인수로 전달할 수 있다.

함수로 포인터를 전달하면 메모리를 함수가 직접 조작할 수 있다. 

 

번지(Address)는 32비트 운영체제 환경에서는 32비트 가상 메모리 공간을 이용할 수 있다.

즉  값을 기억할 수 있는 최대 메모리 용량은 4G이다. 자세한 건 운영체제에서 확인하자.

메모리 위치를 구분하기 위해 번호를 붙여 관리하는데 이 번호를 번지라고 한다. 

 

예를 들어

int Num = 627;

이라는 선언문이 있을 경우 

사용자는 Num 변수가 메모리 어디에 할당되어 있는가 상관없이 변수값을 읽거나 쓰면 된다. 

컴파일러는 Num이 할당된 주소를 기억하다가 이 변수를 참조하면 해당 메모리 값을 읽어서 읽거나 쓴다. 

Num을 읽고 쓰는 건 기억되어 있는 값이지 주소값이 아니다. 

Num이 할당되어 있는 주소값을 알고 싶거나 직접 다루고 싶다면 이 때 포인터를 사용한다. 

 

값을 읽을 경우 Num을 바로 읽으면 되는데 왜 포인터를 이용하여 간접적으로 사용할까?

중간 과정을 거치면 많은 유용한 조작이 가능하기 때문이다. 

소프트웨어 공학에서 융통성을 위해 중간과정(레이어)을 삽입하는 경우가 빈번하다.

예를 들어서 자바 가상 머신이 레이어의 좋은 예시이다. 

네트워크는 7개의 레이어로 구성되어 있다. 

 

사용자 정의형은 기존 자료형과 동등해서 사용자 정의형의 배열을 만들 수 있고 포인터도 가능하다. 

가독성을 높이는 효과가 있어서 구조체처럼 큰 타입을 별도 타입으로 사용하는 경우가 많다. 

 

논리형

BOOL 타입은 열거형이든 사용자 정의형으로 정의되든 실제는 정수형.

따라서 변수 크기가 4바이트이다.  참 또는 거짓 두 가지 경우만 있으면 되는데 4바이트는 큰 메모리를 소비.

C++에서는 논리형 별도 기본 타입인 bool형으로 정의.

C에서는 BOOL 타입 C++에서는 bool 타입으로 사용 

어차피 둘 다 정수 호환형이라서 서로 호환된다. 대입하거나 인수로 전달할 때 정수형으로 확장되기 때문이다. 

1바이트 4바이트 큰 차이가 없어 보일 수 있지만 대용량 배열이나 구조체는 차이가 커질 수 있다.

처리 속도는 별 차이 없다. 왜냐하면 32비트 CPU는 한 번에 32비트를 처리하므로 8비트나 32비트나 똑같은 시간을 소비한다. 

 

 


프로그래밍의 장점 

1. 직접 내 뜻 대로 만들 수 있다.
2. 소프트웨어는 무한 복제가 가능하므로 누구든 프로그램을 사용할 수 있다. 
3. 한 번 만들어 놓고 끝나는 게 아니라 끊임 없는 수정 가능.
4. 기변 비용이 들지 않아서 자유로운 상상과 도전이 가능하다. 실패하더라도 시간과 노력 외 잃을 것이 없다. 

'컴퓨터공학 > C, C++' 카테고리의 다른 글

C,C++> 배열  (0) 2022.06.09
C,C++> 기억 부류  (0) 2022.06.08
C,C++> 함수  (0) 2022.06.06
C,C++> 조건문 제어문 연산자  (0) 2022.06.01
C, C++ 공부 프롤로그  (0) 2022.05.08