관리 메뉴

History

c 언어 온라인 무료강좌 2차시 정리 본문

Tipslab 강좌 복습/김성엽 선생님 c 강의 복습

c 언어 온라인 무료강좌 2차시 정리

luckybee 2021. 1. 15. 13:15
728x90
반응형

해당 게시물은 김성엽 선생님의 강의를 바탕으로 만든 게시물입니다.

 

●식별자

 

-변수의 자료형: 키워드

-변수의 이름: 식별자

 

변수의 이름 예시를 아래 코드 주석에서 설명하겠습니다. 

#include<stdio.h>

int main()
{
//좋지 않은 습관

    int 한글  //변수 이름을 한글로 하다가 나중에 피봅니다
    int a,b,c // 변수 이름을 어떻게 하든 상관없지만 나중에 코드가 길어지면 알아보기 힘듭니다.
    int num set // 변수 이름은 띄어쓰기를 사용할 수 없습니다.
    int 123num // 변수 앞에 숫자를 사용할 수 없습니다. 숫자를 앞에 사용하게 되면 컴파일러가 
               // 숫자로 인식합니다.
    
//사용가능    
    
    int num,Num,nUM //변수는 대 소문자를 구분하기 때문에 전부 다른이름의 변수입니다.
    int _num,n_um, memory_set //언더바는 자신의 변수 이름을 보기 쉽게하기 위해 사용합니다.
                              //또한 자료형(키워드)이(가) 같으면 한줄에 여러번 사용가능.
    int name // 변수이름은 사용자나 다른 사람이 유추가능한 이름으로 설정하는게 좋습니다.
    int name123 // 변수 이름 뒤에는 숫자를 사용가능 
       
        
}

-세미콜론(;)은 종결자를 의미.

 

* 글을 쓸 때. 이 문장의 끝을 사용하듯, 세미콜론(;)은 프로그래밍의 한 줄이 끝난다는 의미를 내포한다. 

ex)printf("hello world~!");

 

* 세미콜론은 종결의미 말고 아무 의미도 없기 때문에 한번 쓸 거 여러 번 써도 오류는 없다.

ex)printf("hello world~!");;;;;;;;;

 

* 세미콜론은 잘만 찍으면 한줄에 여러 줄 써도 상관없다.

ex)printf("hello"); printf("world~!");  ->권장하지는 않는다.

 

코드는 한 줄을 끊어서 사용해도 된다. 아래 코드는 위, 아래가 같은 코드이다.

#include<stdio.h>

int main()
{
    int num;
    num=num+1; //표준

    num=
    num
    +
    1;   //기분 좋으면 이렇게 써도 무관 뒷감당은 알아서
}

 

●복합문

-복합문은 하나의 그룹이라고 생각하면 된다. 

-{}(중괄호)를 사용하여 코드를 그룹화한다.

-중복된 변수를 사용 가능하다(아마다 지역변수 개념이 들어간 듯)

-복합문은 반복문, 조건문에서만 사용하는 것이 아니라 사용자가 코드 분리를 원할 때면 언제든 사용할 수 있다.  

 

> 그룹화 전

 

-아래 코드를 보면 변수 이름이 2개 이상 중복이 되어서 어떤 결과값이 나올지 예측할 수 없다. 솔직히 이렇게 쓰면 그냥 오류가 난다.

-결론: 이렇게 쓰지는 말자.

#include<stdio.h>

int main()
{
   int num=4;
   num=num+1;
   num--;
   int num=1;
   num++;
  
}

>그룹화 후

 

-아래 코드를 보면 위의 코드와 같이 변수 이름이 중복된다. 그러나 {}(중괄호)를 이용하여 그룹화를 시키면 다른 이름의 변수라고 생각한다.

-주소값도 다르다.

#include<stdio.h>

int main()
{
   int num=4;
   num=num+1;
   num--;
   {
     int num=1;  //위의 변수와는 다른의미의 num이다. 쉽게 설명하면 동명이인이다.
     num++;
   }
}

●함수

 

평균을 구하는 코드가 있다. 평균을 구하는 코드는 간단하게 4줄 이내로 짤 수 있는 코드이지만 이 간단한 코드도 1000번을 써야 한다면 매우 귀찮을 것이다.

그때 함수를 이용하여 사용한다면 4줄짜리*1000이 아니라 그 함수만 호출하면 되기 때문에 함수 이름 1000번만 적으면 된다.

 

결론: 함수는 재사용성이 좋고 편리해진다.

 

아래 함수를 사용하지 않은 간단한 평균 구하기 코드로 예시를 보여주겠다. 

#include<stdio.h>

int main()
{
   int num1=12, num2=7, num3=5;  //선언과 동시에 초기화
   double avg; //평균을 대입할 변수 
   avg=(num1,num2,num3)/3.0; // 3.0을 대입하는 이유는 double변수이기 때문에 소수점을 위해  
 
}

 

아래 코드는 함수를 사용하여 간편하게 만들어보겠다.

#include<stdio.h>

double Average(int a,int b, int c, double count)  //함수의 키워드(변수)로
{                                                 //최종 반환 자료형을 추측
   return (a+b+c)/(double)count;
}  //함수화


int main()
{
   int num1=12, num2=7, num3=5;  //선언과 동시에 초기화
   int Num1=10, Num2=6, Num3=45;  //위에랑 이름이 다른 변수(복습)
   int num_1=1, num_2=4, num_3=51;  //이것도 위에 변수들이랑 다른 이름을 가진 변수(복습)
   double avg; //평균을 대입할 변수 
   double avg2;
   double avg3;
   avg=Average(num1,num2,num3,3);
   avg2=Average(Num1,Num2,Num3,3);
   avg3=Average(num_1,num_2,num_3,3);  //이렇게 함수를 사용하면 코드도 깔끔해지고
                                       //시간도 절약이 된다

}

이렇게 Average함수 하나만 쓰면 간편하게 재사용이 가능하다.

 

이때 프로그램에 변형이 생겨서 변수를 하나 더 추가해서 평균을 내야 한다면, 간단하게 함수만 수정해주면 된다.

 

아래 코드를 보면 간단하게 변수가 4개로 수정된 것을 확인할 수 있다. 이렇게 함수를 사용하면 유동적으로 프로그램에 대한 변화에 대처가 가능하다

#include<stdio.h>

double Average(int a,int b, int c, int d)  //함수의 키워드(변수)로
{                                                 //최종 반환 자료형을 추측
   return (a+b+c+d)/4.0;
}  //함수화


int main()
{
   int num1=12, num2=7, num3=5, num4=50;  
   int Num1=10, Num2=6, Num3=45, Num4=5;  
   int num_1=1, num_2=4, num_3=51, num_4=5;  
   double avg; //평균을 대입할 변수 
   double avg2;
   double avg3;
   avg=Average(num1,num2,num3,num4);   //num4 추가 
   avg2=Average(Num1,Num2,Num3,Num4);
   avg3=Average(num_1,num_2,num_3,num_4);  
                                       

}

그러나 나누기 연산에서 0으로 나눠버리면 문제가 발생하기 때문에 예외처리라는 것을 해줘야 한다.

 

그렇지만 어떻게?

먼저 쉬운 if문으로 코드를 보자

#include<stdio.h>

double Average(int a,int b, int c, double count) 
{  
  if(count)// if(count!=0), if(count>0)은 같은 의미이지만 쓸데없는 연산 낭비이다. 
   return (a+b+c)/(double)count;
   else
   return 0;
}  

이렇게 하면 분명 오류를 없앨 수 있다. 그래도 if문 보다 좀 더 효율성 높은 코드가 있다.

 

아래 코드를 보자.

#include<stdio.h>

double Average(int a,int b, int c, double count) 
{   
   return (a+b+c)/(double)(count+!count);// count가 0이 되면 !를 통해 부정한다. 그럼 1이된다.
}  

나는 김성엽 선생님이 수업하기 전까지 이런 코드를 생각도 못했다...

 

 

 

이번에는 구조체를 이용하여 매개변수를 관리해보겠다.

 

함수만 바꿔주면서 유동적으로 프로그램하기에는 한계가 있다. 그래서 등장한 것이 구조체이다. 

 

구조체는 매개변수의 개수가 달라질 수 있으면 나열 형식으로 사용하지 않고 구조체를 사용하는 것이 좋다.

#include<stdio.h>

typedef struct NumList{
  int a;
  int b;
  int c;   //unsigned가능?
  int d;
}NL;

double Average(NL data)  
{                        

   return (data.a+data.b+data.c+data.d)/4.0;
}  //함수화


int main()
{
   NL data1={12,7,5,50};
   NL data2={10,6,45,5};
   NL data3={1,4,51,5};

   //int num1=12, num2=7, num3=5, num4=50;  
   //int Num1=10, Num2=6, Num3=45, Num4=5;  
   //int num_1=1, num_2=4, num_3=51, num_4=5;  
   
   
   double avg; //평균을 대입할 변수 
   double avg2;
   double avg3;
   avg=Average(data1);  
   avg2=Average(data2);
   avg3=Average(data3);  
                                       

}

위처럼 코드 전체에 변화가 생겼을 때 쉽게 변형이 가능해진다.

 

●함수의 원형

 

다음은 함수의 원형에 대해서이다.

 

먼저 함수의 원형이라고 말하면 무슨 뜻인지 헷갈려 하는 사람들이 있을 텐데 아래 코드를 보면 된다.

 

#include<stdio.h>

int sum(int a,int b);  //함수의 원형

int main()
{
   int num=56,num2=4,result=0;
   result=sum(num,num2);
}

int sum(int a,int b)
{
    return a+b;
}

 

함수의 원형을 쓰는 것은 오래전에 코드를 배운사람이라고 한다. 난 젊으니까 함수의 원형을 안 쓸 거다.

그러면 함수의 원형을 안 쓰고 사용자 함수를 만들려면 어떻게 해야 할까?

 

답은 간단하다 그냥 모든 함수를 main함수 위에다가 쓰면 끝난다. 아래 코드로 보여주겠다.

 

#include<stdio.h>

int sum(int a,int b)
{
    return a+b;
}

int main()
{
   int num=56,num2=4,result=0;
   result=sum(num,num2);
}

이렇게 사용하면 된다. 하지만 모든 일에는 예외가 있다. 꼭 함수의 원형을 사용해야 할 때가 있는데 그때는 함수들이 서로가 서로를 호출할 때이다. 아래 코드로 설명하겠다.

 

void a()
{
    b();
}

void b()
{
    a();
}

이렇게 서로가 서로를 호출할 때는 함수의 원형을 이용하여 코드를 작성하자!

 

 

●연산자와 조건문

연산자를 잘 이용하면 조건문을 쓰지 않는다.

 

#include<stdio.h>

int main()
{
   int data;
   data=1<3;  //> < && || 이렇게 조건문에서만 쓰이던 기호들이 알고보면 연산자이다. 0과 1로 출력
}

 

아래 a가 6 이상이면 b에 1을 대입하고 그렇지 않으면 b에 0을 대입하는 코드가 있다. 이제 이 코드를 if문 없이 만들어 보자

#include<stdio.h>

int main()
{
   int data,a=5,b=6;
   if(a>5)
     b=1;
   else
     b=0;
}

아래 보이는 코드는 놀랍게도 위의 코드와 같다.. 

#include<stdio.h>

int main()
{
   int data,a=5,b=6;
   b=a>5;
}

자 그러면 a가 6이상이면 b에 1이 아닌 5를 대입해도 이렇게 작성이 가능할까?

 

-가능하다. 지금부터 코드를 보자.

#include<stdio.h>

int main()
{
   int data,a=5,b=6;
   b=(a>5)*5; //참이면 ()안은 1이되고 *5를하면 된다. 아니면 0이니까 *5를해도 상관없다.
}

 

자 다음은 다른 예시를 보자

 

이 코드는 data가 10이 되거나 넘어가면 data를 0으로 바꾸고 10 미만이라면 data를 1씩 더해지는 코드이다. 

#include<stdio.h>

int main()
{
   int data=6;
   while(1)
   {
   if(data>10)
     data=0;
   else
     data++;
    }
}

이렇게 바꾸는 게 가능하다.

#include<stdio.h>

int main()
{
   int data=6;
   while(1)
   {
   data=(data+1)%10; //data가 10이 되는순간 나머지 0이 대입이 되며 10미만이면 1씩 더한다 
   }
}​

이제 if 조건문에 대해서 간단히 알아보겠다.

 

아래 코드를 보면 if~else문 안에 if~else문을 썼다. 그리고 중괄호를 사용하여 구분을 했더니 눈이 엄청 피곤하다.

또한 if~else문은 if문을 먼저 사용하고 else를 쓰기 때문에 else if라는 말은 없는 말이다. 그래서 if else를 한 줄로 해석하는 것이 옳다. 

#include<stdio.h>

int main()
{
  int data=7;
  if(data>5)
  {
     data++;
  }
  else{  //else 안에 if문을 넣는 것을 중첩 if이라고 한다
  if(data>6)
    {
       data++;
    }
    else
    {
      data=0; 
    }
  }
}

if~else를 한 줄로 해석한다는 것은 중괄호가 필요 없다는 것이다. 나중에 if문이나 for문에서는 한 줄 코드는 중괄호를 생각하기 때문이다. 그러면 이제 중괄호를 없애서 보기 편하게 만들겠다.

 

#include<stdio.h>

int main()
{
  int data=7;
  if(data>5) data++;
  else if(data>6) data++;
  else data=0; 
}

중괄호를 없애니 좀 더 코드의 줄 수가 줄어들었고, 보기 편해졌다.

 

 

다음에는 성적 프로그램이다.

아래 코드는 일반적인 if~else문을 이용한 성적 프로그램이다.

#include <stdio.h>
#pragma warning(disable:4996)  //scanf_s안쓰기 위한 오류코드
int main() 
{
	int score;
	char grade;

	scanf(" %d", &score); //0~100 불안하면 
    
    //score=score%101 이 코드를 넣어도 되고
    
    //if()문을 사용해서 예외처리를 하도록하자

	if (score >= 90) grade = 'A';
	else if (score >= 80) grade = 'B';
	else if (score >= 70) grade = 'C';
	else if (score >= 60) grade = 'D';
	else grade = 'F';

	printf("score : %d, grade : %c\n", score, grade);
}

그러나 이 프로그램을 if~else없이 만들어보라고 하면??? 가능할까? 

 

#include <stdio.h>
#pragma warning(disable:4996)  //scanf_s안쓰기 위한 오류코드
int main() 
{
	int score;
	char grade[11]= { 'F','F', 'F', 'F', 'F', 'F', 'D','C','B','A','A' };  //테이블 기법(배열)


	scanf(" %d", &score); //0~100 불안하면 
    
    score=score/10
    
  
	printf("grade : %c\n", grade[score]);

}

그렇다. 가능했다.. 바로 배열을 사용한 테이블 기법이라고 한다. 이렇게 하면 if~else문 보다 효율적인 처리가 가능하다.

728x90
반응형
Comments