버그는 코드에 들어있는 오류이다. 버그로 인해 프로그램의 실행에 실패하거나 프로그래머가 원하는 대로 동작하지 않게 된다. 디버깅은 코드에 있는 버그를 식별하고 고치는 과정이다. 프로그래머는 디버거 라고 불리는 프로그램을 사용하여 디버깅을 하게 된다.
디버거는 프로그램을 특정 행에서 멈출 수 있게 해주기 때문에 버그를 찾는데 도움이 된다. 프로그래머는 멈춰진 그 지점에서 무슨 일이 일어나는지 볼 수 있다. 프로그램이 멈추는 특정 지점을 중지점이라고 한다.
GDB는 자주 쓰이는 디버거 중 하나이다.
0.1은 2진수로 정확히 표현할 수 없다. 1/3을 10진수로 정확히 표현할 수 없듯이
C에는 int형,float형,char형을 포함한 여러개의 자료형이 있습니다. 가끔 변수를 한 자료형에서 다른 자료형으로 변환시켜줘야 할 때가 있는데, C는 형변환(Typecasting)을 통해 이것을 해결합니다. 형변활때 정밀도(표현 범위)가 더 높은 자료형으로 바꿀 경우 값에 오차가 발생할 수 있다는 점의 유의해야 한다.
#include <stdio.h>
int main()
{
int x = 65;
printf("%d\n", x); //65출력 // 암묵적 형변환
printf("%c\n", (char)x); //A 출력 //명시적 형변환
}
#include <stdio.h>
int main()
{
int a = 28;
float b = a / 5;
float c = (float)a / 5;
float d = 28.523;
int e = d;
}
형 변환은 부동 소수점 수와 정수의 변환에 아주 유용하게 쓰인다. 6행에서 28에 5를 나눈 값인 5.6을 ㅠ에 저장되어야 하는데, 실제로는 b의 값이 5.0이 된다. 이것은 컴파일러가 정수 두개를 나누었기 때문에 그 결과도 정수로 나온 것이다, 이 문제를 해결하기 위해 7행과 같이 a를 float 형으로 명시적 형변환하면 그 결과 값으로 c는 5.6이 된다.
암묵적 형변환도 int형과 float 형 변수들을 다룰 때 유용하게 쓰인다. 정수는 소수점 뒤에 숫자들에 대한 정보를 저장할 수 없기 때문에 float 형인 값을 int형으로 변환하면 부동 소수점 수의 소수점 뒤를 버린 값을 쉽게 저장할 수 있다. 10 행을 보면 int형인 변수에 부동 소수점 값을 넣으려고 했을 때, d는 묵시적으로 int형으로 형변환 되며, 이 과정에서 소수점 뒤에 값을 버리게 된다, 결과적으로 e의 값은 28이다.
함수는 특정 목적을 위해 만들어진 재사용가능한 코드이다. 함수는 입력값과 출력값을 가지며 프로그램 내의 어디에서든 재사용될 수 있다. 프로그램을 여러 개의 함수로 만들면 코드를 조직화하고 간단하게 만들 수 있다. 이것이 추상화의 한 예이다. 함수를 한번 작성하면 그 함수가 구체적으로 어떻게 만들어졌는지 몰라도 함수를 사용할 수 있다. 그리고 함수를 만들지 않은 사람도 저수준의 상세 내용을 신경쓰지 않고 함수를 사용할 수 있다.
#include
void sayHi(void)
{
printf("Hi!\n");
}
int main(void)
{
sayHi();
sayHi();
}
(3행) 함수의 첫 행은 세 부분으로 나누어져 있다. 첫째는 반환 자료형인데, 함수를 호출한 쪽에 출력값으로 반환해줄 값의 자료형이다. 반환할 값이 없을 경우 반환할 값이 비어있다는 의미로 void를 쓴다. 둘 째는 함수의 이름이다. 공백이 있으면 안되고, C에서 이미 사용하는 키워드는 쓸 수 없다. 셋 째는, 괄호 안에 인자라고도 알려진 함수의 매개변수(parameter)를 넣어준다. 이것은 함수의 입력값이며 입력값이 없으면 void를 쓴다.
sayHi 함수는 함수를 호출할 시에 괄호 안에 인자(argument)를 작성하지 않는다.
함수 안에서 변수를 정의하거나 함수의 매개변수로 전달된 것들은 그 함수 안에서만 유효하다. 이러한 변수들을 지역변수라고 한다. 지역변수는 그 함수 안에서만 사용될 수 있고, 다른 곳에서는 존재하지 않는다.
C에서는 배열이라는 자료구조를 제공한다. 배열은 같은 자료형으로 된 여러 개의 변수를 연속적으로 저장한다. 예를 들어 정수 배열은 여러개의 정수 값을 연속적으로 저장하고 문자배열(문자열)은 문자 값을 연속적으로 저장한다.
C에서 문자열은 char 값들의 배열을 나타낸다. C에서 문자열의 마지막 인덱스는 널로 끝나며, ‘\0’으로 나타낸다. 널 종단(null-terminator)은 문자열에게 문자열이 끝났고 더 이상의 문자가 남아있지 않다고 말하는 문자이다.
라이브러리는 프로그래머들이 이미 만들어진 코드를 다시 개발하지 않아도 되게 하고, 서로 함께 작업할 수 있도록 만들어주는 함수의 모음이다 .
라이브러리를 불러오기 위해서는 #include 를 사용해 해당 라이브러리의 헤더 파일을 포함해주면 된다. 라이브러리를 불러오면 라이브러리 함수들을 사용할 수 있다.
프로그래밍을 할때 일반적인 자료형들을 사용하기에 적합하지 않을 수 있다. 이런 상황에서 우리는 데이터를 캡슐화하여 어떤 개체에 연관되는 정보들을 한 덩어리로 묶을 수 있다. 예를 들어 이름(string형), 나이(int형), 평점(float형)와 같은 정보들을 갖고 있는데, 이 정보들은 단독으로는 큰 의미를 갖고 있지 않다. 이 정보들이 모여 학생이라는 개체를 이룰 때 의미를 갖게 되고 C에서는 구조체(structure)라는 방법을 사용한다.
데이터를 묶어 효율적으로 활용하기 위하여 배열을 사용하였다. 배열의 장점은 각 학생의 인덱스를 알때, 모든 학생들에게 임의 접근할 수 있으며, 각 배열 원소를 순환하면서 확인할 수 있다는 것이다. 하지만 배열은 같은 데이터형의 변수들을 하나로 묶을 수 있지만, 서로 다른 데이터형의 변수를 묶어서 사용할 수없다. 그리고 사용전에 배열의 크기를 선언해야만 한다.
typedef struct
{
string name;
int year;
float gpa;
}
student;
데이터를 묶어주는 또 다른 방법은 구조체이다. 구조체를 사용함으로써 서로 다른 자료형의 변수를 하나로 묶어 새로운 자료형을 만들 수 있다. 그리고 구조체를 구성하는 정보들을 멤버라고 한다.
함수가 본인 스스로를 호출해서 사용하는 것
재귀 함수에서 동일한 함수를 계속해서 호출할때마다 함수를 위한 메모리가 계속해서 할당된다, 함수가 호출될때마다 사용되는 메모리를 스택이라고 한다. 컴퓨터가 일을 처리하는데 관리를 하는 역할인 운영체제는 함수를 실행할 수 있도록 일정량의 바이트를 주고, 그 공간에 함수의 변수나 다른 것들을 저장할수 있도록 한다. 그래서 재귀함수를 이용하다 보면 함수가 종료되지 않고 함수가 계속해서 호출되는 경우가 발생하기도 한다, 이 경우 스택 공간은 초과되고 프로그램 충돌이 발생한다. 그렇기 때문에 재귀를 사용할 때는 스택 메모리가 사용되지 않도록 주의해야 한다. 메모리 사용 문제 때문에 재귀는 매우 유의해야 하지만, 특정 자료구조를 다룰때 매우 유용하게 사용된다.