본문 바로가기

카테고리 없음

[ 정보처리기사 ] 프로그래밍 언어(C언어)

소프트웨어 개발 단계(절차)는 클라이언트의 요구사항을 확인하고, 요구사항에 기반하여 설계하고, 설계에 기반하여 구현(개발)하고,

구현한 후에 테스트(시험)를 거쳐, 시기에 따라 소프트웨어가 최신버전으로 업그레이드하고, 문제가 있으면 해결하는 등 유지보수까지로 구성된다. 정보처리기사 필기에서 소프트웨어 설계 과목의 세부사항은 요구사항 확인과 설계로 구성된다. 

 

프로그래밍 언어 파트는 소프트웨어 개발 단계에서 구현(개발) 부분에 해당한다.

소프트웨어를 개발(구현)할 때 사용하는 프로그래밍 언어에는 C언어, Java, Python 등이 있다.

프로그램을 구현할 때 개발자가 사용하는 언어가 프로그래밍 언어고,

개발자가 프로그램을 구현하기 위해 프로그래밍 언어로 작성하는 과정을 프로그래밍이라고 한다.

- 경우의 수를 고려한 다양한 상황에서 문제없이 잘 작동할 수 있도록

작동 방법과 단계를 명령어 작성하는데, 이 명령어의 집합을 프로그램이라고 한다.

컴퓨터에게 어떻게 작동하라고 명령을 할 때 사용되는 명령어는 여러 종류가 있고,

명령어의 집합(프로그램)의 종류를 프로그래밍 언어라고 한다 → 프로그래밍 언어는 그냥 명령어의 종류라고 해도 될 듯?

 

컴퓨터와 프로그래밍 언어로 대화할 수 있으며

프로그래밍 언어는 크게 두 가지로 나뉜다 - 컴퓨터 중심의 저급 언어(기계어, 0과 1)와 사용자 중심의 고급 언어(C, Java, Python 등)

컴퓨터 중심의 → 컴파일러(번역기)를 거치지 않고 컴퓨터와 바로 대화할 수 있는 언어라는 의미, 컴퓨터가 이해하는 언어는 2진수, 정보는 0과 1로 표현된다 - 비트(bit, binary digit)라고 불리는 0과 1의 값. 고급언어의 경우 10진수, 개발자가 이해하기 쉬운 언어로 구성되어 있어, 고급 언어로 프로그램을 작성했을 때, 컴파일러를 통해 변환을 해야 컴퓨터가 이해할 수 있는 언어가 된다.

 

컴퓨터는 0과 1 형태로 구성된(2진수) 프로그램만 바로 이해할 수 있는데,

만약 프로그램이 0과 1 외의 (영)문자들로 구성되었다면

번역기(컴파일러)를 거쳐(고급언어 → 저급언어, 변환과정)

0과 1 형태로 변환되어야만 컴퓨터가 이해할 수 있게 한다.

 

컴퓨터는 0과 1 형태로 작성되어 있는 명령어의 집합(프로그램)만 이해할 수 있다.

 

자료(데이터)의 단위는 2진수 단위로 시작하는데

정보의 최소 단위는 bit, bit로 나타낼 수 있는 정보의 형태는 1과 0 → 2가지 경우다. 2^1

1bit는 0또는 1 형태의 정보를 담을 수 있다.

1bit가 8개면 1Byte → 2^8 → 256가지의 경우의 수를 나타낼 수 있다.

1bit → 1Byte → 1Kb → 1Mb → 1Gb → 1Tb

 

bit가 나타내는 정보를 컴퓨터가 이해하는 과정:

0인 경우 1.5V(볼트)를, 1인 경우 5V(볼트)의 전기적 신호를 컴퓨터에게 보내 0과 1을 구별할 수 있게 한다.

 

아스키: ASCII: American Standard Code for Information Interchange (미국 정보교환 표준코드)

아스키는 출력가능한 문자(영문자, 특수문자, 숫자 등)와 출력하진 않고 출력에 도움이 되는 제어문자 등에 대해

컴퓨터가 이해할 수 있는 전기적 신호로 변환하는 기준을 정리해 놓은 표(table)인 것 같다.

나타낼 수 있는 128가지의 경우의 수를 정리해 놓았다. (→ 7bit, 0과 1로 구성된 128가지의 문자들)

128가지의 경우의 수가 표현할 수 있는 문자들은 출력가능한 영문 알파벳의 대/소문자 52개,

10개의 숫자(0부터 9까지), 하나의 공백문자, 32개의 특수문자, 출력 불가능한 제어문자 33개로 구성되어 있다.

아스키의 단점은 출력가능한 문자 95개와 출력불가능한 문자 33개, 총 128개의 문자만 표현이 가능하다,

즉 그 외의 문자들(한국어, 중국어 등), 여러 언어들을 표현할 수 없는 문제점으로 인해 유니코드(Uni Code)가 나오게 된다.

 

유니코드는 16비트, 최대 65,536자 표현이 가능하여 각 나라별 언어들을 모두 표현할 수 있다.

 

C언어 문법

- ;(세미콜론)은 문장의 끝을 의미하는 마침표

항상 main()이라는 함수로부터 (프로그램 )실행이 시작된다. main() 함수는 프로그램의 시작점,

  운영체제에서 프로그램을 시작할 때 main() 함수를 호출한다. 

- #include <stdio.h> → 헤더파일(.h) 은 자주 사용되는 변수나 함수를 외부에서 편리하게 사용하기 위해 만들어진 파일이다.

자주 사용되는 변수나 함수에 대한 정의를 작성한 파일들이 헤더파일에 작성되어 있고(예를 들면 printf() 함수에 관한 정의 등)

헤더파일을 현재 파일에 포함하기 때문에 → #include <studio.h>

현재 파일에서 헤더파일에 있는 파일들에 정의되어 있는 변수나 함수들을 사용할 수 있는 것이다.

# 은 전처리기, 먼저 처리하는 기호를 의미하고, include는 포함하는 것을 의미한다.

#include 는 먼저 포함하는 것을 수행하라는 것이다. 무엇을?

외부파일인  파일을 현재 파일에 먼저 포함시키는 것을 지시하는 것.

 

데이터(자료) 타입: 자료의 종류가 무엇인가? 자료가 무엇인지를 데이터 타입을 통해 유추할 수 있음. 예를 들어 변수(저장 공간, 저장 공간에 저장될 값은 바뀔 수 있음)에 어떤 값이 저장되어 있는데, 그 값이 정수인지, 실수인지, 문자인지를 데이터 타입을 보고 알 수 있다. 변수에 담긴 값이 정수라면 데이터 타입은 int가 된다. 데이터 타입은 변수 앞에 작성한다. 변수는 컴퓨터가 명령어를 처리하는 도중 발생하는 값을 저장하기 위한 공간으로, 변수에 저장되는 값은 변할 수 있다.  

 

변수이름 작성규칙

- 영문자, 숫자, _를 조합한다.

첫 글자는 영문자 또는 _(언더바) 사용이 가능하나 숫자는 첫 글자에 올 수 없다.

- 공백이나 특수문자(*, +, -, / 등)를 사용할 수 없다.

- 대/소문자를 구분한다.

- 예약어(미리 약속된 언어, ex. char, double, for, while 등)를 변수이름으로 사용할 수 없다.

- 변수 선언 시 문장 끝에 반드시 세미콜론(;)을 붙여야 한다.

- 글자 수에는 제한이 없다.

 

변수를 상수로 변경하는 예약어는 const,

상수는 프로그램이 시작되어 값이 한 번 결정되면 프로그램이 종료될 때까지 변경되지 않는 값을 의미한다.

상수(변수에 저장되는 값이 한 번 정해지면 변경할 수 없다)를 의미하는 예약어는

Java의 경우 변수명 앞에 final을 붙이고, C언어의 경우 변수이름 앞에 const를 붙인다.

 

c언어를 이용해서 문자 A의 값을 변수에 초기화, const char c = 'A'; 

const는 char라는 변수이름에 담길 초기(처음) 값이 프로그램이 종료될 때까지 변경되지 않는 값이라는 것을 알려주는 것,

char는 값을 저장할 공간의 이름(변수이름)이고, 변수이름에 'A'라는 문자를 =(대입연산자)를 이용해 초기화(처음에 값을 할당) 한다.

 

증(가)감(소) 연산자

++k → ++은 증가연산자인데, 변수명 앞에 있으므로 전치 증가연산자라고 한다.

전치 증가연산자는 변수에 저장된 값을 먼저 1 증가 시킨후 사용하라는 것,

k++ → 후치 증가연산자는 변수에 저장된 값을 먼저 사용한 후, 1을 증가시키는 것이다. 

 

증감 연산자는 단독 사용시 전치증감 연산자인지 후치증감 연산자인지 구분할 필요가 없다.

결과는 동일하기 때문이다. 단, 처리문 사용시에는 결과가 다르기 때문에 구분할 필요가 있다.

 

```

int x=10, y; 정수형 타입인 변수 x에 담긴 값은 10, 정수형 타입인 변수 y에 담긴 값은 0일 경우,

 

1. y=++x;

2. y=x++;

 

의 결과는 다르다.

 

1번의 경우 x에 담긴 값을 1 증가시킨 후(x=11) x의 값을 y에 대입하기 때문에 x와 y의 값은 같게 된다. x=11, y=11

2번의 경우 x에 담긴 값을 먼저 y에 담은 후(y=10), x의 값을 1증가 시키게 되어(x=11) x와 y의 값은 다르게 된다.

 

```

 

조건 연산자는 조건식의 결과에 따라 수식을 실행하는 것, 형식은 조건식 ? 수식1 : 수식2;

조건식이 참이라면 수식1을 수행하고, 조건식이 거짓이라면 수식2를 수행한다.

 

sizeof 연산자는 피연산자의 크기를 바이트(byte) 단위로 계산하는 연산자다.

데이터 타입중 int는 4byte의 크기를 갖고 있다.

 

제어문은 프로그래밍 언어로 작성된 명령문을 컨트롤하는 것, 흐름을 제어한다(Control Flow statement)

작성된 코드블록의 흐름을 상황에 따라 원하는 방향으로 작동하게 하려면 조건문과 반복문을 사용한다. 제어문 → 조건문과 반복문

작성한 조건(경우의 수)에 따라 명령어들을 수행할 경우 조건문을 작성하고, 어떤 명령문을 반복 수행시킬 때는 반복문을 작성한다.

 

어쨌든 제어문은 1. 조건이 지정되고, 2. (지정한 조건에 따라) 진행 순서를 변경할 수 있다는 특징이 있다.while(조건지정) {...} → 조건을 먼저 판단하고, 조건이 참일 경우, {}블록문 내부에 작성된 명령문을 실행한다.

while문의 경우 조건이 거짓이면 한 번도 수행하지 않는다.

 

do{...}~while(조건지정); 의 경우 우선 블록문 내부의 명령문을 실행하고,지정한 조건이 참일 경우 반복해서 블록문 내부의 명령문을 실행한다.

do{...}while(조건지정); 의 경우 조건이 거짓이더라도 한 번은 블록문 내부의 명령문을 실행한다는 특징이 있다.

지정된 조건을 판단하기 전에 일단 블록문 내부의 명령문을 실행하기 때문

(실행순서를 살펴보면 이해가 가능)

 

break문은 제어문에 사용되며(주로 while문에 사용), while문과 같은 가장 가까운 루프를 벗어나는 명령어다.

 

for문은 시작과 종료 조건을 지정하여 참인 동안에는 블록문안의 명령문을 반복한다는 것이다.

// statement 1은 {}코드블록이 시작되기 전에 한 번 실행된다.
// → 코드블록{}이 실행되기전: 반복이 실행되기전 변수에 저장될 처음 값을 설정한다.

// statement 2는 코드블록이 실행되기 위한 조건을 정의한다.
// → 코드블록{] 내부의 명령문들이 반복해서 수행되기 위한 조건을 정의한다.
// 만약 작성한 조건이 참이라면 반복은 처음부터 다시 실행될 것이다.
// If the condition is true, the loop will start over again,

// statement 3는 코드블록이 실행된 후에 매번 실행된다.
// → 루프 안의 코드블록이 실행될 때마다 값이 증감한다. 즉 루프가 한 번 돌 때마다 state 3이 실행된다.

for(statement 1; statement 2; statement 3) {
	// 수행할 명령어들을 이곳에 작성하기
}

 

다중 if문을 간략화하는 방안 → switch~case문

break문을 생략시 일치하는 실행문부터 switch문이 종료될 때까지 모든 문장을 실행한다.

 

break문은 switch~case문, for문, while문, do while문의 제어를 벗어나기 위해 사용하는 명령문이며,

가장 가까운 곳에 있는 하나의 루프(loop)만 벗어난다. continue문은 for문, while문, do while문에서

다음 반복을 실행하기 위해서 사용하는 명령문이다. continue문이 실행되면 continue문 아래의 코드들이 실행되지 않고,

바로 그 루프의 선두로 되돌아가서 명령문을 실행한다. continue문을 실행하게 되면 for문에서는 ***증감식을 수행하고,

while문에서는 *** 조건식을 검사한다. 

 

배열은 한 가지 자료형을 연속적으로 나열한 것,

우선 여러 개의 값을 저장할 공간에 저장될 자료의 타입을 적고 → int

배열의 이름을 작성하고 → int score

값을 저장할 공간이 몇 개인지 대괄호 안에 작성한다 → int score[3]; => 데이터타입 배열이름[배열의 크기];

배열의 크기란 데이터를 저장한 공간의 갯수를 의미하며, 3이라 작성했다면 데이터를 저장할 공간이 3개라는 것,

저장공간에 값을 저장하려면 '배열명[인덱스] = 값;' 의 형식을 따른다. 인덱스는 배열에 나열되어 있는 공간의 주소 같은 것,

배열 인덱스는 항상 '0'부터 시작한다. 

 

---------------------------------------------------------------------------------------------------------------------------------------------------

 

 

간헐적으로 arr[1]의 값으로 4096이 출력되는데 어떻게 이 값이 출력되는 걸까?

C언어에서 배열을 선언만하고, 그 배열이 갖는 공간들에 값을 명시적으로 초기화하지 않을 경우

배열의 요소들은 이전 메모리 상태에 따라 임의의 값을 가질 수 있기 때문에 메모리 상태에 따라 4096이 출력될 수 있다고 한다.

 

---------------------------------------------------------------------------------------------------------------------------------------------------

 

C언어에서는 문자 자료형인 char는 있지만 문자열을 저장할 수는 없다.

문자열을 저장하기 위해서는 문자(char) 배열을 사용한다.

 

// 배열 크기 생략시 반드시 초기 값을 지정해야 한다.
// 초기 값을 지정한 개수 만큼의 배열의 크기가 만들어지고, 해당 값이 배열의 요소에 차례대로 대입되기 때문
char string[] = "gisa first";

char string[10] = {'g', 'i', 's', 'a', ' ', 'f', 'i', 'r', 's', 't'};

 

***문자열은 선언과 동시에 초기화를 하지 않으면 에러가 발생한다.

이미 할당된 배열에는 문자열을 바로 넣을 수 없지만

string.h 헤더 파일의 strcpy함수를 사용하면 가능하다.

 

C언어에서 함수란자주 사용되는 명령문들을 하나로 묶고, 필요할 때마다 호출하기 위해 함수가 필요하고 → 효율적인 개발을 위해 함수가 필요함수는 표준함수와 사용자 정의 함수로 나뉜다. 표준함수는 내장함수라고도 하며, C언어로 프로그래밍을 하면서 자주 사용될법한 명령문들을 C언어 제작회사가 함수로 만들어 제공하는 것이고, 사용자 정의 함수는 프로그래머가 직접 만들어 정의할 수 있는 함수를 말한다. 프로그래머가 직접 함수를 작성하여 정의할 때 지켜야 하는 형식이 있는데

 

사용자 정의 함수 형식

 

```

리턴형 함수이름(매개변수){함수(이름) 호출시 수행할 동작들을 작성한다.}

```

 

- 리턴형은 해당 함수이름 호출시 어떤 결과가 나타나는데 해당 결과의 데이터타입을 작성한다.해당 함수가 정수를 반환한다면 리턴형 자리에 int를 작성하면 된다. 반환되는 값이 없는 경우 void를 작성한다.- 함수이름은 해당 함수 호출시 사용되며, 여러 함수중 해당 함수를 식별하기 위해 존재한다.- 매개변수는 파라미터(parameter)라고도 부르며, 함수가 전달받는 값으로 값의 타입과 함수 내부에서 사용될 이름을 적는다.파라미터는 있을 수도 있고, 없을 수도 있다.

 

main() 함수에서 return 0; 은 프로그램의 정상종료를 의미하고, 생략이 가능하다.

 

----------------------------------------------------------------------------------------------------------------------------------------------------------------

 

구조체(struct)는 데이터(변수)를 체계적으로 관리하기 위한 문법, 관련 정보를 하나의 의미로 묶을 때 사용한다.

- 객체라는 개념을 중심으로 프로그래밍 하는데 대표적인 언어 Java에서 구조체는 Class와 유사하다.

- 배열은 같은 자료형의 묶음, 구조체는 서로 다른 자료형의 묶음이 가능하다.

 

구조체 작성 형식

```

struct 구조체이름 {

// 자료형이 다른 변수들을 정의한다.

 

}

```

***구조체이름은 관례상 대문자로 작성한다.

 

typedef는 타입을 정의한다는 의미로, 자료형의 이름 길이가 긴 경우 프로그래머가 짧고 간결하게 자료형을 재정의하는 문법이다.

부호없는 정수타입을 unsigned int 라 한다. 부호없는 정수타입의 값을 담을 변수를 선언할 때, usigned int temp; 라고 작성할 수 있는데, unsigned int → 자료형 이름의 길이가 긴 경우, typedef unsigned int KWS; 이렇게 선언하면 부호없는 정수타입의 변수를 작성할 때 KWS temp; 이렇게 간략하게 작성이 가능하다. 구조체 정의에 구조체 별칭을 붙이면 구조체 변수를 선언할 때 struct을 붙이지 않아도 된다.

 

#include <stdio.h>

// 구조체 정의시 구조체 별칭을 붙인다.
typedef struct [이자리에 구조체이름을 작성하는데, 생략이 가능하다] {
	char name[20];
    int age;
    char addrress[100];
} PERSON; // PERSON이 구조체 별칭

int main() {
	PERSON p1 = {"류현진", 30, "대전"}; // p1은 구조체 변수 선언
    
    return 0; // 프로그램의 정상 종료, 생략 가능
}

 

-----------------------------------------------------------------------------------------------------------------------------------------------------------------

 

C언어에서 정수 자료형 → short[2Byte] ,  int, long[4Byte]

C언어에서 실수 자료형 중 크기가 제일 작은 것은 float[4Byte]

- float[4Byte] → double[8Byte]

C언어에서 문자형 자료형은 char

파이썬/C언어 변수작성시 유의사항:

- 영문 대/소문자, 숫자, _(언더바) 사용 가능하나 숫자는 변수명 첫 글자에 작성할 수 없고, 특수문자인 -(하이픈)을 작성할 수 없다.

**-(하이픈)와 _(언더바) 헷갈릴 수 있으니 구별하기

- 공백 사용이 불가하다. 만약 잇고 싶다면 park_sung_ju 이렇게 _(언더바기호)를 사용하여 작성할 것

- 변수 선언 시 문장 끝에 반드시 세미콜론(;)을 붙일 것, 글자 수에는 제한이 없고, 예약어를 변수명으로 사용할 수 없다.

 

***C언어에서의 비트 논리연산자(비트 단위로 쪼개서 연산)

0과 1의 상태를 표현하는 단위를 비트(bit)라고 하고,

어떤 값을 (0과 1로 구성된) 비트단위로 쪼갠 다음 연산할 때 사용하는 연산자를 비트 연산자라고 한다.

비트 단위의 연산을 한다는 것은 피연산자들을 모두 비트 단위, 즉 0과 1로 표현된 수로 변환한 후(2진수로 변환한 후),

비트 논리연산자(&: AND, |: OR, ^:XOR, ~: NOT)를 사용하여 연산하는 것을 말한다.

비트 논리연산자에서 &(엠퍼센드, AND) 연산자는 피연산자가 모두 1일 때만 1의 결과를 반환한다.

|(OR) 연산자는 피연산자중 둘 중 하나라도 1이면 1이다. ^(XOR) 연산은 서로 다른 값이면 1이 된다.

AND, OR, XOR 연산자는 이항 연산자, 항이 두 개 있어야 연산 수행이 가능하고,

~(NOT) 연산자는 단항 연산자다. 항이 한 개만 있어도 연산 수행이 가능하다.

~5 → 5를 비트단위, 8개로 표현하면 00000101, 여기에 ~(NOT) 연산자를 수행하면 1은 0으로, 0은 1로 뒤집어진다

그 결과 ~5를 비트단위, 8개로 표현하면 11111010이 되고, 이를 다시 10진수로 나타내면 -6이 되는데,

여기서 컴퓨터가 음수를 어떻게 표현하는지를 알아야 되는데, 2의 보수법을 먼저 이해해야 한다.

 

컴퓨터가 음수를 표현하는 방법

보수는 보충하는 수, 1의 보수는 어떤 수를 1로 만드는 것, 예를 들어 n의 1의 보수라면 n에 어떤 수를 더해야 1이 되는가?를 생각하면 구할 수 있다. 2의 6의 보수는 2에 어떤 수를 더해야 6이 될 것인가? 4다. 2의 6의 보수는 4가 된다. 비트단위로 쪼개진, 양의 수를

음수로 표현하려면 해당 음수 값의 1의 보수를 구하고, 1의 보수에 1을 더하면 2의 보수가 된다. 어떤 숫자에 2의 보수를 더하면 자동으로 2진수 뺄셈이 된다. 

 

***모든 수(n)의 0승은 1이다.

 

비트 단위로 쪼개서 연산하는 비트 논리연산자와 논리연산자는 다르다.

비트 논리연산자의 종류에는 &, |, ^, ~, <<, >> 가 있고, 논리연산자의 종류에는 &&, ||, ! 가 있다.

 

? 는 조건연산자, 같지 않다의 연산자는 !=, 나머지를 구하는 연산자는 %, 

 

// C언어
int a = 16, b = 64;

// a에 저장된 값을 비트 단위로 변환한 후, 오른쪽으로 2비트 이동한 후
// 변수 a에 대입하기
a = a >> 2;

// b에 저장된 값을 비트 단위로 변환한 후,
// 왼쪽으로 2비트 이동한 후 변수 b에 대입한다.
b = b << 2;

 

C언어에서 강제적으로 데이터형 변환을 하는 연산자를 cast연산자라고 한다.

C언어에서 sizeof() 는 데이터타입이 메모리를 얼마나 차지하는가? 데이터타입의 크기를 구하는 함수다.

논리연산자 || (OR기호) 와 && (AND기호) 가 같이 쓰일 경우 → x||y&&z;

&&의 피연산자들을 먼저 연산해야 한다. 연산자의 우선순위는 ! → && → || 순이다. 

 

C언어에서 서식 문자와 기능

- %o: 8진수 정수, o는 octal의 약어

- %c: 문자, %s: 문자열

- %x: 16진수 정수

- %d: 10진수 정수

 

C언어에서의 제어문자와 그 기능

- /n: 커서를 다음 줄로 바꾼다, 줄바꿈. /r: 커서를 그 줄의 맨 앞으로 이동시킨다.

/n/r → 줄바꿈한 뒤 커서가 있는 해당 줄에서 맨 앞으로 이동시킨다.

/t: 커서를 그 줄의 tab만큼 이동시킨다.

- /b: 커서를 그 줄의 1문자만큼 앞으로 이동시킨다. b는 backspace의 약어.

- /f: form feed, 한 페이지를 넘긴다.

 

참고

강의: 프로그래밍 언어 활용_권우석