Jasontreks Blog

DM 보내기


Send

연산자와 함수

I. 대입 연산자

변수에 값을 입력하는 연산자이다. '='를 기준 왼쪽의 값을 오른쪽의 값으로 대체한다.

int a = 10;
int b;
a = 12;
b = a;

자료형이 다르더라도 정수형과 실수형은 오류를 일으키지 않는다.

float f = 13.928;
char c;
bool b;
int i;

i = f; // 소수점이 잘리고 값은 13
c = f; // 소수점이 잘리고 값은 13(아스키코드)
b = f; // 0이 아니므로 값 true

f = i; // 13.0000

사용자 정의 자료형은 자료형이 다르면 컴파일 오류를 일으킨다.

MyType1 mt1;
MyType2 mt2;

mt1 = 1;   // 오류
mt2 = mt1; // 오류

또한 배열이나 포인터 변수를 일반 변수에 대입하는 경우 오류를 일으킨다.

char str = "Hello World"; // 오류: 일반 변수에 배열 대입

int* ptr = NULL;
int var = 350;

ptr = var; // 오류: 포인터 변수에 일반 변수 대입
*ptr = &var; // 오류: 실제 값에 주소값 대입

컴파일 오류를 일으키지 않지만, 잘못된 값이 입력되어 프로그램이 의도치 않게 동작할 수 있다. 이것을 논리 오류라고 한다.

char c = 1203;           // 범위를 초과하여 입력: 비트가 잘리고 다른 수로 바뀜
unsigned int ui = -250;  // 부호없는 정수에 음수값 입력: 2의 보수(양수) 그대로 입력

II. 산술 연산자

기본적인 산술 연산자

정수나 실수를 계산하는 연산자이다.

int a = 5;
int b;
b = a - 3; // 덧셈
b = a + 3; // 뺄셈
b = a * 3; // 곱셈
b = a / 3; // 나눗셈(몫)
b = a % 3; // 나눗셈(나머지)

수학 연산은 정수와 실수를 혼용할 수 있다. 다만 나머지를 구하는 연산은 정수끼리만 가능하다.

int a = 5;
float b = 0.452;
float c;

c = a + b; // 5.452
c = a - b; // 4.548
c = a * b; // 2.226
c = a / b; // 11.06
c = a % b; // 오류

대입 연산자와 결합

대입 연산자와 결합해 식을 줄일 수 있다. 연산의 대상이 대입하려는 변수일 때 유용하다.

int a = 5;
int b = 3;

a += b; // a = a + b | a = 8
a -= b; // a = a - b | a = 5
a *= b; // a = a * b | a = 15
a /= b; // a = a / b | a = 5
a %= b; // a = a % b | a = 2

이 경우 대입이 발생하기 전의 a값이 먼저 계산에 사용되고, 그 결과를 에 덮어쓰게 된다. 이는 누적 계산에서 유용하다.

증감 연산자

정수 1을 한번씩 더하거나 빼는 연산자이다. -= 1 을 축약했다고 볼 수 있다. 이 연선자는 변수 뒤에 올수도, 변수 앞에 올수도 있는데, 이것은 선행과 후행의 차이다.

int a = 5;
// 선행
++a; // a += 1
--a; // a += 1
// 후행
a++; // a += 1
a--; // a -= 1

선행은 해당 코드줄이 실행되기 전 ++a가 먼저 수행된다. 후행은 ++a가 해당 코드줄에서 가장 마지막에 수행된다.

int main(void)
{
	int a = 0;
	int b;
	b = ++a; // a += 1 이후 b에 대입   -> a값 1, b값 1
	b = a++; // a를 b에 대입 후 a += 1 -> a값 2, b값 1
}

III.비교 연산자

두 값을 비교해 참 또는 거짓을 반환하는 연산자이다.

int a = 5;
int b = 3;
int c = 3;
bool d;

d = a > c;  // a는 c보다 크다: true
d = a < c;  // a는 c보다 작다: false
d = a == c; // a와 c는 같다: false
d = a != c; // a와 c는 다르다: true
d = a >= c; // a는 c보다 크거나 같다: true
d = b <= c; // b는 c보다 작거나 같다: true

IV. 논리 연산자

AND, OR 은 두개의 참과 거짓을 함께 판별하는 연산자이다.

int a = 5;
int b = 3;
int c = 3;
bool d;

// AND: 두 값 모두 참이면 참
d = a < b && b == c; // a < b는 false, b == c는 true -> false
d = a > b && b == c; // a > b는 true,  b == c는 true -> true

// OR: 두 값중 하나라도 참이면 참
d = a < b || b == c; // a < b는 false, b == c는 true  -> true
d = a > b || b == c; // a > b는 true,  b == c는 true  -> true
d = a < b || b != c; // a > b는 false, b != c는 false -> false

NOT은 반전으로, 참이면 거짓, 거짓이면 참을 반환한다.

int a = 5;
int b = 3;
bool d;

// NOT: true -> false, false -> true
d = !(a < b); // true
d = !(a > b); // false

V. 함수

함수는 특정한 기능이 정의된 코드 블록이다. C와 C++같은 컴파일 언어에서는 함수를 기반으로 프로그램이 작동하기 때문에, 생물을 이루는 세포와도 같다고 할 수 있다. C, C++은 main함수로 시작해, main함수 안에서 또 다른 함수를 호출하고 탈출하기를 반복한다. 함수는 선언으로 시작하여 용도에 맞게 정의, 적재적소에 호출하는 것으로 프로그램을 조금씩 완성시켜가는 근본적인 요소이다.

함수 구성요소

함수는 식별자(Identifier), 매개변수(parameter), 반환값(return)으로 구성된다.

//  반환 타입     매개변수 타입
		int main(void)
		{
			// 반환 제어문: 함수 종료와 함께 0을 넘겨줌 
			return 0;
		}

함수의 가장 기본적인 역할은 호출 시 매개변수를 전달받고, 전달받은 값들로 계산을 수행한 뒤 탈출 시 호출자에 이 값을 넘겨주는 것이다. 하지만 꼭 반환값을 넘겨주거나, 매개변수를 전달받지 않아도 된다.

void fun1(int a)
{
	// 반환이 없는 함수. return 제어문이 없어도 오류X
}
int fun2(void)
{
	// 매개변수가 없는 함수.()에 보통 void 명시하지만 안해도 상관 X
	return 0;
}
void fun2(void)
{
	// 매개, 반환 모두 없는 함수.
}

함수 선언 및 정의

세 구성요소에 유의하며, 용도에 맞는 함수를 작성한다.

  • 식별자: 기능을 유추할 수 있도록 직관적이고 가독성이 좋아야 한다.
  • 매개변수: 꼭 필요한 변수만 전달받고, 기능 구현에 장애가 없도록 필요한걸 누락하지 않아야 한다.
  • 반환값: 적절한 자료 구조를 선택해 호출자가 필요한 값을 의도에 맞게 전달해야 한다.

어떤 문자의 아스키코드 값을 반환하는 함수를 작성한다면 다음과 같다.

int GetASCII(char c)
{
	int ascii = (int)c;
	return ascii;
}

형 변환 (int)c 형 변환은 어떤 변수의 값을 본래의 자료형이 아닌 다른 자료형으로 바꾸는 작업이다. 변수 c의 경우 문자를 표현하는 char 타입이지만, 기본적으로 아스키코드 값을 저장하는 1바이트 정수형이기에 아스키코드값 그대로 int 변수로 넘어오게 된 것이다. 형 병환은 두 자료형의 관계에 따라 정상적으로 변환이 될 수도 있지만, 의도치 않은 값으로 변환되어 논리 오류를 일으킬 수도 있으니 주의해야 한다.

함수 호출

함수는 다음과 같이 호출할 수 있다. 호출자 입장에서 매개변수로 넘겨주는 값을 '인수'라고 한다.

int main(void)
{
	char c = 'A';
	int i;
	i = GetASCII(c);   // 변수를 인수로 전달
	i = GetASCII('B'); // 상수를 인수로 전달

	return 0;
}

함수의 반환값은 그 자체로 지역에 존재하는 하나의 값이기 때문에, 다른 함수의 인수로 전달되거나 연산에 사용될 수 있다.

int Add(int x, int y)
{
	return x + y;
}

int main(void)
{
	int a, b = 3;
	int c;
	c = Add(a, Add(a, b));     // c = a + (a + b)
	c = Add(a, b) * Add(a, b); // c = (a + b) * (a + b)

	return 0;
}