*주의 - 개인적으로 학습하는 내용이라 틀릴 수 있으니 틀린 부분을 알려주시면 진심으로 감사드리겠습니다.
가. 함수 Function
함수는 수학에서의 정의와 동일하다. 특정 수를 넣으면 특정한 결과가 나오는 것을 함수라고 부르고, 이를 이용해 내가 필요한 기능을 각각 만들 수 있다. 컴퓨터에서도 마찬가지로 함수를 만들어 본문에 사용할 수 있다. 이럴 경우 본문이 지저분해지거나 길어지지 않게 관리할 수 있고, 기능만 조금씩 수정하면 되기 때문에 수정, 가독에 유리하다.
함수는 아주 직관적으로 우리가 알고 있다. 밥을 먹으면 똥으로 나오듯이 input이 있으면 output이 있다. 함수에서는 입력을 인수(argument)로 명명하고, 출력을 반환(return), 작업을 기능(operation)이라고 한다. 이 세 가지는 함수를 이용하려면 반드시 필요한 것인데, 변수와 마찬가지로 main 함수보다 앞서 선언되어야 compiler 가 인식할 수 있어 오류를 발생시키지 않는다.
함수의 선언은 return type + identifier + argument + operation 으로 이루어진다.
컴퓨터 언어로 예를 들면
int Func(int a) { return a; }
처럼 생겼다. return type 은 함수가 끝났을 때 돌려주는 data 의 type 을 뜻하고, identifier 는 함수의 이름을 뜻한다. argument 는 integer type 의 데이터를 입력으로 받겠다는 소리이고 그 입력의 이름을 a로 하겠다는 뜻이다. operation 은 {} 로 감싸서 구성한다. 안에는 내가 처리하고 싶은 기능, 예를 들어 a 에다가 3을 더해서 내보내고 싶다면 return a+3; 등으로 활용할 수 있으며, 반복문, 조건문 등도 안에서 수행이 가능하다. 주의할 점은 return 시에 내가 앞에 return type으로 정한 것과 동일한 자료가 나가야한다는 것이다. int 로 선언했지만 return 에 char형을 내보낸다면 예기치 못한 오류를 발생시킬 수 있다.
return 의 경우, 자료를 반환하고 함수를 종료시키는 역할을 하다보니, return 뒤의 명령들은 모두 무시되어버리니 작성에 주의하도록 하자.
함수의 경우 기능이 중요하게 작동하다 보니 당장은 저 정도만 알고 넘어가서 기능을 만들어보자.
나. 조건문
1. if-else
입력을 받았을 때 경우에 따라 처리하고 싶은 기준이 다를 수 있다. 예를 들어 내가 천 원을 갖고 슈퍼에 간다면 아이스크림을 사먹고, 500원을 갖고 슈퍼에 간다면 새콤달콤을 사먹는 것처럼 나의 조건에 따라 다른 결과를 낼 수 있다.
이렇듯 조건을 걸 수 있는 명령어가 if ~ else 문이다.
#include <stdio.h>
int main(){
int a;
scanf("%d", &a);
//a=1일 경우 a+=10 수행
if(a==1){
a+=10;
}
// a=2 일 경우 a+=5 수행
else if (a==2){
a+=5;
}
// a=1 혹은 a=2가 아닌 모든 경우에 a-=10 수행
else{
a-=10;
}
printf("%d",a);
기본 형식은 if(조건) { 기능 } else { 기능 } 이다. 이 때 조건은 0이 아니면 모두 참이며, 0일 때만 거짓이 된다. 조건이 참일 경우에만 기능이 작동하며, 만약 if 문의 조건이 거짓이라면 else 문이 실행된다. 중간에 if 말고도 조건을 추가하고 싶다면 조건문에 || (or) 나 || (and) 를 추가하여 if (a || b) (a나 b 중 하나만 0이 아니어도 실행) 처럼 사용할 수 있고, 아예 다른 기능을 수행하고 싶다면 else if(조건) {기능} 을 if 와 else 중간에 사용하여 조건문을 수행할 수 있다.
조건을 사용할 때 비교 연산자를 주로 사용한다.
상등비교 | a==b | 서로 같다(1) 다르다 (0) |
a!=b | 서로 같다(0) 서로 다르다(1) |
대소비교 | a>b ,a<b | 부등호가 맞다(1) 틀리다(0) |
a>=b a<=b |
서로 같거나 크다(작다) 부등호가 맞다(1) 틀리다(0) |
논리비교 | !a | a가 참이면(0) 거짓이면 (1) |
a&&b a||b |
a b 모두 참이다(1) a b 중 하나라도 참이다(1) |
비교 연산자를 여러개 사용할 경우 앞서 본 연산의 우선순위를 고려해서 작성해야한다. 자칫하면 우선순위가 꼬여 조건이 전혀 다르게 작동할 수 있다.
또한 && 이나 || 를 사용할 경우 수행속도를 높이기 위해 Short circuit 이 적용된다. 즉 A&&B 일 때, A가 거짓이면 굳이 B를 계산해보지 않아도 조건이 거짓임을 알 수 있으므로 B를 계산하지 않고 넘어간다. A||B도 마찬가지로 A가 1이면 B를 계산하지않고 조건문이 수행된다. 가장 가능성이 높은 식을 앞에 배치하여 수행속도를 높일 수 있고, 대입이나 숫자를 증가시키는 연산이 조건에 들어있을 경우, 예를 들어 if (a==3 || b+=1 ) 일 경우 a가 3이라면 뒤의 b+=1이 수행되지 않으므로 b가 증가하지 않는 것에 주의해야한다.
조건 연산자는 삼항 연산자에도 있다. 연산자는 ? : 이며 사용법은 (조건)? 참일 때 값 : 거짓일 떄 값;이다.
예를 들어 b= 3 일 때, c= (b>5)? 1:2; 로 식을 두면 b>5가 거짓이므로 c에는 2가 들어간다.
2. switch - case
if 문과 다르게 case를 손으로 나열하기 쉬울 때 사용하면 좋다.
#include <stdio.h>
int main(){
int a= 1;
switch(a){
case 0 : printf("a\n"); // a가 0일 때 a를 출력
case 1 : printf("b\n"); // a가 1일 때 b를 출력
case 2 : printf("c\n"); // a가 2일 때 c를 출력
default : printf("d\n");// case에 없는 경우에도 수행함
}
}
// b
// c
// d
// 이렇게 출력
switch(변수)로 도입하며 변수의 값을 case 상수 : 기능 으로 표현한다. 명령어가 하나 이상이 될 경우 {} 를 사용하여 블럭으로 표현할 수 있으며, 해당하는 case가 있더라도 수행 후 종료되지 않고 다음 case로 넘어간다. 즉 진입로라고 생각하면 된다. 0으로 들어간다면 뒤에 있는 곳도 전부 들렀다가 나가는 것이다. 그렇기 때문에 case 문 마다 break를 넣어 해당 case 의 기능을 수행하고 나면 switch 문을 멈출 수 있도록 많이 쓴다.
변수에는 정수형만이 들어갈 수 있고, 상수식이 들어갈 수 있다. 즉, a+1, a/2, a%2 등등의 식이 모두 들어갈 수 있다.
다. 반복문
1. for 문
일정횟수를 반복할 수 있게 해주는 문법이다. 기본 형식은 for (초기화식; 조건식; 후처리식) { 기능 } 으로 이루어져있다.
#include <stdio.h>
int main(){
int a=0,b=0;
for (int i=0; i<5; i++){
// i=0 부터 시작하여 i<5인 동안 기능을 수행하고, 한 번 수행시마다 i++를 실행한다.
a+=1;
}
for (int i=0; i<5; i+=2){
// i=0 부터 i<5 인 동안 기능을 수행하고, 수행시마다 i= i+2 를 실행한다.
b+=1;
}
printf("%d %d", a,b); // 5 3 출력
}
초기화식에 변수를 선언하여 for 문 안에서 변수로 활용할 수 있으며, 조건식이 참인
동안은 계속 수행된다. 또한 for문이 끝날때마다 후처리식이 실행되고, 후처리 후 조건식이 참이면 다시 수행하게 된다.
초기화식이나 조건식, 후처리식은 모두 생략이 가능하므로 for(;;){} 를 쓸 경우 무한루프를 돌게 된다.
중간에 반복문을 그만두고 싶다면 함수를 아예 종료시키는 return 문을 사용하던가, 수행중인 함수를 중지하고 빠져나오는 break 문을 사용하면 된다. 또한 continue 문을 사용하여 뒤의 문장을 실행하지 않고 후처리식으로 바로 넘어가는 방법도 존재한다.
2. while 문
while(조건) {} 로 이루어져있고, 조건이 참인 동안 계속 수행한다.
#include <stdio.h>
int main(){
int a=0;
int b=0;
while(a<10){
b++;a++;
}
printf("%d", b); //10 출력
}
주의할저은 조건식과 처리식이 같이 있지 않으므로, 루프 내에서 조건에 사용된 요소가 계속해서 업데이트 되어야 한다. 반대로 말하면 업데이트하지 않을 시에 무한 루프를 돌 수 있고, break 나 continue, return 문 모두 사용이 가능하다. 조건식은 위의 조건 연산자에서 사용된 것과 동일하며, 0만이 거짓이다.
비슷한 방식으로 do ~ while 문을 사용할 수 있다.
while 문과는 다르게 조건을 먼저 수행하지 않고 do 뒤의 기능을 먼저 수행한다.
#include <stdio.h>
int main(){
int n=0;
while(n<0){
printf("HI\n"); //조건문 때문에 출력되지 않음
}
do{
n-=1; //n= -1이 수행된다.
}
while(n<0){
printf("HI\n"); // n<0 이 참이므로 HI가 출력된다
n++; //n=0 이 되므로 조건문이 거짓이 되므로 while문이 종료된다.
}
}
for 문이나 while 문이 이중으로 겹쳐있는 경우 빠져나오기 번거롭다. 그럴 때 goto 문을 사용하여 쉽게 빠져나올 수 있다.
#include<stdio.h>
int main(){
int a=0;
for (;;){
for (;;){
a+=1;
if (a>=10) goto LABEL; // 무한 루프 속에서 a>=10 일 경우에 이름 LABEL 로 간다.
}
}
LABEL:
printf("HI %d", a); // HI 10 출력
}
하지만 goto는 순서를 뒤바꿔 버리고 논리를 따라가기 힘들게 만드므로 주로 사용하지 않도록 약속한다.
생략한 것이 어마무시하게 많긴 하지만, 앞으로 함수를 이용한 알고리즘을 풀어가면서 조금 더 넓고 깊이 알아봐야겠다.
'C언어' 카테고리의 다른 글
C언어의 기초 - 포인터 (0) | 2021.02.06 |
---|---|
C언어의 기초 - 구조체와 공용체 (0) | 2021.02.03 |
C언어의 기초 - 변수와 배열 (0) | 2021.02.03 |
C언어의 기초 - 변수와 상수 (0) | 2021.02.01 |
C언어를 위한 사전 지식 (0) | 2021.01.31 |