#1 C 언어

송민혁·2022년 8월 30일
0

C

목록 보기
1/2

프론트엔드를 목표를 두고 있지만, 복수전공인 컴공을 졸업하기 위해 C언어를 해야 한다. 여기다가 공부한 걸 기록하면 좋을 것 같아서 내년 6월까지 이렇게 C언어에 대한 글을 쓸 것 같다.

목차
1. 인트로
2. 컴파일
3. 상수와 데이터 출력
4. 변수와 데이터 입력
5. 연산자
6. 조건문(선택문)
7. 반복문
8. 함수
9. 배열


인트로

C언어는 1972년 탄생했으며, 데니스 리치가 UNIX 시스템(운영체제)를 사용하기 위해 B언어에서 발전시킨 언어이다.
C언어의 장점을 말하자면 다음과 같습니다.

  • 시스템 프로그래밍이 가능합니다. : 운영체제를 개발할 목적으로 만든 언어이다.
  • 이식성을 갖춘 프로그램을 만들 수 있습니다. : 기종이 다른 컴퓨터라도 적용이 가능하다.
  • 함수를 사용하여 개별 프로그래밍이 가능하다. : 함수로 프로그램 유지보수가 수월하다.

컴파일

컴파일이란 소스 파일을 기계어로 바꾸는 과정을 의미한다.
컴파일하기 위한 소스 파일을 만들기 위해서 텍스트 에디터가 필요하다. 많은 에디터 중에서 Visual Studio를 사용한다.

유의사항

  • 파일 이름의 확장자는 꼭 .c를 넣어야 한다. : 그렇지 않으면, C++의 문법이 적용될 수 있다.
  • 소스 파일을 메모장으로 작성할 수 있다. : 단 텍스트 파일로 저장하여야 한다.

(에러를 수정하는 것을 디버깅이라고 한다.)


첫 컴파일 성공!


이것저것 추가해보고 빌드(Ctrl+Shift+B)해보고 출력(Ctrl + F5)해보았다.


컴파일 과정

컴파일 과정은 아래 이미지와 같다.

전처리기 (Preprocessor)

전처리기 구문(#으로 시작하는 구문)을 처리하는 것이 바로 전처리기라고 하는데, 일반적으로 #으로 시작하는 부분을 거의 항상 사용합니다. 그것이 언제냐면 바로 #include이다. printf를 사용하기 위해서는 항상 #include <stdio.h>를 항상 명시해주어야 합니다.
다른 예시로 #define A 10 과 같은 줄을 볼 수 있습니다. 여기서 전처리기는 A라는 부분을 단순히 10으로 치환합니다.

중요한 것은 전처리기가 컴파일 단계 맨 처음 단계라는 것을 기억하여야 한다. 그래야지 전처리를 통한 조건부 컴파일을 이해하게 됩니다.

컴파일러 (Compiler)

전처리기를 거치면 컴파일러로 컴파일 과정을 거치면 된다. 컴파일러는 전처리가 끝난 파일을 컴파일하면 개체 파일이 됩니다. 다시 말해, 고수준언어를 저수준언어로 나타내는 역할을 수행한다.

어셈블러 (Assembler)

어셈블러를 통하여 완전히 기계어로 바꿔주는 과정을 거치면 된다.

링커 (Linker)

링커는 이름이 말해주듯 연결해주는 역할을 합니다. 개체 파일에 start.code를 겹하는 과정을 수행하는데 이 과정을 링크라고 합니다. 여러 개의 오브젝트 파일을 하나로 합치거나 라이브러리를 합칠 때 링커가 필요합니다.

요약하기
컴파일 과정은 전처리-컴파일-링크의 세 단계를 거친다.
파일은 1. 소스 파일 2. 전처리된 소스 파일 3. 개체파일 4. 실행파일으로 변한다.


상수와 데이터 출력

본격적으로 C 프로그램의 구조를 살펴보고, C 프로그램에서 값을 표현하는 방법과 결과를 화면에 출력하는 방법에 대해 살펴보고 컴퓨터 내부에 값이 저장되는 방식을 알아봅시다.

주요 키워드
main 함수, printf 함수, 제어 문자, 변환 문자

main 함수

main함수는 머리와 몸통으로 나누어집니다. 머리는 함수 원형(function prototype)이라 합니다. 아래 코딩에서 머리 부분은 int main(void)에 해당하는 부분입니다. 그 아랫부분은 몸통에 해당합니다.

int main(void)
{
         //실행 코드
         
         return 0; // 항상 프로그램을 종료할 때는 이렇게 작성한다.
 }

출력 함수 (printf)

화면에 데이터를 출력할 때는 printf 함수를 사용합니다. (프린트에프라고 읽습니다.)
아래 내용을 자세히 살펴보자면, 1행의 #include <stdio.h>라는 코드는 stdio.h를 불러온다는 의미이며, stdio.h 파일의 내용을 프로그램 안에 복사한다는 의미입니다.
stdio.h는 standard input putput을 의미합니다.

아직 코드가 불안정하네요. 여기서 줄바꿈은 어떻게 하면 될까요?

제어 문자 출력

printf 함수로 출력할 때 행을 바꾸려면 제어 문자를 사용해야 합니다. 제어 문자는 출력 방식에 영향을 주는 문자를 의맣ㅂ니다.
예를 들어, 백슬래시(\)를 의미합니다.

  • \n (new line): 줄바꿈
  • \t : 탭 위치로 이동
  • \r (캐리지 리턴): 맨 앞으로 이동
  • \b (backspace): 왼쪽으로 한 칸 이동
  • \a (alert, 벨소리): 벨소리를 낸다(=한 번 말한다(?))
printf("Be happy\n");
printf("My\tfriend\n");
printf("Goot\bd\tchance\n"); //Good Chance
printf("Cow\rW\a\n"); //Wow

정수와 실수 출력 (변환 문자)

printf 함수는 기본적으로 문자열을 출력하는 함수입니다. 따라서 숫자를 출력할 때는 변환 문자를 사용해서 숫자를 문자열로 변환하는 과정이 필요합니다.
변환 문자는 데이터의 형태에 따라 다릅니다. 정수는 %d, 실수는 %lf를 사용합니다.
(%d는 decimal, %lf는 long float를 의미합니다.)


여기서 새로 안 점은 문장의 양식을 먼저 쓴 뒤에 뒤에 숫자를 껴맞추면 된다.
printf("%d과 %d의 합은 %d입니다.\n", 10, 20, 10+20);
그리고 숫자를 어떻게 출력할지 내가 설정할 수 있다.

%.1lf (소수점 이하 첫째 자리까지 출력(둘째 자리에서 반올림)
%.10lf (소수점 이하 10자리까지 출력)

요약하기

  • C 프로그램은 main 함수로 시작한다.
  • printf 함수는 데이터를 화면에 출력할 때 사용한다.
  • 제어 문자를 문자열 안에 포함시키면 그 기능에 따라 출력 형태가 바뀐다.
  • printf 함수로 숫자를 출력할 때는 정수 %d, 실수는 %lf 변환 문자를 사용한다.

상수와 데이터 표현 방법

C언어에서 다루는 데이터에는 정수, 실수, 문자, 문자열이 있습니다.
이 데이터는 값을 바꿀 수 있는 변수와 값을 바꿀 수 없는 상수가 있습니다.

C언어에서 진법 표현하기

10진수는 우리가 알던 그대로 표현하면 되지만, 16진수0x(영엑스)를 붙여 구분합니다.

printf("%d\n", 12);
printf("%d\n", 0xc);
진법
10진수0123456789101112131415
16진수0x00x10x20x30x40x50x60x70x80x90xa0xb0xc0xd0xe0xf

실수 상수 표현법

실수는 소수점 형태와 지수 형태로 표현할 수 있습니다.

소수점 형태는 숫자 0~9, +,- 기호와 소수점을 사용하여 표현합니다.
반면에, 지수 형태는 수학에서 알던 지수 표기법에서 나온 표기입니다.
0.0000314 = 3.14 * 10^(-5) 를 3.14e-5라고 표현합니다.
위와 같이 소수점 앞에 0이 아닌 유효 숫자 한 자리를 사용하여 지수 형태로 바꾼 것을 정규화 표기법(normalization)이라고 합니다.

(혹은 0.314e-4 , 31.4E-6 이렇게 표현하기도 하고 e의 대소문자는 신경 안 써도 된다.)

100 = 1e2, 10000 = 1e4

문자와 문자열 상수 표현법

문자와 문자열 상수의 차이는 간단하다. 문자 상수는 작은따옴표로 묶고 문자열은 큰따옴표로 묶는다.
문자의 변환 문자는 %c, 문자열의 변환 문자는 %s으로 쓰면 된다.


변수와 데이터 입력

변수

프로그램에서 데이터를 메모리에 저장해 놓으면 필요할 때마다 거내 사용할 수 있습니다. 이때 변수 선언을 통해 메모리에 저장 공간을 확보합니다. 변수는 데이터의 종류에 따라 각각 다른 형태를 사용하는데, 정수는 int, 실수는 double, 문자는 char , 문자열은 char 배열을 사용합니다.

변수 선언 방법

int a; // int형 변수 선언
a = 10; //초기화

정수를 사용할 공간을 a라 이름을 붙여 메모리에 4바이트 할당하겠다라는 의미이다.
그리고 a라는 공간에 10라는 값을 할당한다.

//변수의 선언과 사용
#include <stdio.h>

int main(void)
{
         int a;
         int b, c;
         douvle da;
         char ch;
         
         a = 10;
         b = a;
         c = a + 20;
         da = 3.5;
         ch = 'A';
         
         printf("변수 a의 값 : %d\n", a);
		 printf("변수 b의 값 : %d\n", b);
		 printf("변수 c의 값 : %d\n", c);
		 printf("변수 da의 값 : %.1lf\n", da);
		 printf("변수 ch의 값 : %c\n", ch);

		return 0;
}

여기서 알 수 있는 사실은 변수의 자료형이 같으면 동시에 둘 이상의 변수를 선언할 수 있다.
(int b,c;)

=를 기준으로 왼쪽에 있는 a와 오른쪽에 있는 a가 있다. 이 둘은 서로 다르다. 왼쪽에 있는 a는 저장공간이며, 오른쪽에 있는 a는 을 의미한다.
이것을 구분하기 위해 용어가 있다. l-value(left value)r-value(right value)이다.

정수 자료형

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

정수 자료형 분류

  • char (1byte) : 문자를 저장하는 용도
  • short (2byte)
  • int (4byte) : 정수형을 저장하는 용도(범위: -2^31 ~ 2^31-1)
  • long (4byte) : 큰 값 전용
  • long long (8byte)

cf) unsigned 정수 자료형이란 나이와 같이 음수가 없는 데이터를 저장할 때 사용하는 키워드입니다. 그리고 %d 대신에 %u를 사용해야 큰 양수값도 잘 출력이 된다.

unsigned int a;

a = 4294967295;
printf("%u\n", a); /// 4294967295

실수 자료형

실수 자료형 분류

  • float (7byte)
  • double (15byte) : 유효 숫자가 많은 실수형 쓸 때 쓰임.
  • long double (15byte 이상)

문자열 저장

문자열 저장하는 방법

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

왜 문자열의 길이보다 배열의 크기를 하나 더 크게 잡아야 할까? 바로 컴파일러가 문자열의 끝에 \0 (널 문자)을 자동으로 추가하기 때문이다.

문자열은 char형을 배열 형태로 만들어 저장하며 %s로 출력한다.

const 상수

상수 선언식
const 자료형 변수명 = 값;

ex) const double pi = 3.14;

const는 변수와 달리 반드시 선언과 동시에 초기화해야 한다.

예약어와 식별자

예약어(키워드)는 컴파일러와 사용 방법이 약속된 단어이고 (즉, 프로그램이 미리 정해준 단어), 식별자는 내가 지은 별명 같은 거라고 생각하면 된다.

식별자 규칙으로는 다음과 같습니다.

  • 알파벳 대문자, 소문자, 숫자, 밑줄(_)로 만듭니다.
  • 숫자로 시작할 수 없다.
  • 대문자와 소문자는 서로 다른 식별자로 인식한다.
  • 키워드는 식별자로 사용할 수 없다.

데이터 입력

키보드에서 타이핑하는 모든 내용은 문자로 인식됩니다. 따라서 입력한 데이터를 연산이 가능한 정수나 실수로 사용하려면 변환 과정이 필요합니다. 이때 사용하는 함수은 바로 scanf 함수입니다. scan formatted라는 뜻으로 입력 문자들을 스캔하여 원하는 형태의 데이터로 바꿔주는 기능을 합니다.

scanf 함수 사용법

scanf 함수는 키보드에서 입력한 값을 변수에 저장할 때 사용합니다. scanf 함수 사용법은 변수의 형태에 맞는 변환 문자를 사용하고 입력할 변수 앞에 & 기호를 붙이면 됩니다.

scanf("%d", &a);

#include <stdio.h>

int main(void) 
{
	int a;
         
    scanf("%d", &a);
	printf("입력된 값 : %d\n", a); //키보드에서 입력

	return 0;
}

scanf 함수를 쓸 때 세 가지를 유의해야 한다.

첫 번째로는 scanf 함수에서 변수명을 지정할 때는 &을 붙여야 합니다.
두 번째는 scanf 함수에서 사용한 변호나 문자와 맞는 형태의 데이터를 입력해야 합니다.
(%d, %s, %c ...)
세 번째는 문자열을 입력할 때는 배열명에 & 기호를 붙이지 않습니다.
scanf 함수의 신기한 점으로는 여러 개의 변환 문자를 나열하여 한 번에 2개 이상의 변수에 값을 입력할 수 있습니다.

scanf("%d%lf", &a, &b);

연산자

산술 연산자, 대입 연산자, 증감 연산자, 비교 연산자, 논리 연산자은 앞서 JS에서 배우던 것과 같으므로 생략하고 그 이외의 고급 연산자에 대해 알아보자.
고급 연산자는 형 변환 연산자, sizeof 연산자, 복합대입 연산자가 있다.

형 변환 연산자

형 변환 연산자는 내가 원하는 데이터 타입을 설정할 때 씁니다.
방법은 간단하게 (자료형)피연산자를 입력하면 됩니다.
예를 들어 int 타입에서 double 타입으로 바꾸고 싶을 때, (double)10을 입력하면 10.0이 됩니다.

sizeof 연산자

sizeof 연산자는 피연산자를 하나만 사용할 수 있으며 피연산자의 크기를 바이트 단위로 계산해서 알려줍니다.

복합대입 연산자

산술 복합대입 연산자로 +=, -=, *=, /=, %= 등이 있다.
ex) res *= b + 10; (res에 b+10을 곱한다)


제어문

제어문에는 선택문, 반복문, 분기문으로 크게 세 가지로 분류합니다.

제어문

  • 선택문: if, switch ~ case
  • 반복문: while, for, do~while
  • 분기문: break, continue, goto, return

선택문

여기서도 JS와 비슷하지만 한 가지 유의한다면 중괄호를 나는 반드시 쓰는 타입으로 작성하는 게 좋을 것 같다.

0개의 댓글