반응형
재귀함수

자기자신을 재호출하는 형태로 정의된 함수를 재귀함수라 합니다.

 

  • 재귀함수는 무한루프에 빠질 수 있다.
  • 탈출조건을 설정해줘야 한다. 그러지 않으면 오버플로우에 빠진다.

 

재귀함수 대표적인 예시 : Factorial n!

 

int Factorial(int num)
{
	if(num == 1)
    	return 1;
    return num * Factorial(num - 1);
}

 

 

 

재귀함수의 특징

함수가 자기자신을 호출할때마다 메모리가 쓰입니다.

그리하면 연산이 많아져서 비용이 커지기에 성능이 좋지 않으며

프로그래머 입장에서는 직관적인 표현은 아닙니다.

 

C언어가 재귀적 함수호출을 지원한다는 것은 그만큼 표현할 수 있는 범위가 넓다는것을 의미

C언어의 재귀함수를 이용하면 재귀적으로 작성된 식을 그대로 코드로 옮길 수 있다.

 

 

하노이 타워

하노이의 탑(Tower of Hanoi)은 3개의 막대가 있고 첫번째 막대에 N개의 서로 다른 크기의 원반이 쌓여있습니다.

 

하노이 탑 규칙

  • 한 번에 움직일 수 있는 원반은 맨 위에 놓여 있는 원반 하나뿐이다.
  • 원반위에 더 큰 원반을 쌓을 수 없다.

하노이 탑은 재귀함수의 예시중 하나이며 아래의 코드로 실행됩니다!

void Hanoi(int num , char from, char by, char to)
{
	if (num == 1)
	{
		printf("%d번째 원반 %c => %c \n", num, from, to);
	}
	else
	{
		Hanoi(num - 1, from, to, by);
		printf("%d 번째 원반을 %c => %c \n", num, from, to);
		Hanoi(num - 1, by, from, to);
	}
}

 

반응형

 

반응형

'C' 카테고리의 다른 글

난수에 대하여!  (0) 2023.05.12
배열에 대하여!  (0) 2023.05.12
함수에 대하여!  (0) 2023.05.10
조건문에 대하여!  (1) 2023.05.10
반복문에 대하여!  (0) 2023.05.09
반응형
함수의 존재 이유

함수를 하나의 기능으로 취급이 가능합니다.

그 기능이 여러부분에서 필요하다면 함수가 없다면

매번 그 기능을 구현해야하는 불편함이 있습니다.

그러하기에 함수로 그 기능을 묶어서 사용하면

함수를 부르는 행위로 그 기능을 수행할 수 있게 됩니다!

 

함수는 한가지 기능으로만 만드는게 좋다

여러가지 기능을 하나의 함수에 다쑤셔넣으면 그 일부의 기능만

사용하고 싶을때 다시 함수를 쪼개야하기 때문에 기능 단위로

만드는 것이 프로그래밍을 할때 유리합니다!

 

 

 

함수의 구조

밑에 그림처럼 함수는 반환형태 / 함수이름 / 입력형태 / 함수의 몸체의

구조로 이루어져 있습니다.

 

함수명은 대문자로 시작해야 하며 함수명을 왠만하면 함수의 기능을 의미하는

동사의 형태로 짓는게 좋습니다.

 

함수는 입력과 출력도 반환해줍니다.

 

return문은 함수에서 값을 반환하는 것과 함수의 종료의 기능이 있다.

 

F12 : 정의되어 있는 함수 호출

 

 

 

 

함수의 구분
  • 유형 1: 전달인자 O / 반환 값 O
  • 유형 2: 전달인자 O / 반환 값 X
  • 유형 3: 전달인자 X / 반환 값 O
  • 유형 4: 전달인자 X / 반환 값 X

 

 

 

함수의 정의와 선언

main()함수 위에서 선언을 하지 않고 아래에서 선언을 하면

main()함수에서 그 함수를 실행하는 순간에 에러가 발생한다.

 

컴파일이 위에서 아래로 진행이 되기에 함수의 배치 순서는 중요하다. 컴파일 되지 않은

함수는 호출이 불가능하다. 이후에 등장하는 함수에 대한 정보를 컴파일러에게 제공해서

이후에 등장하는 함수의 구현부를 컴파일 가능하게 도울 수 있습니다.

 

main()함수 위에서 선언을 하고 그 밑에서 구현부를 작성하는게 좋은 예시이다.

main()함수 위에서 선언과 구현부를 같이 작성해도 정상적으로 작동한다.

 

헤더 파일 또한 선언부로, 해당 헤더에 있는 소스코드는 구현부로 라고 생각할 수 있습니다.

 

아래의 코드처럼 선언부에 인자 타입부분만 써도 됩니다.

void Func(int numX, int); // 선언부

int main()
{
	Func();
}

int Func(int num1, int num2)	// 구현부
{
	printf("Hello");
    return num1 + num2;
}

 

전역변수 지역변수 static변수

변수는 어디에 위치하는지 키워드가 붙는지에 따라서

전역인지 지역인지 static변수인지 알 수 있습니다.

 

전역변수 지역변수 static변수의 차이점

  • 메모리에 언제 올라가고 언제 내려가냐?
  • 어디에서 접근 가능하냐?

 

 

 

지역변수란?

지역변수는 함수 내에서 선언되는 것이 지역변수입니다.

 

 

 

지역변수 특징
  • 프로그래밍을 하면서 지역변수를 많이 사용하게 됩니다.
  • 지역변수는 함수 내에서만 사용과 접근이 가능합니다.
  • 한 지역 내에 동일한 이름의 변수를 중복 선언이 불가능합니다.
  • 하지만 다른 지역에 동일한 이름 변수는 선언 가능합니다.
  • 해당 지역을 빠져나가면 지역변수 소멸 / 메모리 해제

지역변수는 스택 메모리 영역에 할당되어서 해당 변수가 있는 

함수(코드블럭)가 종료될 때 메모리가 해제 됩니다.

스택 메모리는 해당 변수가 있는 함수(코드블럭)가 종료될 때 메모리가

해제가 됩니다. 그러한 이유로 외부에서는 이 변수를 이용할 수 없습니다.

 

지역변수는 호출될 때마다 새롭게 할당됩니다.

1. 지역변수는 외부에서 선언된 동일한 이름의 변수를 가린다.(선언은 되지만 헷갈리니 지양하자)

2. 지역변수와 전역변수의 이름이 같을때 지역에서 쓸때는 지역변수가 사용되며 그 지역을 벗어나면

전역변수를 사용한다.

 

예 ) 반복문 안에서 선언하는 변수들

예 ) main이 아닌 다른 함수에서 선언하는 변수들

매개변수도 지역변수다.

매개변수는 함수에 입력값을 의미한다.

 

들여쓰기로 판단하기 쉽다

 

 

전역변수

전역변수는 함수 외부에 선언된다.

프로그램의 시작과 동시에 메모리 공간에 할당되어 종료시 까지 존재

전역변수는 프로그램 전체 영역 어디서든 접근이 가능하다

별도의 값으로 초기화하지 않으면 0으로 초기화한다.

지역변수의 이름이 전역변수의 이름을 가린다.

 

전역변수는 많이 쓰면 좋지 않다.

전역변수는 프로그램 전체에서 접근이 가능하기에 전체 프로그램의 변경으로 이어질 수 있기에

전역변수에 의존적인 코드는 프로그램 전체 영역에서 찾아야 한다. 수정이 용이하지 않다.

전역변수의 복잡함

 

 

 

static 변수

static 붙은 애들은 프로그램 시작할때 메모리에 올라가고 끝날때 해제된다.

지역변수에 붙은 static은 선언된 함수 내에서만 접근이 가능한 지역변수의 특성과

딱 1회 초기화되고 프로그램 종료시 까지 메모리 공간에 존재하는 전역변수의 특성을

같이 가지고 있습니다.

 

전역변수, 지역변수, static변수 필요한 이유

전역변수가 필요한 이유

선언된 변수가 함수 밖에서도 계속 사용할 필요가 있을때

 

지역변수가 필요한 이유

  • 함수내에서만 활용할 변수가 필요할 때
  • 필요할 때만 메모리가 사용된다
  • 메모리의 빠른 순환

 

함수밖에서도 사용하기 위해 계속 메모리 공간에 존재하는 변수

  • 전역변수
  • static 지역변수

static지역변수를 쓰는 이유

  • 전역변수처럼 쓰고 싶지만 접근을 제한하고 싶을때 사용됩니다.
  • static 지역변수는 접근의 범위가 전역변수보다 훨씬 좁기 때문에 안정적이다.(전역변수의 단점을 최소화)
  • static 지역변수를 사용하여 전역변수의 선언을 최소화하자.

 

 

 

레지스터(register) 변수

레지스터는 힌트를 제공하는 키워드입니다.

컴파일러는 이를 무시하기도 한다.

 

레지스터는 CPU내부에 존재하기에 접근이 가장 빠른 메모리 장치입니다.

 

레지스터 변수를 사용하는 이유는 빈번히 사용하는 메모리를 가장

접근이 빠른 레지스터에 저장하므로 성능향상에 도움이 됩니다.

 

레지스터변수는 이런게 있다고 이해만 하고 넘어갑시다!

 

이미지 출처 : 윤성우의 열혈 C 프로그래밍

 

반응형

 

반응형

'C' 카테고리의 다른 글

배열에 대하여!  (0) 2023.05.12
재귀함수에 대하여!  (0) 2023.05.10
조건문에 대하여!  (1) 2023.05.10
반복문에 대하여!  (0) 2023.05.09
printf함수와 scanf함수 정리하기!  (0) 2023.05.09
반응형
조건문

조건문은 프로그래머가 상황에 따라서 프로그램의 흐름을 선택하고

싶은 순간에 사용할 수 있습니다.

 

 

 

if문 구조

if문은 조건식이 참일경우 실행문을 실행합니다.

if(조건식)
{
	실행문;
}

 

 

 

if문 활용

입력값에 따라서 입력값이 음수인지 양수인지 0인지를 출력해주는 코드입니다.

이런식으로 if문을 활용할 수 있습니다

 

if문은 프로그래밍의 꽃이라고 불릴 정도로 매우 매우 활용도가 높습니다!

 

밑의 예시 같은 경우에 문제점은 입력값이 음수일 경우 맨 위의 if문에서 무엇이 출력될지 결정되었지만,

밑의 if문도 검사를 해서 쓸데없는 연산이 발생합니다. 이러한 이유로 if~else if문이 필요하게 됩니다.

이는 밑에서 다시 설명해 드리겠습니다!

int input = 0;
scanf("%d", &input);

if(input < 0)
	printf("입력 값은 음수입니다.");
if(input > 0)
	printf("입력 값은 양수입니다.");
if(input == 0)
	printf("입력 값은 0입니다.");

 

 

 

if-else문

조건에 해당하면 if문 내부의 코드를 실행하고 아닌 경우 else문 내부의 코드를 실행합니다.

 

if~else 문은 하나의 문장으로 취급되기에 다른 문장이 삽입될 수 없습니다.

 

 

 

 

삼항 연산자

삼항 연산자는 피연산자가 세개입니다.

밑의 예시처럼 입력값을 넣고 입력값을 max와 비교하여 조건이 참일경우 : 앞에 코드를 실행하고

거짓일 경우 : 뒤에 코드를 실행합니다!

int input = 0, max = 10;

scanf("%d", &input);

input > max ? max = input : printf("입력값이 최대값보다 작습니다.");
printf("최대값은 %d입니다!", max);

 

 

 

반복문 탈출 break문

반복문 안에서 break문을 만날 경우 자신을 감싸는 반복문 하나를 빠져나오게 됩니다.

if문과 함께 사용이 되어서 조건이 참일경우 반복문을 탈출하는 용도로 사용됩니다!

 

 

 

반복문 생략 continue문

반복문 안에서 continue문을 만날 경우 break문과 달리 반복문을 빠져나가지 않고

뒤에 문장으로 내려가지 않고 반복조건을 확인하러 올라갑니다. 그리고 반복조건이

아직도 참인경우 그대로 반복영역을 처음부터 실행합니다

 

continue문도 if문과 함께 사용됩니다. 조건이 참이지만 넘기고 싶은 경우에 조건문과 함께

사용되어 해당 조건일때 반복영역을 실행하지 않고 넘어갈 수 있습니다!

 

 

 

switch문

switch문의 조건에는 정수 값이 와야합니다. 상수는 들어올 수 없습니다.

switch문의 조건에 따라서 case문이 실행됩니다.

default문에는 예외의 값이 들어올경우에 처리되는 코드입니다.

case문에서 코드를 실행하고 그 구문을 빠져나오려면 break;문을 써줘야 탈출가능합니다

case와 break는 어떻게보면 세트라고 생각하면 됩니다!

 

case에는 상수

 

swtich문은 case문을 모두 확인합니다. 그러다 해당 조건에 맞는 case문을 만날 경우 그제서야

코드가 실행되고 break문을 만나야 탈출이 가능합니다.

한마디로 조건에 맞는 case문을 만나기 전까지 모든 case문의 조건식을 비교하게 됩니다

 

break문이 없으면 조건에 만족하는 case문의 구문을 실행하고 그 밑의 case구문들이 모두 실행됩니다!

 

두가지 조건식을 걸고 싶을 경우

case 'A':

case 'a':

              break;

 

if~else if~else문 보다 swtich문이 가독성이 더 좋아서 선호한다.

 

 

 

goto문

goto문은 레이블을 설정해서 해당 레이블: 로 표시한 곳으로

흐름이 이동되는 문법입니다.

 

goto문 쓰면 사수에게 뒤통수를 맞는다.

문법이 있긴하지만, 장점보다 단점이 훨씬 많다.

 

goto문을 쓰면 흐름을 설정할 수 있지만, 직접 추적을 해야하기에

흐름이 한눈에 들어오지 않는다.

 

 

 

goto문 문법
go to SKIP(레이블);

...

SKIP(레이블):

레이블로 바로 이동한다.

 

결론 : 이해는 하되 쓰지말자!

 

반응형

 

반응형

'C' 카테고리의 다른 글

재귀함수에 대하여!  (0) 2023.05.10
함수에 대하여!  (0) 2023.05.10
반복문에 대하여!  (0) 2023.05.09
printf함수와 scanf함수 정리하기!  (0) 2023.05.09
자료형에 대하여!  (0) 2023.05.09
반응형
반복문이란?

하나 이상의 문장을 N번 이상 반복 실행하기 위해서 구성하는 문장

 

 

 

반복문의 종류

while, do~while, for

 

 

 

while문

while문은 반복영역내부의 코드를 조건이 참일동안 반복시켜줍니다.

반복문의 대상이 한 문장이면 중괄호 생략 가능합니다.

 

주의사항

들여쓰기(tab)를 해야 가독성이 좋습니다!

 

 

 

무한루프의 구성

숫자 1은 '참'을 의미하므로 반복문의 조건은 계속해서 '참'이 된다.

이렇듯 반복문의 탈출조건이 성립하지 않는 경우 무한루프를 형성한다고 한다.

 

이러한 무한루프는 실수로 만들어지는 경우도 있지만, break문과 함께 유용하게 사용되기도 한다.

break문은 강제로 반복문을 나가게 만들어주는 기능입니다.

 

 

 

반복문 중첩

반복문은 중첩이 가능합니다.

while문으로 예시를 들면 while문 안에 while문이 존재하는 상태입니다.

 

 

do~while문 기본구성

반복조건을 반복문의 마지막에 진행하는 형태이기 때문에

최소한 1회는 반복영역을 실행하게 된다. 이것이 while문과의 가장 큰 차이점입니다.

 

최소한 1회 이상 실행되어야 하는 반복문은 do~while문으로 구성하는 것이 자연스럽다.

문법은 아래의 그림과 같이 사용하면 됩니다.

 

while문과 do~while문과의 차이

while문은 반복영역을 실행하기전에 조건을 검사하고 들어가고,

do~while문은 반복영역을 실행한 후에 조건을 검사하고 들어갑니다.

 

조건이 맞지 않을 경우, while문은 반복영역이 실행되지 않고,

do~while문은 1회는 실행이 가능합니다.

 

 

 

반복문 필수 3요소
  • 반복을 제어하기 위한 변수
  • 반복 조건검사
  • 조건을 빠져나오기 위한 연산(장치) / 조건을 false로 만들어서 반복문을 탈출하려는 장치

 

 

 

for문의 구조

초기식에서의 값이 조건식을 만나고 해당 조건에 만족하면 반복문장을 실행후에 증감식에 가서

초기값을 증가합니다 이를 다시 조건식에 비교하는 방식으로 반복문장에 있는 코드들이 반복됩니다.

 

일부 컴파일러는 여전히 초기식에서의 변수 선언을 허용하지 않습니다.

for문의 반복영역도 한 줄이면 중괄호 생략가능합니다

 

 

 

for문의 흐름 이해

for문의 흐름은 밑에 그림에 설명이 잘 되어있기에 별도의 설명은 생략하겠습니다!

 

 

 

for문 메모리

아래의 코드에서 변수 num은 main함수가 시작하자마자 메모리에 저장됩니다.

그리고 main함수가 끝나야지 메모리가 해제가 됩니다.

int main(void)
{
	int num;
    
	for(num = 0; num < 3; num++)
	{
		printf("Hello");
	}
}

 

아래의 코드에서는 int가 for문 안에서 선언되어서 for문에서 처음으로 메모리에 저장됩니다.

그리고 for문이 끝나야 메모리가 해제가 됩니다.

for(int num = 0; num < 3; num++)
{
	printf("Hello");
}

 

위 두개의 차이점은 for문안에서 변수가 선언된 경우에는 for문이 끝나면 main함수에서 더 이상 활용되지 않습니다.

반대로 main함수(for문 밖에서 선언한다면)에서 선언을 한다면 for문이 끝나고 num변수를 활용할 수 있습니다!

프로그래머는 프로그래밍을 최적화를 해야하기 때문에 메모리를 최대한 잘 활용해야 합니다.

for문안에서만 쓸 변수라면 for문안에서 변수를 선언하는것이 좋습니다!

 

이미지 출처 : 윤성우의 열혈 C 프로그래밍

 

반응형

 

반응형

'C' 카테고리의 다른 글

함수에 대하여!  (0) 2023.05.10
조건문에 대하여!  (1) 2023.05.10
printf함수와 scanf함수 정리하기!  (0) 2023.05.09
자료형에 대하여!  (0) 2023.05.09
비트 연산자에 대하여!  (0) 2023.05.09
반응형
printf함수 특수문자

큰 따옴표는 문자열의 시작과 끝으로 해석이 된다

큰 따옴표 자체의 출력을 원하는 경우에는 큰 따옴표 앞에 \문자를 붙이면 사용 가능합니다.

 

 

 

printf함수 서식문자

%# : #을 붙이면 접두사가 같이 나온다.

=> #을 삽입하면 8진수 앞에 0, 16진수 앞에 0x가 삽입됩니다.

컴퓨터는 지수를 표현할 수 없으므로 e 표기법으로 지수를 대신 표현한다.

 

정돈된 출력보이기

서식문자 사이에 들어가는 숫자는 필드의 폭을 의미

기본 오른쪽 정렬 / -는 왼쪽 정렬로 사용된다.

 

 

 

입력

입력은 해당하는 주소의 값을 넘겨줍니다.

 

float, double, long double 의 데이터 출력 : %f, %f, %Lf

float, double, long double 의 데이터 입력 : %f, %lf, %Lf

float형 데이터의 삽입을 위한 서식문자
double형 long double형 데이터의 삽입을 위한 서식문자

 

이미지 출처 : 윤성우의 열혈 C 프로그래밍

 

반응형

 

반응형

'C' 카테고리의 다른 글

조건문에 대하여!  (1) 2023.05.10
반복문에 대하여!  (0) 2023.05.09
자료형에 대하여!  (0) 2023.05.09
비트 연산자에 대하여!  (0) 2023.05.09
정수와 실수의 표현 방식에 대하여!  (0) 2023.05.09

+ Recent posts