[조건문]
if / else
int main()
{
if (조건식1)
{
// 조건식1의 결과가 참일 때 실행되는 명령문;
else if (조건식2)
// 조건식2의 결과가 참일 때 실행되는 명령문;
else
// 조건식1,2의 결과가 거짓일 때 실행되는 명령문;
}
return 0;
}
<예시>
int main()
{
int num = 0;
printf("숫자를 입력하세요.\n");
scanf("%d", &num);
if (num < 5)
{
printf("입력하신 숫자는 5보다 작습니다. \n");
}
else if (num == 5)
{
printf("입력하신 숫자는 5입니다.\n");
}
else
{
printf("입력하신 숫자는 5보다 큽니다\n");
}
}
switch
// switch 문 //
int main()
{
switch (정수식) // 값이 정수가 되어야 한다.
{
case 정수값1: // 콜론
문장1; // 실행될 문장
break;
case 정수값2; // 콜론
문장2; // 실행될 문장
break;
default: // default 생략 가능
break; // break를 만나면, switch문 전체를 빠져나간다.
}
return 0;
}
default는 생략 가능
단, case에서 확인하지 못한 결과 값이 들어오면
아무것도 발생하지 않기 때문에 적어 주는 것이 좋다.
<예시>
int main()
{
int num; // 변수만 선언!, 현재 변수가 가지는 값은 쓰레기값
printf("미세먼지 농도 선택 \n");
printf("1 : 좋음\n");
printf("2 : 보통\n");
printf("3 : 나쁨\n");
printf("4 : 매우 나쁨\n");
scanf("%d", &num);
// switch문 시작
switch (num)
{
case 1:
printf("미세먼지 좋음\n");
break;
case 2:
printf("미세먼지 보통\n");
break;
case 3:
printf("미세먼지 나쁨\n");
break;
case 4:
printf("미세먼지 매우 나쁨\n");
break;
default: // 예외 처리
printf("잘못 누르셨습니다. 다시 입력해주세요.");
break; /// 지금은 예외처리 누르면, 프로그램이 종료되어 버린다. ---> 반복문 사용해보자.
}
return 0;
}
<switch문의 정수식에 문자 대입>
사칙연산자(+, -, *, /)도 문자로 취급됨.
int main() {
int a, b;
char c;
int res = 0;
printf("수식 입력 : \n");
scanf("%d%c%d", &a, &c, &b);
switch (c) {
case '+':
res = a + b;
break;
case '-':
res = a - b;
break;
case '*':
res = a * b;
break;
case '/':
res = a / b;
break;
}
printf("result : %d %c %d = %d", a, c, b, res);
return 0;
}
[반복문]
while
// while 문 //
int main()
{
while (조건식) // 조건식이 참이면, 무한 루프에 빠진다.
{
// 반복문
// 변화식
}
return 0;
}
<예시>
int main()
{
int weight = 80;
int count = 0;
while (weight > 50) // 무한 루프에 걸리면, 컴퓨터 꺼질 때까지 돈다. 잘 설계해라.
{
printf("매일 빡시게 운동해서 1kg을 뺀다. \n");
weight--;
count++;
}
printf("축하합니다, 운동 안하셔도 됩니다.\n");
printf("%d 일 운동하셨습니다. \n", count);
return 0;
}
<무한반복>
while(1){
실행문
}
do-while 문
int main()
{
int weight = 80;
int count = 0;
int select;
do
{
printf("빡시게 운동해서 1kg 뺸다.\n"); // 반복코드
weight--;
count++; // 변화식
printf("운동을 더 하시겠습니까? \n");
printf(" 1. yes\n");
printf(" 2. no\n");
printf(" 숫자를 입력하시오. \n");
scanf("%d", &select);
if (select == 2) break; // 여기까지는 일단 한 번 실행함.
// 그 이후는 while 조건이 참이 될 때까지 무한반복
} while (weight > 50);
printf("축하합니다. 운동 종료 \n");
printf("%d 일 운동하셨습니다.\n", count);
return 0;
}
do-while문
: 일단 무조건 반복문과 변화식1회 실행한다.
while문
: 조건식부터 검사하고 실행한다.
for 문
int main()
{
for ( 초기식 ; 조건문 ; 할당문)
{
// 반복문 실행(위 조건문 참일 때,)
} // 반복문 먼저 실행하고, 할당문 실행(순서 잘 봐라)
return 0;
}
<for문 sequence>
i) 초기식 실행
ii) 조건문이 참이면, 반복문 실행
iii) 할당문 실행
iv) 조건문 확인
v) ii~iv 반복
int main()
{
int weight = 80;
int count = 0;
for (weight = 80; weight > 50; weight--)
{
printf(" 빡시게 운동해서 1kg 뺀다. \n");
count++;
}
printf(" 축하합니다. 운동 종료! \n");
printf(" %d 일 운동하셨습니다. \n", count);
return 0;
}
<조건식 변형>
int main()
{
int sum;
for ( unsigned i = 0; i < 100 && sum < 2000 ; i++ )
// 조건식이 참인지 거짓인지 판별만 가능하다면, 어떤 조건식이든지 사용 가능
{
sum += i;
}
return 0;
}
<무한 루프>
int main()
{
for ( ; ; )
{
// 반복문
}
return 0;
}
<Break>
break는 자신이 속한 반복문 하나만 빠져나올 수 있다.
int main(){
for(int i=0 ; i<50 ; i++) {
sum += i;
if(sum>40) break;
}
return 0;
}
<Continue>
continue는 반복문의 일부를 건너 뛴다.
건너뛴 후에는 블록의 처음부터 다시 반복됨.(즉, 블록의 끝으로 건너 뜀)
int main() {
int sum;
for( int i = 0 ; i < 100 ; i++) {
if((i%3)==0) {
continue;
}
sum += i;
}
return 0;
}
<반복문의 중첩>
// 반복문의 중첩 //
int main()
{
int i = 0;
int j = 0;
for (i = 0 ; i < 5 ; i++)
{
printf(" 외부시작 %d \n", i);
for (j = 0; j < 3 ; j++)
{
printf(" 내부 수행 %d \n", j);
// 지역변수(j)들은 자신이 속한 함수블럭을 벗어나면, 메모리를 반환하고 초기화된다.
}
printf(" 외부 끝 %d \n\n", i);
}
return 0;
}
int main()
{
int i, j;
for ( i = 0; i < 5; i++)
{
for ( j = 0; j <= i ; j++)
{
printf(" *");
}
printf("\n");
}
for (i = 4; i > 0; i--)
{
for (j = 0; j < i; j++)
{
printf(" *");
}
printf("\n");
}
return 0;
} // AVR 사용 시, LED 왔다갔다하는 구문 만들 때 활용할 예정
<할당문 변형>
int main()
{
int i, j;
for (i = 0; i < 5; printf("%d",i++)){}
return 0;
}
<팩토리얼 함수>
// 팩토리얼 함수 //
int main()
{
long fac = 1;
int i, n;
printf("정수를 입력하세요. : ");
scanf("%d", &n);
for (i = 1 ; i <= n ; i++)
{
fac = fac * i;
}
printf("%d ! 는 %d 입니다.\n", n, fac);
return 0;
}
[함수]
함수의 형태
함수를 정의하는 이유
- 모듈화에 의한 프로그램의 질 향상이 가능
- 유지 보수 및 확장의 용이성
- 문제 해결의 용이성 : "Divide and Conquer"
함수의 매개변수
매개 변수(parameter)
▶ 함수를 호출한 곳에서 함수 안으로 전달되는 값을 보관하기 위한 변수
인자, 인수(argument)
▶ 함수를 호출할 때, 실제로 전달되는 값
사용자 정의 함수
// 사용자 정의 함수 //
int sum(x, y) // 매개변수 : x, y(매개변수 없이도 가능)
{
// 함수 몸체
return 0;
}
① void sum() : 반환할 게 없음
int sum() : 반환할 값의 자료형이 int
② 반드시 main함수보다 위에 있어야 한다.
visual studio는 아래 있어도 가능한데, atmege studio 등 다른 곳에서는 안 됨.
근데, 그렇게 하면 main함수가 맨 아래로 가므로 함수의 원형만 윗쪽에 선언해준다.
print_hello(); // 함수 원형 선언
int main()
{
printf("함수를 호출합니다.\n : ");
print_hello();
printf("함수를 또 호출합니다.\n : ");
print_hello();
return 0;
}
int print_hello()
{
printf("Hello world. \n");
return 0;
}
int add();
int main()
{
int a, b, sum;
a = 3;
b = 5;
sum = add(a, b);
printf(" a와 b의 합은 : %d \n", sum);
printf(" a와 10의 합은 : %d \n", add(a, 10)); // printf문 내에서도 사용 가능
return 0;
}
int add(int x, int y)
{
//int ret;
//ret = x + y;
//return ret; // 식을 간소화하면, 아래와 같다.
return x+y;
}
<함수 사용 시, 주의사항>
- 함수의 작성은 함수의 리턴값, 함수의 인자, 내용이 필요!!
- 함수의 인자는 반드시 갯수와 자료형에 맞게 넣어서 호출!!
- 함수의 이름은 중복되면 골치 아파진다.(중복 금지!)
- 함수명은 변수의 이름 생성 규칙과 동일
변수의 유효 범위
지역 변수(local variable)
의미
: 블록{} 내에서 선언된 변수
특징
① 블록 내에서만 유효하며, 블록이 종료되면 메모리를 반환하고 초기화됨.
② 지역 변수는 stack 영역에 저장됨
③ 초기화하지 않으면, 쓰레기 값으로 초기화된다.
④ 함수의 매개변수도 지역 변수로 취급됨
void local(void); // 함수 원형 선언
int main()
{
int i = 5;
int var = 10;
printf(" main()함수 내의 지역 변수 var의 값은 : %d \n", var);
if (i < 10)
{
local();
int var = 30;
printf(" if문 내의 지역변수 var의 값은 : %d\n", var);
}
printf(" 현재 지역변수 var의 값은 : %d\n", var);
/// local()의 지역변수는 초기화되었으므로 var = 10이 출력
return 0;
}
void local()
{
int var = 20;
printf(" local()함수 내의 지역변수 var의 값 : %d\n", var);
return 0;
}
전역변수(global variable)
의미
: 함수 외부에서 선언된 변수
특징
① 전역변수는 프로그램의 어디서나 접근이 가능
② 프로그램이 종료되어야 메모리에서 삭제
③ 전역변수는 data 영역에 저장됨
④ 직접 초기화하지 않아도 0으로 초기화됨!!!
⑤ 지역변수로 같은 변수를 선언하면, 더이상 전역변수에 접근 불가
같은 이름의 지역 변수에 가려진다는 의미 → 굳이 같은 문자 쓰지 마라, 중복 금지!
tip) 전역 변수명을 길고 확실한 이름으로 쓰면 됨.
void local(void); // 함수 원형 선언
int var; // 전역 변수 선언
int main()
{
printf(" 전역변수 var의 초기값 %d\n", var); // 자동으로 0으로 초기화됨
int i = 5;
int var = 10; // 지역변수 var
printf(" main()함수내의 지역변수 var의 값은 : %d\n", var);
if (i < 10)
{
local();
printf(" if문 내의 지역변수 var의 값은 : %d\n", var);
}
printf(" 더 이상 main()함수에서는 전역변수 var에 접근 불가 : %d\n", var);
return 0;
}
void local()
{
int var = 20;
printf(" local()함수 내의 지역변수 var의 값 : %d\n", var);
return 0;
}
정적변수(static varible)
의미
: C언어에서 정적변수란, static으로 선언된 변수
특징
① 지역변수와 전역변수의 특징을 모두 가진다
② 함수 내에서 선언된 정적 변수는 전역변수처럼 단 한 번만 초기화되며
③ 프로그램 종료 시, 메모리에서 삭제
④ 정적변수는 지역변수처럼 해당 함수 내에서만 접근 가능
⑤ 함수 내부에서 선언하는 정적변수는 결국 프로그램을 헷갈리게 만든다.
→ 전역 변수로 선언하는 것을 권고함.
void local(void);
void staticVar();
int main()
{
int i;
for ( i = 0; i < 3; i++)
{
local();
staticVar();
}
return 0;
}
void local(void)
{
int count = 1;
printf("local()함수가 %d번째 호출됨\n", count); // 블록 탈출 후, 메모리 반환
count++;
}
void staticVar()
{
static int static_count = 1;
printf("staticVar()함수가 %d번째 호출됨\n\n", static_count); // 블록 탈출해도 계속 결과가 누적
static_count++;
}
변수 종류 | 키워드 | 선언 위치 | 유효 범위 | 메모리 소멸 시기 |
초기값 | 저장 장소 |
지역 변수 | auto | 함수/블록의 내부 |
함수/블록의 내부 |
함수 종료 시 | 초기화 안 됨 | stack 영역 |
전역 변수 | extern | 함수의 외부 | 프로그램 전체 | 프로그램 종료 시 |
0으로 초기화 | data 영역 |
정적 변수 | static | 함수/블록의 내부 |
함수/블록의 내부 |
프로그램 종료 시 |
0으로 초기화 | data 영역 |
레지스터 변수 | register | 함수/블록의 내부 |
함수/블록의 내부 |
함수 종료 시 | 초기화 안 됨 | CPU의 레지스터 (register) |
포인터의 주소값을 레지스터 변수에 저장함
재귀함수
재귀 함수의 기본적 이해
: 자기 자신을 다시 호출하는 형태의 함수
재귀호출 잘못 하면,
무한 재귀 호출 되므로 자원을 상당히 낭비할 수 있다
stack overflow를 야기할 수 있다는 의미.
가급적 쓰지 않는 것이 좋다.
void Recursive()
{
printf("recursive call!\n" )
Recursive();
}
int main()
{
Recursive();
return 0;
} // 무한 재귀 호출의 굴레에 빠진다.
'# Semiconductor > - Semicon Academy' 카테고리의 다른 글
[Harman 세미콘 아카데미] 14일차 - 강의 일정 Summary(ARM Architecture 이해 및 RTOS 활용), C언어 review (0) | 2023.07.06 |
---|---|
[Harman 세미콘 아카데미] 13일차 - C언어 문법(포인터, 배열, 구조체) (0) | 2023.07.06 |
[Harman 세미콘 아카데미] 12일차 - Review, 디지털 시계 만들기(교육 과정 외) (0) | 2023.07.04 |
[Harman 세미콘 아카데미] 11일차 - 반도체 개요, C언어 개요 및 문법 (0) | 2023.07.03 |
[Harman 세미콘 아카데미] 10일차 - Register, Memory (0) | 2023.06.30 |