관리 메뉴

History

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

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

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

luckybee 2021. 1. 18. 10:52
728x90
반응형

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

 

 

● 조건 수식 연산자

 

-if~else문을 하나의 문장으로 만들어 놓은 것

-항상 단일 문이 와야 함 수식은 안된다.

 

예를 들어 아래와 같은 코드가 조건 수식 연산자이다.

#include<stdio.h>

int main()
{
   int num;
   int data=5;
   
   num=(data>4) ? data++ : data--;   //?은 연산자 어떤 형식으로든 대입해야하는 것이 필요
                                 
                                 //참이면 앞에꺼(data++) 실행 거짓이면 뒤에꺼(data--) 실행
   return 0;

}

 

헷갈려하지 말아야 할 것은! 조건 수식 연산자를 아래와 같이 사용하면 안 된다.

#include<stdio.h>

int main()
{
   int num;
   int data=5;
   
   (data>4) ? num=data++ : num=data--;   //이러면 오류남
   return 0;

}

조건 수식 연산자는 복잡한 수식 사용이 불가능하기 사람들이 if~else를 많이 사용한다. 그래서 조건 수식 연산자는 권장하지 않는다!

 

●반복문

 

-c언어는 반복문을 3가지 제공한다(while, do~while, for) 

 

ps) goto문은 쓰레기임 쓰지 말 것

 

-반복문 3개의 성능은 비슷하다.

 

 

먼저 for문을 살펴보자 아래는 for의 구성이다.

int main()
{
   for(시작조건; 범위; 증감식)
   {
   
   }
}

-중간에 세미콜론이 나오는 것은 for반복문의 구성요소를 구분하기 위해서 세미콜론을 찍은 것뿐이다. 문장 분리자 x

 

이제 아래 코드는 for문의 예제이다.

int main()
{
   for(int i=0,j=0; i<10; i++,j++)
   {
   
   }
}

이런 식으로 ,를 사용하여 시작 조건을 2개 이상이 가능하다. 또 다른 사용 예제를 보자

int main()
{
   for(int i=0,j=0; i<10 && j<10; i++,j++)  //중간 범위는 ,(콜론)이 아니라 || 나 &&를 사용하여 추가한다 
   {
   
   }
}
int main()
{
   for(; ; )  //이런식으로 시작조건과 종결조건이 없으니 for로 무한루프를 만들 수 있다. 
   {          
   
   }
}

 

이제 while문의 사용 방법을 보겠다. 아래 보이는 코드처럼 매우 간단하다.

 

int main()
{
  while(조건식)
  {
  }
}

 

 

Quiz1

 

만약 반복문으로 1, 2, 3, 4, 5를 만들어야 한다. 그럴 때 어떻게 사용할 것인가?

 

답은

 

 

 

 

 

 

int main()
{
   int i=1;
   for(i; i<5; i++)
   {
      printf("%d, ",i); // 1, 2, 3, 4,까지 찍고
   }
   printf("%d\n,i);   //5출력하고 개행
}

최대한 for문 안에 if문 사용하는 것을 줄이자!

 

Quiz2

 

아래 코드처럼 if문에서 i가 0일 때만 실행하는 코드는 매우 나쁜 코드이다. 이럴 때 어떻게 하면 좋을까?

int main()
{
   int i;
   for(i=0; i<5; i++)
   {
      if(i==0)....;  //i가 0일때 실행
      printf("%d, ",i);
   }
}

답은

 

 

 

그냥 반복문 전에 한번 실행하고 그다음에 반복문을 실행하면 된다.

int main()
{
   int i;
   ....;     //처음 실행할 코드
   for(i=1; i<5; i++)
   {

      printf("%d, ",i);
   }
}

 

 

__inline

 

-__inline은 메크로 함수이다.

-함수를 많이 많이 만들 때 관리하기에는 용이하지만 함수를 만들 때마다 스택 프레임이 발생한다. 

 그럴 때 사용하는 게 inline( __를 안 쓰면 c언어 표준으로 사용하는 것, c와 c++ 전부 호환)이다.

 

이렇게 말해서는 감이 안 오니까 코드를 보면서 이해하자. 아래 코드를 보자. 

 

지금 아래 보고 있는 코드는 구구단 출력 코드이다.

int main()
{
   for(int i=2; i<10; i++)
    for(int j=1; j<10; j++)
    {
        printf("%d*%d=%d",i,j,i*j);
    }
}

지금과 같은 상황에서 함수를 사용하여 안에 있는 for문을 따로 빼보자.

 

아래 코드는 함수를 이용한 구구단 출력 함수이다. 아래 주석에 보이는 것처럼 인자 값을 넘겨주고 받는 과정에서 스택 프레임이 쌓인다. 

void f(int d)   //인자값을 받는다.
{
    for(int i=1; i<10; i++)
    {
        printf("%d*%d=%d",d,i,d*i);
    }
}


int main()
{
   for(int i=2; i<10; i++)
    f(i)  //인자값을 넘겨준다.
}

이와 같은 스택 프레임을 없애려면 

 

아래 코드처럼 앞에 __inline 또는 그냥 inline 메크로 함수를 입력하면 된다. 그러면 컴파일러는 아까 함수로 빼내기 전에 프로그램으로 인식한다.

__inline void f(int d)   //인자값을 받는다.
{
    for(int i=1; i<10; i++)
    {
        printf("%d*%d=%d",d,i,d*i);
    }
}


int main()
{
   for(int i=2; i<10; i++)
    f(i)  //인자값을 넘겨준다.
}

형태적으로 함수로 빼놓은 것처럼 보이지만 기계어로 해석할 때 컴파일러한테 합쳐서 해석해달라고 이야기하는 것과 같다. 이렇게 보면 보기에 좋아지고 성능도 같게 진행되니까 유용한 메크로 함수인 것 같다.

 

#define 메크로 함수도 스택 프레임이 쌓이지 않게 도와주지만 복잡한 수식이 들어가면 내 머리가 터질 수 있으니까 그냥 inline 쓸 것

 

 

● 악마들(전역 변수, static, extern, goto, const)

 

-전역 변수는 프로그램 전체에 영향을 줄 수 있는 악마 같은 놈이다.

-전역 변수를 사용하면 내 실력 향상을 더디게 해주는 악마 같은 놈이다.

-전역 변수를 사용하면 좋은 구조를 만들 수 없다.

-나중에 멀티 스레드 사용하다가 문제가 된다. 악마 같은 놈...

 

결론: 포인터와 지역변수를 활용할 것!

 

-static 이 놈도 전역 변수임. 악마 같은 놈

-static 초기화 불가능 전역 변수임. 더 악랄한 놈

 

 

-extern 악마 이종사촌임. 쓰지 말 것

 

-const 이놈은 정치인.. 타락천사...

-const는 수정이 불가하다.

-왜 정치인이냐면 나중에 프로그램된 기계에서 사람이 사고를 당할 때임

왜냐하면 사고 경위를 밝히기 위해 코드를 확인해보니 전에 프로그래밍하던 사람이 

이 코드는 바꾸면 안 돼!!라는 뜻으로 const를 사용한 것임 그런데 나중에 코드를 바꾼 사람이

const를 무시하고 바꿈!! 이럴 때는 둘 중 한 명이 누가 잘못했냐 이렇게 나올 텐데 전임자는 const를 붙여놨기 때문에

 

자기 방어가 가능 결국 바꾼 사람 잘못임. 

 

 

 

그냥 교양 개념으로 이해하면 좋을 듯

 

 

● 한 대 맞아야 하는 코드

 

그냥 길가다가 상사한테 까이고 싶으면 아래 코드처럼 써도 됨

 

int a; //전역 a

int main()
{
   int a; // 지역 a
   {
      int a// {}속 지역 a
      {
         int a// {}속 {}속 지역 a
      }
   }
}

4개의 a 모두 같은 이름이지만 다른 종류이다. 그냥 이렇게 쓰는 사람이 보이면 한 대 때리면 된다. 물론 내가 이렇게 쓰면 난 4대 정도 맞아야 한다.

 

 

 

● 포인터

 

먼저 우리는 어떠한 말을 할 때 어떤 사람이 무엇을 할지 정하고 말을 한다. 

 

ex) 내가 밥을 먹는다, 민기가 집으로 온다. 

 

이러한 개념이 변수이다.

 

그러나 포인터는 간접 지정 명령이기 때문에

 

ex) 그가 밥을 먹는다.

 

이렇게 대명사를 지칭하는 것이 포인터 즉 대상을 지칭할 수 없고 행위만 지칭할 수 있을 때

 

왜 포인터는 이렇게 할까?

 

c언어가 미래 운영체제를 만들 수 있는 기술이기 때문이다. 미래에는 누가 쓸지 어떻게 될지 모르기 때문에

대명사로 지칭하는 것이다.

 

(이게 맞는지 잘 모르겠으니 다른 사람들 블로그도 찾아볼 것)

 

즉 대상을 추정할 수 없을 때 사용

 

또한 행위도 특정할 수 없는 경우도 있다.

 

ex)그가 그것을 합니다.   

 

누군지도 뭐하는지도 알 수 없는 것 이럴 때 포인터와 함수 포인터를 같이 쓰는 것이다.

 

포인터는 대상을 대명사로 바꾸고

 

함수 포인터는 행위를 대명사로 바꾼다.

 

 

 

 

 

 

 

728x90
반응형
Comments