간단 지식/C

01. c언어 기초 간단 정리

납작한돌맹이 2020. 7. 13. 03:13
반응형

c언어의 시작은 포인터부터라고 생각하기 때문에 그 전까지는 간단하게 핵심만 정리해보았다. 여기까지는 자바와 거의 이론이 비슷하기 때문에 더 참고해야하는 사항이 있으면 자바 카테고리에 가면 된다.


  • 2진수, 10진수, 16진수

2진수는 수를 0과 1로 표현한다.

10진수는 우리가 흔히 아는 자연수이다. 

16진수는 수를 0~9, A~F 로 표현한다.

 

각 진수들은 아래처럼 서로 변환할 수 있다.

1). 2진수 -> 10진수

    ex. 10101001 = 169

2) 10진수 -> 2진수

    ex. 202 = 11001010

3) 16진수 -> 2진수

   ex. 4F3C = 0100111100111100

16진수 2진수   16진수 2진수
0 0000   A 1010
1 0001   B 1011
2 0010   C 1100
3 0011   D 1101
4 0100   E 1110
5 0101   F 1111
6 0110      
7 0111      
8 1000      
9 1001      

  • 변수

수많은 데이터들이 컴퓨터 메모리에 저장된다. 이 메모리를 램(ram)이라고 부르며 아래 그림처럼 조직되어 있다.

한 공간 당 1byte의 크기를 차지하며, 해당 공간의 주소는 대개 16진법으로 나타낸다. 그리고 각 주소들을 쉽게 이용하기 위해 변수가 필요한 것이다.

 

자바와 마찬가지로 c언어도 데이터 타입이 존재한다.

bool, char(1byte) < short(2) < int, long, float(4) < double(8)

다만 몇가지 차이점이 존재한다. 첫째로, #include <stdbool.h> 를 적어줘야지 bool, true, false를 사용할 수 있다. 둘째로, 문자열을 위한 타입이 따로 없다. 문자열은 문자형들이 모여 만들어지기 때문에 char타입이지만, 변수에 저장하지 않고 char타입 배열에 저장한다. 

 

수를 표현하는 범위는 unsigned, signed에 따라 다르다. unsigned는 양수만 표현가능하고 signed는 음수, 양수 둘 다 표현가능하지만 음수, 양수의 표현 범위는 unsigned의 1/2가 된다. 즉 표현 범위는 다르지만, 절대적인 크기는 같다.


  • 비트연산자와 논리연산자

비트연산자에는 &  |  ^  ~  >>  << 가 있다.

&는 AND라는 의미로, 두 비트가 모두 1이여야 결과비트가 1이 된다.

|는 OR라는 의미로, 두 비트 중 하나만 1이어도 결과비트가 1이 된다.

^는 XOR라는 의미로, 두 비트가 1이면 결과비트는 0, 두 비트 중 하나가 1이면 결과비트가 1이 된다. 

~는 NOT이라는 의미로, 비트가 1이면 결과비트는 0, 0이면 1이 된다.

>>는 RIGHT SHIFT라는 의미로,  비트를 오른쪽으로 한칸씩 이동시킨다. 새롭게 채워야하는 가장 왼쪽 비트에는 sign bit로 채워주고 밀려나간 비트는 삭제한다.

<<는 LEFT SHIFT라는 의미로, 비트를 왼쪽으로 한칸씩 이동시킨다. 새롭게 채워야하는 가장 오른쪽 비트에는 0으로 채워주고 밀려나간 비트는 삭제한다.

 

논리연산자에는 &&  ||  ! 가 있다.

&&는 AND라는 의미로, 두 조건식을 모두 만족해야 true 이다.

||는 OR라는 의미로, 두 조건식 중 하나 이상 만족하면 true 이다.

!는 NOT이라는 의미로, 조건식의 반대가 true이다.


  • printf(), scanf_s()

가장 대표적인 출력함수는 printf()이다. 직접적인 문장을 출력하고 싶다면 printf("문장"); 을, 변수에 저장된 값을 출력하고 싶다면 printf("%_?_", 변수); 를 실행시키면 된다. 이때 ?에 들어가야하는 식은 변수가 어떤 타입이냐에 따라 다르다. int형이라면 %d, char형이라면 %c, 문자열이라면 %s, float형이라면 %f, double형이라면 %f, 그 외에 8진수는 %o, 16진수는 %x 이다.

 

가장 대표적인 입력함수는 scanf_s()이다. scanf("%_?_", &변수); 를 실행시키면 된다. 마찬가지로 ?에는 입력할 데이터의 타입에 따라 다른 식이 들어가야한다. printf()와 약간의 차이가 있는데, 바로 float과 double을 입력할 때 사용하는 식이다. float형은 %f로 똑같지만, double은 %lf를 입력해줘야한다. 참고로 scanf()는 버퍼 오버플로우 문제를 발생시킬 가능성이 있기 때문에 openMP에서나 몇가지 상황을 제하면 잘 쓰이지 않는다.


  • 형변환

자바와 마찬가지로 표현범위가 작은 데이터 타입에서 큰 타입으로의 형변환은 아무 문제가 없다. 차이점이 있다면 c에서는 큰 타입에서 작은 타입으로의 형변환도 컴파일 에러없이 실행된다는 것이다. 다만 컴파일러는 warning메시지를 통해 데이터손실이 일어날 수 있다는 것을 알려준다. 따라서 캐스팅을 해주면 warning 메시지를 없앨 수 있다. 실제로 데이터 손실이 일어날 가능성이 매우매우 농후하기 때문에 에러가 안일어난다고 무시하지 말고 캐스팅을 하도록 하자.

 

추가로 산술변환에 대해서 간략히 알아보자. 자료형이 다른 두 변수를 연산 할 시 범위가 더 큰 타입으로 결과가 나오는 것을 산술변환이라고 말한다. 예를 들어 int형 변수 a, double형 변수 b가 있다고 한다면, a/b의 결과는 실수가 나온다.


  • 배열

선언 방식은 타입 이름[크기]; 이다. 필요에 따라 바로 원소를 저장할 수도 있고 크기만 선언할 수 도 있다.

ex) int arr[4] = {1,2,3,4};

이때 배열의 크기 자리에는 오로지 자연수 또는 상수만 넣을 수 있다. 변수가 들어갈 수 없다. 또는 위 예시처럼 배열에 채울 원소들을 다 알고 있다면 int arr[] = {1,2,3,4}; 처럼 크기를 생략할 수 도 있다. 참고로 상수는 const 타입 이름 = 값; 으로 지정하는 불변의 데이터다.

배열을 초기화 하고 난 뒤에 빈공간이 존재한다면 그 곳은 출력해보면 0으로 나온다. 그러나 초기화를 하지 않고 선언만 하고 출력을 한다면 쓰레기값만 볼 수 있으니 주의하자. 의외로 코딩을 하다보면 자주 하는 실수다.

다차원 배열 역시 자바와 다를 것 없이 타입 이름[크기1][크기2]; 로 선언해서 사용하면 된다. 다만 c언어에서는 크기1 자리는 생략이 가능하지만 크기2자리는 절대 생략 불가이다.

자바와는 달리 c언어는 문자열을 위한 데이터타입이 따로 존재하지 않는다. 그래서 배열이나 포인터를 이용한다. 포인터에 대해선 다음 글에서 정리해두었고 배열을 이용해서 문자열을 저장하는 방법은 간단하다.

예를 들어 char str[6] = "happy"; 는 문자열 happy를 문자열 배열 str에 저장하게 해준다.

 

위 그림은 배열에 문자열이 어떻게 저장되는지를 보여준다. 이때 마지막의 \0은 문자열의 끝을 알리는 널문자로, 꼭 이 공간을 고려하고 배열을 생성해야한다.

 

 

 

 

(이 글이 도움이 됐다면 광고 한번씩만 클릭 해주시면 감사드립니다, 더 좋은 정보글 작성하도록 노력하겠습니다 :) )

 

 

반응형