C언어 수업정리/3월 수업정리

3월 12일 부가연산자, 함수, 제어문(if, else....)

송시혁 2013. 3. 12. 09:09


 증감연산자.

 a = a +1; , ++a;는 같은 뜻.


예) b=100; ,a=5;


b= ++a;(1)


b = a++;(2)


1. 전치문 a : 6,  b : 6


2. 후치문 b : 5,  a : 6


b = ++a; 알아보기 쉽게 표현.


a = a + 1;


b = a;


b = a++; 알아보기 쉽게 표현.


b = a;


a = a+1;





부가연산자.(대입연산자)

부가 연산

부가

x += 5;

x = x + 5;

-5;

x = x - 5;

x %= 5;

x  = x % 5;

*x;

x = x * 5;


가능하면 오른쪽으로 프로그래밍 한다!!

좌변 = 우변

좌변  = l(L) value

우변  =  r(R) value

'='이 기준이다.

변수선언시 유의

변수 = 변수, 상수, 수식, 함수

예) 3= 5;(x) 좌변이 상수(x)

3 + 1 = 5 + 4; 좌변이 수식(x)

 다음은 변수에 함수를 넣어 만든 소스.

#include <stdio.h>
int main()
{
  int inum;
  inum = printf("12\n");
  printf("%d\n", inum);
  return 0;
}

enter까지 포함하여 화면에 inum의 갯수 가 출력된다.

지금 inum = printf("12\n");선언 되었다. 프린트문에 12가 출력되겠지만

이것이 printf("12\n"); inum에 대입되었다. 그래서 아래에 프린트문에서 %d로 받아 출력이 된다

그런데 3이 출력이 되었다. 12인데 3으로 출력이 된것은 우리가 enter키를 포함해서 출력한 것이다. 즉, 12가 출력이 되고 키보드로 enter를 누른 것까지 합하여 3이 나온것이다.





#include <stdio.h>
int main()
{
  int num = 17;
  printf("num += 5: %d\n", num += 5);
  printf("num -= 5: %d\n", num -=5);
  printf("num *= 5: %d\n", num *=5);
  printf("num /= 5: %d\n", num /=5);
  printf("num %= 5: %d\n", num %=5);    
  
  return 0;
}

 x += 5; -> x= x+5;만 쓴다.(알아보기 쉽다)

int num;

num = num +5;(초기화되지 않았다)

num  =17; 선언하면-> 초기화된 상태. 

num + 5;에서 17을 + 5 연산을 먼저한 뒤, = 좌변에 있는 num에 저장된다.

그래서 아래 출력에 22가 나온다. 2번째 프린트문에서도 마찬가지로  num = num -5;

에서 num이 저장되어 있는 값 22를 먼저 -5한 다음 = 좌변에 있는 num에 대입이 된다.

그래서 17이 된다. 그와 같은 방법으로 연산이 되어 아래와 같은 결과가 나온다.

이부분은 잠깐 맨마지막 참고 자료에서 따로 언급하겠다.





캐스트 연산자.

int + float 인 경우 생각해보자. int가 정수형 float이 실수형. 서로가 다른 타입의 자료형

이 때 int가 실수형인 float으로 변환하여 연산된다. 이처럼 int의 타입이 실수형으로 임시적으로

변하게 이것을 캐스트라고 부른다.

캐스트  : 타입을 바꾸는 것, 상수, 변수 앞에()를 붙이면 수동적으로 자료형을 바꿀 수 있다.

예) 4+3.2f = 묵시적형변환(컴파일시 error를 띄우지 않는다)

(float)4 + 3.2f = 명시적형변환(수동적으로 캐스트를 집어넣었다.)

4를 (float)으로 지정하지 않아도 자동적으로 캐스팅 되지만(위의 예),

(float)으로 수동적으로 해주면 정확한 결과를 얻을 수 있다. 다음의 예제를 보면서 생각해보자.



#include <stdio.h>
int main()
{
  int intA= 14, intB =3;
  
  float floatC = 0;
  
  floatC = intA / intB; //
  printf("%f\n",floatC);
  
  floatC = (float) intA / intB;
  printf("%0.10f\n", floatC);
    
  
  return 0;
}

floatc = intA /intB;에서 자료형인 intA와 intB는 같은 정수형이다. 그래서 먼저 14/3을 연산하여 몫이 4가 나오는데 = 좌변인 float의 의해 실수형이된다. 그러나 이미,  intA /intB;가 대입하기 전에 먼저 int형으로 계산하여 float에 대입된다. 

즉, intA /intB; = 4.xxxxx에서 .xxxxxx가 지워지고 4만 남게 된다. 그리고 이제야 실수인 float에실수형의 변환하지만, 4.0000000으로 출력된다. 이미, .xxxxxxxx부분이 날아갔기 때문이다.

하지만, 다음구문floatc = (float)intA /intB; 에서는 수동적으로 캐스트를 해주었다. 즉 intA는 실수가 되는 것이고 따라서 intB또한 실수형으로 변환한다. intA/intB가 캐스트되어 실수형소수까지 연산되고, = 좌변읜 float에 대입된다. 이때, 똑같은 실수형이므로 출력이 4.xxxxxx까지 출력된다. 위의 프린트문에서는 소수점 10자리까지 표현되었다.

 그런데 결과값이 제대로 나오지 않았다  그이유는 float의 크기가 작아 다 표현하지 못해 에러가 났다

이런 경우 float 값을 double 로 바꾸면 정상적으로 출력된다.


printf()함수

형식

1.("내용");

2.(" %형\n", 변수,상수); 

3.("%형%형", , , ); 그림참조


 4.대소문자.

5.소수점사용가능 예)4.5;

다음예제보기. 30을 10진수, 8진수, 16진수




#include <stdio.h>
int main()
{
  int num;
  num = 30;
  printf("%d\n", num); //10진수
  printf("%o\n", num);//8진수 
  printf("%x\n", num);//16진수
  
  return 0;
}





scanf()함수

scanf() 수가 키보로부터 값을 받을 때는 사용 <엔터 >  

지는 입력  는다.

버퍼 - 그램과  이에 일시으로 값을 저장

단락문자(공백문자) - 여러개의 입력값은 동시에 읽을 경우 사용

                                , 문자, 탭문자


127을 소스에 입력한다고 생각하자. 
scanf내부처리를 표현하면 
num = ('1' - '0')*100; // 1*100이되어 100
num = ('2' - '0')*10 + num; //  (2-0)*10+ 100이되어 120.

num = ('7' - '0') + num; // 7+120이 되어 비로소 127이된다.





#include <stdio.h>
int main()
{
  printf("%d\n"'9'-'0');
  printf("%p\n"255);
  printf("%08x\n"255); // 8자리를 나타내되, 앞에 비워있는 곳은 0.
  
  return 0;

}




%p를 쓰면 000000FF로 출력된다.

%08x = 000000ff로 출력된다.이것을 보아 %08X를 하면 %p와 같은 값이 나온다고 알 수 있다.

08에 8은 여덟자리를 나타내고 앞에0은 숫자가 없는곳은 0으로 표현한다.





#include
 <stdio.h>
int main()
{
  int a =123;
  
  printf("*1234567890*\n");
  printf("*%5d*\n", a);
  printf("*%7d*\n", a);
  
  
  return 0;
}





%5d와 %7d.

%5d는 5자리까지 표현. -를 붙이면 *123__*로 된다.(__는 보여주기 위한 것.)

%7d는 7자리까지 표현 *____123*, %-7d는 *123____*이 나온다.



#include <stdio.h>
int main()
{
  int num;
  char ch;
  float fnum;
  
  printf("Please enter integer, character\n, floating poinber number : ");
  scanf("%d %c %f"&num, &ch, &fnum);
  printf("You typed na integer : %5d\n", num);
  printf("You typed na integer : %5c\n", ch);
  printf("You typed na integer : %9.2f\n", fnum);
  
  return 0;
}




제어문 - 실행순서를 정하는 문.

원래는 프로그램은 위에서 아래로 순차적으로 실행되어 최종값을 도출하나, 제어문에서는 그것을 반대로 하거나 중간에 있는 것을 뛰어넘고 실행할 수도 있다. 그래서 제어문이다.

복합문 : {}가 2세트 이상 들어가 있는 소스.(괄호의 줄을 맞춰서 작성한다. 그래야 분별이 쉽다.)

선택문 : if/if else/swich문 ....

반복문 : for/while/do -while.......


#include <stdio.h>
int main()
{
  if(1)
  printf("하이\n");
  if(0)
  printf("하이\n");  
  return 0;
}
if()의 가 참일 때 다음 프린트문이 실행되고 거짓일 때는 실행되지 않는다.
그래서 if(1) = 참이다. 괄호안에 1이면 참 0이면 거짓이다.
그래서 아래와 같이 if(1)아래 프린트문과 실행되고 if(0)은 실행되지 않는다.










복합문

#include <stdio.h>
int main()
{
  int a, b; //
  a = 15;
  {
    int a = 100// 새로 변수를 지정 100
    b=23;
    printf("a + b = %d and a - b =%d\n", a + b, a -b); //123, 77
  }
  printf("a + b = %d and a - b =%d\n", a + b, a -b);//중괄호를 벗어낫기 때문  
  return 0;
}
변수를 중복 지정 할 수 없지만, 복합문에 중괄호에는 지정이 가능.
그러나 중괄호안에서만 효과가 있다. a + b에서 새로선언한 100이 연산되어 값이 저장된다.
글래서 123. 77이 나온다.
그러나 }중괄호 닫히는 순간, 바낕쪽 소스에는 int a = 100; 선언은 효과가 없다. 그래서 제일 위에
선언한 int a; , a = 5;가 저장되어 출력값 38, -8이 나온다.



참고

미정값 = 값은 있지만,불명확한 값 (일명, 쓰레기값)

cpu와 메모리

int num = 100;

num = num - 5;

num = num + 5;

num = num + 1;.........

printf("...\n",?);

있다고 가정하자. 여기서 cpu를 다시보자.

cpu의 주요 3대기능이 arithmatic(산술), cu(제어), reg(저장)이 있다. 위에서 int num = 100;은 메모리의int의 넘이라는 미정값이 저장된다.  그리고 100이라는 숫자가 num에 저장되어 메모리의 초기화가 된다. 이때 cpu에도 저장을 하는 역할을 reg가 담당한다. 그리고 num이 -5를 연산하는데 이 때의 역할을 alu가 담당한다. 그리고 cpu가 메모리에 보내는것을 cu가 제어한다.

자 그럼 cpu와 메모리의 저장되는 형태, 순서를 정리해보자.

최초의 int num은 메모리에 기억(미정값)

그리고 = 100;에 의해 초기화.

cpu에도 초기환 된값을 저장되어있다(reg)

다음 -5;를 연산하는데 일단 cpu가 이 연산한 값95를 가지고 있다. 그러나 메모리에 보내지 않고 그대로 cpu에 남아서 연산처리 한다. 이 연산처리를 프린트문 바로 윗줄까지 cpu의 저장한 다음에 비로소 최종출력값만 메모리에 보내게 된다. 즉, 최종출력을 하기전에 cpu가 연산하여 저장하는 값을 캐시(chache)라고 한다. 

cpu가 캐쉬를 반복하여 한계에 다다른면, 제일 오래된 캐쉬값부터 지우고 새로운 값을 저장해 나간다. 위에 예에서는 가장 먼저 저장 되는 캐쉬는 95이다. num =num -5;에서 연산되 95이다. 지금 당장에는 문제가 되지 않는다. 그러나 나중에는 문제가 발생한다. 지금단계에서는 개념만 이해하자.




<!--[endif]-->