증감연산자
증감 연산자는 1씩 증가 혹은 1씩 감소시킨다.
1씩 증가 또는 1씩 감소 되는 경우가 굉장히 빈번하게 일어나기 때문에
a = a + 1; 보다는 ++a, a++ 가 더 간편하고 편리하다.
전위형(Prefix)
++a, --a
후위형(Postfix)
a++, a--
**a, //a. a**, a// 같은 연산자는 없다.
**는 앞으로 학습하게 될 이중포인터를 의미하며
// 은 한줄 주석처리하는 문장이다.
1씩 증가 시키는 문장은 4가지 형태가 존재한다.
1. a = a + 1;
2. a += 1;
3. a++;
4. ++a;
1씩 감소 시키는 문장은 4가지 형태가 존재한다.
1. a = a -1;
2. a -= 1;
3. a--;
4. --a;
<질문>위의 4가지 형태 중 어떤 것이 실행 속도가 가장 빠를까?
a++;
00411A35 cmp byte ptr [ebp-0D1h],0
00411A3C jne main+3Bh (411A4Bh)
00411A3E push 411ABDh
00411A43 call @ILT+550(__RTC_UninitUse) (41122Bh)
00411A48 add esp,4
00411A4B mov eax,dword ptr [a]
00411A4E add eax,1
00411A51 mov byte ptr [ebp-0D1h],1
00411A58 mov dword ptr [a],eax
a= a+ 1;
00411A5B cmp byte ptr [ebp-0D1h],0
00411A62 jne main+61h (411A71h)
00411A64 push 411ABDh
00411A69 call @ILT+550(__RTC_UninitUse) (41122Bh)
00411A6E add esp,4
00411A71 mov eax,dword ptr [a]
00411A74 add eax,1
00411A77 mov byte ptr [ebp-0D1h],1
00411A7E mov dword ptr [a],eax
a+=1;
00411A81 cmp byte ptr [ebp-0D1h],0
00411A88 jne main+87h (411A97h)
00411A8A push 411ABDh
00411A8F call @ILT+550(__RTC_UninitUse) (41122Bh)
00411A94 add esp,4
00411A97 mov eax,dword ptr [a]
00411A9A add eax,1
00411A9D mov byte ptr [ebp-0D1h],1
00411AA4 mov dword ptr [a],eax
<질문> 전위형과 후위형은 어떤 차이가 있을까?
#include <stdio.h>
void main()
{
int a = 0;
printf("a = %d\n", ++a); // 결과는 ? 1
printf("a = %d\n", a++); // 결과는 ? 1
printf("a = %d\n", ++a); // 결과는 ? 2+1 =3
printf("a = %d\n", a++); // 결과는 ? 3
printf("a = %d\n", ++a); // 결과는 ? 4 +1 = 5
}
<두 문장 비교>
printf("a = %d\n", ++a);
-> a 의 값을 1 증가 시킨 후 %d 에 대입한다.
printf("a = %d\n", a++);
-> a 의 값을 %d 에 대입 시킨 후 1 증가 시킨다.
++a 는 먼저 증가하고, 값을 대입시키며,
a++ 는 먼저 값을 대입시키고, 나중에 증가한다.
--a, a-- 동일한 패턴으로 진행된다.
<컴파일 된 어셈블리로 분석>
void main()
{
int a = 0;
int b = 0;
a = ++b;
a = b++;
a = b;
b = b + 1;
}
a = ++b;
00411A2C mov eax,dword ptr [b]
00411A2F add eax,1
00411A32 mov dword ptr [b],eax
00411A35 mov ecx,dword ptr [b]
00411A38 mov dword ptr [a],ecx
a = b++;
00411A3B mov eax,dword ptr [b]
00411A3E mov dword ptr [a],eax
00411A41 mov ecx,dword ptr [b]
00411A44 add ecx,1
00411A47 mov dword ptr [b],ecx
a = b;
00411A4A mov eax,dword ptr [b]
00411A4D mov dword ptr [a],eax
b = b + 1;
00411A50 mov eax,dword ptr [b]
00411A53 add eax,1
00411A56 mov dword ptr [b],eax
}
<유의사항>
특별한 상황이 아니라면 a++ 후치형 보다 ++a 부분을 쓰는 것이 훨씬 더 명확하다.
어셈블리 코드에서도 나와 있듯이
a = b++;
-------
a = b
b = b + 1;
두 코드는 글자 하나 틀리지 않고 똑같은 코드로 되어 있다.
따라서, a++ 는 초보자들에게는 위험 요소를 안고 있기 때문에 특별한 상황이 아니라면 ++a를 쓰는 것이 훨씬 더 좋다.
2씩이상 일때는 +, -, *, / 가 같은 형태로 적용 된다.
a += 2; // a = a + 2;
b -= 2; // b = b - 2;
c *= 2; // c = c * 2;
d /= 2; // d = d / 2;
<생각해 볼 점>
a++, a+=1 이러한 것이 있다는 것만 알고 있으면 충분하고 다른 사람 코드를 보았을때 이해만 가능하면 된다. a++, a+=1 은 a = a + 1 가 비교해서 어셈블리코드도 같을 뿐만 아니라 실행 속도도 같기 때문에 괜한 겉멋 들여서 a+=1 로 쓰지 않고 가장 가독성이 높은 a = a + 1 로 써주는 것도 현명한 방법이다. 단지 글자 몇자 더 적어 줄 뿐이다.
삼항연산자
if 문과 흡사한 형태이다.
<문법>
(조건식) ? 문장1:문장2
조건식이 참이면 문장1을 실행하고, 거짓이면 문장2를 실행한다.
예1)
#include <stdio.h>
void main()
{
int a, b;
scanf("%d%d", &a, &b);
printf("Max(%d, %d):%d\n", a, b, (a > b) ? a:b);
}
예2)
#include <stdio.h>
void main()
{
int a, b;
scanf("%d%d", &a, &b);
printf("Max(%d, %d):", a, b);
(a > b) ? printf("%d\n", a) : printf("%d\n", b);
}
예3)
#include <stdio.h>
void main()
{
char szLastNum[8];
printf("주민번호 끝자리(7글자)를 입력하세요\n");
scanf("%7s", szLastNum);
printf("당신은 %s입니다.\n", ((szLastNum[0]-'0') % 2 == 1) ? "남자":"여자");
}