'강의'에 해당되는 글 8건

  1. 2008/05/23 Lesson 11. 포인터 - 2부 call by value vs. call by reference by 모니터에습기찼어
  2. 2008/05/11 Lesson 10. Pointer란? -1부. 간단하게 알아보기 by 모니터에습기찼어
  3. 2008/04/21 Lesson 9. Array? 배열은 무엇인가요? by 모니터에습기찼어
  4. 2008/04/14 Lesson 8. 함수 (function)란 무엇인가요? by 모니터에습기찼어
  5. 2008/04/11 Lesson 7. 반복되는 삽질을 간편하게~ for/while/.do-while by 모니터에습기찼어 (1)
  6. 2008/04/07 Lesson 6. 판단하고 살자! if, else, switch case문 by 모니터에습기찼어
  7. 2008/04/04 Lesson 5. 기본연산과 우선순위 by 모니터에습기찼어
  8. 2008/04/03 Lesson 4. 기본 입출력 by 모니터에습기찼어
자.. 포인터는 총 3번에 나누어서 할게요.. ㅎㅎㅎㅎ
한동안 업뎃이 지연되었으므로 몰아서 올립니다. ㅋㅋㅋ 앞으로 빵꾸 안낼게요 ㅎㅎ

------------------------------------ 절 취 선 ---------------------------------------------
Call by value? Call by refernce?
이게 무슨말일까.. 자.. 이것을 알려면 잠시 함수로 돌아가줘야할 필요가 잇어.
함수를 우리가 호출할때 인자를 넘겨줄수 있었지?
넘기는 방식은

void main(){
int a=4;
int b=3;
...
 myfun( a,b);
...
}

myfun(int a, int b){
 ....
}

이렇게 사용이 되었다는걸 기억할거야
자.. 이경우가 call by value라 불려.. 단순히 지금은 변수 자체를 던져주었잖아.. 그치? 이경우 a와 b가 실제로 넘어가지 않고 myfun에서 새로이 a,b가 생겨서 거기에 값만 복사가 되는거야. 실제로 프로그램에서 함수가 실행되면.. (호출되면..) 메모리 스택에 현재 상황에서 상위 영역에 호출되는 함수를 위한 영역을 새로 잡아.. 그리고 거기에 필요한 데이터를 복사하는거지... 음...
그니까..

|    main함수영역     |      myfun 영역       |
|  int a,   int b         |   a의사본 b의사본   |

이런식으로 존재하게 된다랄까?  이렇게되면.. myfun에서 a의 사본과 b의 사본을 아무리 지지고 볶아도..
메인함수의 a와 b에는 아 무 런 영향을 주지 않겠지?
 음.. 예를 들자면.. 우리가 main에서 myfun을 호출했어....
 myfun에서는 자기가 넘겨받은 a와 b의 값을 하나씩 증가시키는 역할을 해..
 즉 myfun이...

 myfun(int a,, int b){
      a++;
      b++;
     printf("%d %d\n",a,b);
  }
 이렇게 선언되어있고...
 main함수에서...
  main(){
     int a=4;
     int b=3;

     printf("%d %d\n",a,b);
     myfun(a,b);
     printf("%d %d\n",a,b);
}
이렇게 소스코드가 있다고 할 경우.. 프로그램을 실행한 후의 결과값은...
 4 3 << main에서 출력
 5 4   <<myfun에서 출력
 4 3  << main에서 출력
 이렇게 된다는거지.. 이유는 아까 위에서 설명한대로임 ^^
만약 우리가 myfun에서 계산한 어떤값을 main으로 가지고와서 활용을 하고싶다면.. 아니면 변화된 어떤값을 사용하고 싶다면.. 방법이 몇가지 있겠지?
우선적으로 3가지만 들어볼게..

1. a와 b를 전역변수로 사용한다.
  a와 b의 범위가 프로그램 전체에 얽히도록 선언해주는 방법이야.. 그러면 myfun에서든 어디서든 a와 b를 건드릴수 있지.. 그렇게된다면.. 정말.. 최악이겠지? 아무데서나 저 a와b를 건드리게될테니.. 뭐.. 여튼 비추야..

2. 리턴값의 활용
  리턴값을 줘서 메인에서 myfun을 호출하고 그 결과를 가져와서 반영하는방법.. 이거도 괜찮은 방법이지
 근데 만약 건드려야할게 한개가 아니라 더 많다면? 이건 좀 골치아픈이야기가 될거같아..

3. 포인터로 주소값을 넘겨준다 (Call By Reference)
 이것이 포인터 사용 목적중에 한가지야. 아까 Call By value는 함수를 호출할때 변수 값(Value)만 넘겨줘서 복사해서 사용하는것이었지만... 이경우는 포인터를 사용하여 변수의 주소값을 넘겨줘서 호출된 myfun에서 참조(reference)하여 사용하도록 하는거지.
사용 방식은.. 대략...

void main(){
int *a=4;
int *b=3;
...
 myfun( a,b);
...
}

myfun(int &a, int &b){
 ....
}

이렇게 되지 이경우... myfun이 호출되었을때..
메모리에 들어간 것을 보자.
|     main 함수 영역   |        myfun영역          |
|   int a,   int b         |  a의포인터, b의포인터 |

이렇게 올라가게 된단다.. myfun에서 a의 포인터를 넘겨받으면 call by value처럼 myfun안의 사본을 가지고 값을 읽는게 아니라. 포인터가 가진 주소를 참조하여 (여기서 포인터가 가진 주소는 main함수 영역의 a를 가리키겠지? 혹은 b나) 값을 읽어와.
 자.. 그럼 call by reference로 호출을 하였을때.. myfun에서 a값을 건드리게 되면.. main함수에 있는 a를 직접 건드리게 된단다. 그러면... myfun에서 a와 b를 가지고 지지고 볶으면... 그게 main에 있는 a와 b에도 영향을 주게된다는거지.
자.. 아까 위의 코드를 call by reference로 바꺼볼게

myfun(int &a,, int &b){
      a++;
      b++;
     printf("%d %d\n",*a,*b);
  }
 
main(){
     int *a=4;
     int *b=3;

     printf("%d %d\n",*a,*b);
     myfun(a,b);
     printf("%d %d\n",*a,*b);
}
이 결과값은..
4 3 <<main에서 myfun호출전에 출력
5 4 <<myfun에서 출력
5 4 <<myfun호출된 후 main에서 출력
이렇게 출력된다는거지.. 영향을 받는다는 말이 무슨뜻인지 알겠지?
그렇다면 어떠한 함수를 호출하고 그결과를 다시 활용해보고싶다면.. 포인터를 쓰는편이 좋겠지?

그리고 call by reference로 호출당하는 함수로 작성할때.... 함수의 파라미터는 &를 붙여서 받는다는거
잊지말길바래... 저 &가 왜 붙었냐하면.. *의 반대로 생각하라고하면 될라나?
*로 넘어간건... &로 받아준다.. 그냥 이렇게 생각하면 대..  &a하면 a의 주소를 받아와라.. 머 이런의미야
반대로 *이 붙으면 이 주소로 가라 는 의미가 되고...
아까 포인터 선언시에는 *a로 선언한다는거 알지? 기억하고있겠지?
포인터를 우리가 사용할때는
a = 주소값 이렇게 사용을 하였어... 포인터로 선언된 변수는 주소값만을 가질 수 있다고했잖으니..
근데.. a가 가리키고있는 주소에 내가 직접 값을 넣고싶으면... *을 붙였지?
*a = 4; 이의미는 a가 가리키고 있는 주소에 4를 대입해라~ 라는 의미거든...
즉 *포인터변수명 은.. 그 포인터변수가 가리키는 주소로 가서 무엇을 해라라는 의미...
값을 읽든 쓰든 변경하든말이지..
*포인터변수 = 일반변수 처럼 생각하고 사용되어진다는말
자.. *이 빠져있으면 주소값만을 가지게된다.........
이게 포인트고.. ㅎㅎㅎㅎ
자 myfun(a,b)라고 호출을 해서 난 주소 값을 넘겨줬어...
그러면 받는쪽도 주소값을 받아와야하잖아?
그래서 int a가 아닌 int &a 로 받아오게 된거지.... int *a는 안되나 하고 궁금해하겠지만...
*a는 아까 말하기로... a가 가리키는 주소에 직접..가서.. 변수처럼 쓰이는거라고했지?
그러면 넘겨주는건 주소를 주는데 받는애는 일반 변수로 받아...
이러면 컴퓨터가 싫증내 ㅋㅋㅋㅋ 그니까.. 안대겠지? ㅋㅋㅋㅋㅋㅋ
주소값으로 받아줘야하므로 &를 붙인다.. ㅋㅋㅋㅋ 이상-
call by reference에 대해서만 설명했고... 3부에서 메모리 동적할당을 하도록 하겠습니다
Posted by 모니터에습기찼어
강좌가 한동안 너무너무 오래 쉬었습니다... -_-;; 이상하게 강좌에 대해서 쓸려고하는데 필이 안와서-_-;
죄송합니다 ㅎㅎㅎㅎ
한번 달려봅시다.

-------------------------------------- 절취선 -------------------------------------------------
 자.. 저번에 배열에 관해서 배웠어...
배열을 배우면 항상 나오는것이 포인터이지... 포인터를 설명하자면.. 음...
포인터란 무엇인가... 이게 상당히 설명하기 어려운 부분인데... 음,... 어떠한 곳에 있는 녀석을 가리키는 녀석이 포인터인데... 설명이 좀 이상하지? ㅋㅋㅋ 나도 이해하기 어려워-_-; ㅋㅋㅋㅋ
 음.... 포인터는 우선 가리키는 녀석이다~ 라고 말을 해둘게...
 우리가 프리젠테이션하는걸 볼때.. 사람들이 레이저 포인터를 쓰지? 그 레이저 포인터가 가리키는곳에는
무언가가있을거야 (설명하는 사람이 중요하다 싶은 내용을 포인터가리키잖니?)
 우리는 그사람이 설명하는 내용중에 여기를 보라~ 하고 포인터로 가리키면 그것을 보고 무엇인지 알수있겠지? 포인터는 그렇게 어떠한 것을 가리키는거야... 포인터가 어디를 가리킬라면 어디로 포인터를 쏜다-라는걸 알고있어야겠지? 가령 설명하는 사람이 세번째 단락의 두번째 줄에있는 C언어 라는 글자를 가리키고싶은데.. 설마 엄한데를 가리키는경우는 없잖니? 실제로 C언어에 쓰이는 포인터 역시 내가 어디를 가리키고있어요~ 라고 정보를 가지고있어.. 그 정보는 내가 찾고자 하는 데이터가 있는 메모리의 주소를 가르쳐주고있지.
 뭐,.. 다른예를 들어보자면... 내가... 수업을 들으러 가야해. 그럴라면 그 강의실을 찾아가야하잖니? 그러면 우리는 시간표를 보겠지.. 그곳에 강의실 번호가있잖아. 가령 Y8317이라고 써있고 거기가 내 수업하는곳이야... 그럼 나는 당연히 그 Y8317이라는 강의실번호(주소값)을 찾아서 수업에 들어가겠지? 포인터의 역할은 그렇게 주소값을 가지고 어디어디로 찾아가면 있어~ 라고 해줘.
 포인터의 사용 방법은

 데이터타입 *포인터이름;

 이렇게 사용을 하게된단다. 변수 선언과 똑같아. 다만 이름앞에 *표시를 붙여준다는 사실을 반드시 기억해주길 바래 ^^
 데이터타입은 왜쓰이는가? 하고 생각을 해볼수도 있어.. 포인터는 단순히 주소만 가리키고있다는데 데이터타입이 왜 필요할까? 하는 답은 변수 선언시 데이터타입을 쓰는 이유에 대한것과 같아.. 이 주소에 있는 데이터는 어떠한 타입이니까.. 읽을때 어떻게 읽어~ 하고 알려주기 위해서 데이터타입을 써주는거야. 이말을 한번 잘 생각해보면 char *nana; 라고 선언된 nana가 가리키는 주소에 char타입의 데이터가 들어가있어야한다는거지.
 변수랑 비슷해 사용하는건.. 다만 앞에 *을 붙여주는거.. 이거 잊지말길 바래...
 char *nana 해놓고서... nana라고 하면 주소값이 출력된다는 사실 잊지말고...
 근데 이 포인터를 왜 쓰는걸까? 뭐할라고 이걸 써먹을까? 그게 좀 이상하지않아? 걍 데이터 하나라면...
 굳이 이것을 이용해서 가리킬 필요는 굳 이 없는데 말이야..
 자.. 포인터를 주로 쓰게되는 경우... 왜써먹는지.. 한번 알아보도록 하자...
 이유는 두가지가 있어.
 그것은 바로...
 Call By Reference
 메모리의 동적인 사용

 이 두가지를 이용해서 쓴단다.
 이것이 무엇인가! 바로.,.. 다음강좌에 시작합니다 (2부가 바로 시작될 것입니다.)
Posted by 모니터에습기찼어
이제 후반부 돌입입니다...
배열과 포인터를 같이 설명하는데.. 그렇게할경우 지면이 많이~ 소모되는 단점이있어..
배열은 따로 뽑아냅니다. 근데.. 아무리봐도 설명이 너무 후잡합니다 ㅜ_ㅠ 짱돌은 던지지말아주세요

------------------------------------ 절취선 ---------------------------------------------------

 자.. 이제 배열이라는것에 돌입했다.. 아직 배열이 무엇인지 모르는 사람들도 있을거야... 음.. 소스코드를 보다보면 이런식으로 선언되어있는것을 보았을지도 몰라
 
  int name[20];

 이것이 배열이란다. 자 배열의 선언법은 이걸로 끝~~~~~
너무 간단하지?-_-;; 이해해 막장이잖아...ㅋ
배열의 선언방법부터 봅시다.

  데이터타입 배열이름[크기];

 이렇게 쓰는데 배열이름은 변수이름처럼 그냥 원하는대로 적으면 된단다. 이것이 변수선언과 똑같은데
차이점이라면... 뒤에 [크기] 이게 붙어.. 크기는 말그대로 배열의 크기를 나타내... 음... 배열은
같은 형식의 데이터를 여러개 묶어서 셀때 편하지.. 음...
 int name[20]; 이라고 한다면 name이라는 int형 데이터가 20개가 있다는것을 나타내는거야...
 int형 데이터 20개를 묶어서 name이라고 부르겠다~ 라는 뜻이지...
 그리고 개별 데이터들은 []안의 숫자(이것을 인덱스라고 말함)를 가지고 내가 몇번째 데이터인지 알려주는거야. 흠... 저 배열은 묶음인거잖아.. 저 묶음의 몇번째 데이터다 하는걸 알려주는거지.... 가운데있는 숫자로..
그러니까.. 음... 만약 int name[20] 이라 한다면...
┌──┬──┬──┬──┬──┬──┬     ┬──┬──┬──┐
│   0  │  1  │  2   │ 3   │  4  │  5   │  ...│ 17  │  18 │  19 │
└──┴──┴──┴──┴──┴──┴     ┴──┴──┴──┘
 이런식으로 공간 20칸을 잡아서 쓰는거야... 음... 방으로 치자면 name이라는 int형식의 방 20개를 잡았다 이런거지... 저 숫자(인덱스)는 0부터 시작하는거고... 음..
 그래서 인덱스의 범위는 0~갯수-1까지 번호가 붙을수있어... 이 배열을 왜써먹을까? 같은 데이터 여러개를 건드려야할때 유용하지...
 가령 뭐... 너네가 씨언어시간에...
수업을 들어갔어.. 가령 c언어 a반이다... 여기에는 40명이있다고 가정해보자... 그래서 너네들의 점수를 담은 배열이있다고 해볼게
 int ca[40]; 이렇게 하면... 너네들의 점수를 ca[1], ca[2].. 이런식으로해서 너네들의 점수를 관리하기편하게하는거지... 가령  for문과 연동해서 생각해보자... 너네들 40명의 점수를 출력해야한다면...
   int ca1,ca2....,ca40;
  printf("%d",ca1);
  printf("%d".ca2);
  ....
  printf("%d",ca40);
 이렇게 처리하는것보다는
 int ca[40];
 for( i = 0 ; i < 40 ; i++){
     printf("%d",ca[i]);
 }
이렇게 쓰면 상당히 편리하다는거지.. 평균같은거 낼때도 편리하겠지? 배열을 돌면서 인덱스를 이용해서 총합을 구하고 하면 편리할테니...
 같은데 쓰일 데이터를 가지고 묶어서 사용하면 편리해 ㅎㅎㅎㅎ 그걸 위해서 배열을 쓰는거고...
잘만 활용하면 쓸만하게 쓸수있지않겠어? ㅎㅎㅎㅎ
 그리고 이제.. 또 한가지 더 추가하자면.. 배열은 다차원 배열도 가능해.,...
 주로 쓰이는것이 2차원배열....
 int matrix[3][3]; 이런식으로 사용하면 2차원배열...
 int mat2[3][3][3]; 이런식으로하며는 3차원배열인거고...
 2차원 배열의 경우 어떻게 데이터가 배치되는가하면...

 matrix[0][0]  matrix[0][1]  matrix[0][2]
 matrix[1][0]  matrix[1][1]  matrix[1][2]
 matrix[2][0]  matrix[2][1]  matrix[2][2]

이런식으로 표현되지.. C언어의경우 배열의 데이터가 메모리에 표현되기로는
 matrix[0][0]  matrix[0][1]  matrix[0][2] matrix[1][0]  matrix[1][1] ......
이런식으로 올라가게 된단다... 음.. 이거는 포인터배울때도 나올 개념이니까 확인하도록 하고...
 배열의 주요한 목적은...
 같은 목적에 쓰일 데이터들(데이터 타입도 같아야해)을 모아서 처리할때.. 아주 유용해...
 아까 위에서 말한 성적같은거처럼 말이지...
 예를들어 컴소과 1학년 아이들의 씨언어/미적/물리 중간고사 성적을 처리하고싶어...
 그렇다면...
  int score_c[70];
  int score_calcu[70];
  int score_physic[70];
 이렇게 해서 처리하면.. 각 과목별 성적의 합계와 평균을 내기에 편하겠지? 그런 목적에 쓰이기 좋은것이
배열이라고 생각하면 좋겠구나... 흠...
 뭐 만약 정의하기 나름이라면 2차원 배열로도 할수있겠지
 int score[70][3];
 해서 각각 인원의 (70명분의) 3과목 성적을 차례대로 입력받는 프로그램을 짤때 이런변수하나(배열하나)넣어두면 도움도 될거같네 ㅎㅎㅎㅎ
 아~ 그리고 인덱스는 절대 범위를 벗어나지 않게해...
 가령 내가 0~39까지의 40개의 배열을 잡았어.. 근데 만약 index가 -1이라거나...(이런경우 100%뻑)
 index가 40이 넘어가버리면... 결과는 장담할수가 없단다... 배열의 크기는 처음에 선언될때 잡으면 무조건 그 크기만큼만 사용이 가능하니까 그거 명심하도록 하고..(배열을 너무크게잡을경우... 좋지않다.... 배열의경우 처음에 프로그램이 시작되서 마무리지어질때까지 그건 메모리에 계속 올라가있게되거덩... 즉.. 불필요한 공간을 많이 잡게되는거야... 너무 크게잡아버림...)
 오늘은 여기까지 ㅎㅎㅎㅎㅎ
 배열은 그냥 같은 데이터 여러개를 모아놓은것이다.. 각 데이터를 구분하는데 있어서 index로 구분한다..
 그리고 배열의 index는 0부터 시작이다.  배열의 index는 절대 지켜라...
 배열은 한번 생성되면 끝이다. 선언될때 크기가 결정되어지기때문이다.. 그래서 너무 크게잡으면 절대 좋지않다.
Posted by 모니터에습기찼어
흠.. 이제부터 좀 내용이 많이 어려운 내용이 될텐데... 제가 썰을 잘 풀수 있을지 모르겠습니다...
여기서부터가 진짜 어려운 부분인데.. 흠.... 이거 고민이네요 ㅎㅎㅎㅎㅎ
뭐 여튼 오늘도 막장강의 올라갑니다.

--------------------------------------- 절취선 -------------------------------------------

 자... 반복문까지 들어갔어... 오늘 배울 함수까지 하면... C언어의 절반을 배운거라고 봐야하려나?
목차상으로는 절반좀 넘었고... 난이도로는 반도 안온거고? ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ
 자... 어쨌든 최대한 쉽게 막장스럽게 설명을 해보도록 할게
함수란 무엇인가.. function이라고 하지... 영문과 다니는 아이에게 function을 물어보면 기능 이렇게 대답하겠지만.. 우리는 컴퓨터한다고.. function하면... 함수가 떠올라서 문제인...-_-; 그 함수...과연 이건 뭐하는녀석일까?
 함수란것은 우선... 어떠한 역할을 하는 애야... 내가 무언가 일을 하고싶어... 그러면 그 함수를 불러다가 필요한거 딱 던져주고나면... 그 함수가 알아서 무언가 일을 하겠지... 음... 뭐라고 설명하면 좋을까..? 너네가 자판기앞에 있다고 해보자.. 커피자판기.. 너네가 돈을넣고... 어떤 버튼을 누르는가에 따라서 각각 다른 커피가 나오지? 밀크커피만 연달아 누르면 계속 밀크커피가 나올것이고... 그렇게... 자판기는 너네한테 돈과 어떤걸 선택할지 주문을 받으며는 해당 커피를 뽑아줘.. 이렇게 너네가 동전을 넣고 버튼을 눌러서 뭘 먹겠다~ 라고만 하면... 알아서 그것을 만들어서 내주는것이지.. 함수도 그것과 똑같에.. 너네가 무엇을 넘겨주면 함수가 자판기처럼 뭘 달라는건지 알아서 그것을 일해주는거지.
 함수의 사용법은....

리턴타입 함수이름(넘겨받을 인자들 목록){
    ... 할일
   (return 돌려줄값)
}


이런형태로 함수를 사용해..... 아직 말이 애매모호하지?
자.. 함수이름은 내가 원하는대로 지정하면 된단다. 물론 기존에 원래 있는 함수 이름이라거나 예약어들과
이름이 중복되면 안되겠지?(printf라거나 scanf, int 이런것등은 사용할수 없다는말이야)
 함수 이름은 원하는 대로 지정하면 될거야. 마음대로~ 자유롭게~ ㅋㅋㅋㅋ
그리고 리턴타입이라는 부분은... 너네가 이 함수가 실행되고나면... 무엇을 돌려줄 것인가..
가령 커피자판기면 우리가 돈을 넣고 버튼을 선택하면 해당하는 커피가 나오지? 커피자판기는 커피를 돌려주고... 라면자판기면 라면을 돌려줄 것이고.. 음료수 자판기면 음료수를 돌려주잖아... 함수도.. 내가 무엇을 돌려줄 것인가~ 를 지정해줄수있어...
 리턴가능한 타입으로는 char,int,float,double등의 기본적인 데이터타입과 char*라는 문자열(그냥 이런게 있다라고만 우선 알아둬 이부분은 나중에 문자열을 공부하면서 같이 배우게 될 것이야) 그리고 마지막으로 void라는 타입이 있어..
 void를 제외한 모든것은.. char면 char를 돌려주고 int면 int값을 돌려주고 그래 아까 말했잖아 커피자판기면 커피를 돌려준다고했으니 정수를 돌려준다고 미리 선언해주면 정수를 돌려받게되는거지 ^^
 자.. 그럼 void는 무엇인가... void는 형태가 없다는것을 말해.. 정확한 의미는 딱히 뭐라 지정할 타입이 없다~
이런의미를 갖게되지만 그냥 여기는 막장이고... 그리고 일반적으로도 쓰이는 의미로 말해서...
 void가 앞에 붙은 함수는 리턴값이 없다. 라고 생각하면 된단다.
 그럴경우는 return 돌려줄값 << 이부분이 없어도 되겠지? 나는 돌려주는 타입이 없다~ 라고 선언해줬잖아.
 그 외의 경우는 return 돌려줄값 이것이 반드시 존재해야하고. 아울러 돌려줄 값은 리턴타입과 일치해야겠지?
커피자판기에서 라면나와봐... 라면자판기에서 라면을 눌렀는데 캔커피 나온다고 생각해봐.. 뭔가 이상하잖아.. 안그래? 리턴타입과 돌려줄 값의 데이터 타입은 맞춰줘야한다~
 예)
   int ret_val(){                                  int ret_val(){
       int a;                                                 float a;
       a = 4;                                                a = 4.2;
       return a;                                            return a;
  }           이건 OK                             } 이건 NO!
이런 이야기지.. ㅋㅋㅋㅋㅋㅋㅋ
그리고... 음... 함수 파헤치기 또하나.
넘겨받을 인자들 리스트란 무엇인가... 우리가 함수를 실행할때 무언가 넘겨주고싶은값이 있을떄... 그것들을 적어주는게 넘겨받을 인자들 리스트야... 다시 커피자판기 이야기로 돌아가보자꾸나...
 우리가 커피자판기 그냥 눌러봤자 아무것도 안나오지? 우리가 넘겨줘야할것... 자판기에게 넘겨줘야할것은 우선 동전을 줘야하고... 그리고 버튼을 눌러서 자판기가 내가 뭘 뽑을지 알게해줘야겠지? 내가 자판기에게 넘겨주는것은 돈과, 내가 무엇을 넘겨줄 것이냐~ 이걸 지정해주는거야.
 음... 지금까지 봐온걸 토탈해서 커피자판기라는 함수를 한번 짜보자(C 언어식으로)
 예)
커피 커피자판기( 동전 금액, 버튼 종류){
      if( 종류 == 밀크){
            if( 금액 > 150원){
                  return 밀크커피;
            }
            else{
                  printf("잔액부족");
            }
      }
      else if( 종류 == 블랙){
             if(금액 > 150원){
                   return 블랙커피;
             }
             else{
                   printf("잔액부족");
             }
      }
          ....
}

파란색 : 데이터타입

대략 이런식이 될거야. 그리고 함수를 사용할때면...

동전 내돈;
커피 내가마실거;
버튼 내가누른버튼;
     
커피 = 커피자판기( 내돈, 내가누른버튼);


이런식으로 사용하면 된단다. 음.. 그리고 하나 중요한점...
함수를 사용하는곳 위에 함수가 미리 구현이 되어있어야 오류가 안나..(C언어에서는)
무슨말이냐 하면...

커피자판기(){
  구현
}

...
커피자판기 호출


이런 경우는 컴파일시 문제가 없지만...

커피자판기 호출
...

커피자판기(){
  구현
}


이렇게 되어있으면 컴파일이 안된다는것이지... 사용하는곳 위에 함수가 구현되어있어야해...
자... 만약 내가 함수를 100개를 써본다고 해보자.. 함수 100개가 위에 주루룩 구현되어있고... 프로그램실행에서 가장 중요한 main이 한참밑에있으면.. 좀 귀찮겠지? 소스코드 보기에 좀 안좋을거야. 그렇다고 밑에 구현하면 컴파일이 되지않고.. 참 난감해 ㅋㅋㅋㅋ
그래서 어떠한방법을 쓰냐하면... 프로토타입이라는것을 써.
아까 위에 커피자판기함수를 보자
커피 커피자판기( 동전 금액, 버튼 종류){
      if( 종류 == 밀크){
            if( 금액 > 150원){
                  return 밀크커피;
            }
            else{
                  printf("잔액부족");
            }
      }
      else if( 종류 == 블랙){
             if(금액 > 150원){
                   return 블랙커피;
             }
             else{
                   printf("잔액부족");
             }
      }
          ....
}

이것의 프로토타입은...
커피 커피자판기( 동전 금액, 버튼 종류);
이렇게 된단다.
즉 함수 구현부분 ( {랑 }로 둘러싸인부분)을 제외한 것을 프로토타입이라고해
프로토타입을 위에 선언해주면 소스코드가 보기 깔끔해져... 어떻게 쓰이냐하면...

프로토타입
....
함수호출
....
함수구현부


이렇게 써도 되거덩.. 그러면 보기에 한결 깔끔해지지않겠어?
프로그램의 제일 윗부분에 프로토타입 선언해두고 필요한데서 다 긁어서 쓰면 되잖아.. 구현은 제일 마지막에 구현하면 되는거니까. 보기에 깔끔해서 좋은편이지...
오늘은 여기까지 해서... 마치도록할게 ㅋㅋㅋㅋㅋ 다음번에는 배열을 한다...
이제 씨언어의 가장 어려운 부분을 건드리는것이야 ㅋㅋㅋㅋ
Posted by 모니터에습기찼어
오늘은 루프에 관하여 썰을 풀도록 하겠습니다. 언제나 막장다운강좌입니다... 아....
언제쯤 나는 강좌를 재미있고 이해하기쉽게 올릴수있을까요... ㅠ_ㅠ

------------------------------------- 절취선 -----------------------------------------------
 자.. 이제 반복문이란것을 배워보자... 루프라고도 하고 (영어로는 loop)이걸 왜 써먹는가에 대해서
조금 이야기를 해보고싶어지는구나 이것을 쓰는 이유는 다름이 아니라.. 반복되는 삽질을 간단하게 줄이기위하여 사용하는것이라 생각하면 된다~ 라고 말하고싶어
 주구장창 썰만 풀지않고.,.. 예를들어서 보자...
내가... 안녕하세요 라는 글자를 100번 출력하고싶어.. 어떻게 하면 될까?

printf("안녕하세요\n");
printf("안녕하세요\n");
printf("안녕하세요\n");
printf("안녕하세요\n");
printf("안녕하세요\n");
 .....
printf("안녕하세요\n");
printf("안녕하세요\n"); //100개째

이렇게 짜면 되겠지? 이말에 수긍하는 당신.... 컵라면과함께 야근하라~ -_-;
저 얼마나 아름다운 삽질이니... 반복문이라는 같은일을 계속적으로 처리해주는 구문이 있고만..
저런식으로 코드를 짜는 경우는 없지? 다들 반복문을 쓰지... 다음처럼말이야

for( i = 1 ; i <= 100 ; i++){
    printf("안녕하세요");
}


얼마나 간결하고 좋니.. 저걸 실행하고나면 안녕하세요~ 라고 100번을 말해줘... 깔끔하잖아? ㅋㅋㅋ
반복문이 하는일... 같은작업을 여러번할때... 써먹으라고 ㅋㅋㅋㅋ 좋잖아?
 자... 이제 어떻게 써먹는지 보는 시간~ 우선 while문부터 보자..

while(조건){
     시키고싶은일 (반복적으로 시킬..)
}


이렇게 쓰면 된다.
while문 안의 내용이 실행되려고 한다면... while안의 조건을 충족시켜야해.. 저 조건이 참이면
계속 시키고싶은일에 써놓은 일을 하는거야. 만약 프로그램이 계~~~속 같은일 반복하게하고싶다면...
while(1){...} 이라고 쓰면 되겠지? (참고로 이경우 탈출조건을 주지않으면 계속 같은일한다-_-)
그리고 do-while문이 있어... do - while문은... 사용법이

 do{
    할일
 }while(조건);


이렇게 쓰여.. 자.. 저것도 역시 while문처럼 조건에만 맞으면 무조건 할일을 해... 조건에 어긋날때까지
그러면 while문과의 차이는 무엇일까?
그 둘의 차이점은... while은 조건이 안맞으면 바로 루프를 빠져나가. 하지만 do - while은 한번 실행해보고나서 조건에 어긋나면 루프를 빠져나가 (반복을 안한다는말이야) while은 조건이 틀리면 아예 실행 자체를 안해.. 그러나 do-while은 최소한 한번은 실행이 된다는거... 루프를 실행할지 말지를 루프시작전에 조건검사를 하는가.. 아님 한번실행한 후에 루프를 빠져나갈지 실행할지 결정하는가. 그 위치의 차이가있어..
반복문의 마지막.. for문을 보자.. 아까 위에 썼던것처럼... 사용법은...

for( 초기값 ; 실행조건 ; 변화할값 ){
    할일
}


이렇게 쓰여.. 말이 좀 애매모호한데... 초기값이라는 부분은 for문에서 무언가 값을 지정해줄일이 있을떄..
아까의 경우 처럼 for( i = 1 ; i <= 100 ; i++)에서.. i라는 값을 for문에서 1로 처음에 설정을 해줬지?
그런역할이야. for문의 가운데의 실행조건은... while이나 do-while처럼...  루프를 실행할것인가 말것인가가
결정되어지는 조건인 것이고... 변화할값은... 루프를 한번 돌때마다 변화해야할 값을 적어둔거야.
어떻게 변화할지.. 아까같은경우는 1~100까지니까 1씩 계속 증가시키면서 카운트를 한거지.
그리고 for문의 경우 초기값과 변화할값 필드를 비워둘수도 있어.
for( ; (c=getchar())!=EOF ; ){
}
이런식으로 말이야
기본적인 구문은 여기까지로 줄이도록 하고...
for문으로 쓸거 while이나 do-while로도 쓸수있어.
그 반대도 또한 가능하고
이런거 말하면 좀 그렇지만... 음... 뭐랄까... 생각의 자유를 뺏을수도있어...
하지만... 그냥 참고삼아 말해둘께....
while, do-while같은경우는 반복을 하는데 카운트할 필요가 없는거 반복할때..
(가령 입력을 계속 받다가 종료할때)
for문은 카운트를 해야하는 (가령 100번이면 100번 1000번이면 1000번.. 이렇게 반복문 범위가 정해져있을떄)
반복문에서 쓰면 유용하다.

 오늘의 키포인트.
 같은일 반복할거면 일일이 쓰지말고 반복문을 쓰자... (즉.. 삽질하지말자)
 루프에서 가장 중요한것은 루프의 실행조건이다 (잘못하면 무한루프에 빠진다.)
Posted by 모니터에습기찼어
막장타는 씨언어강좌가 어느덧 6회.... 아마 다해서 15회정도에 끝날거같은데-_-;;
뭐 막장이니까 얼마나갈진 모르지만... 중반은 왔군요..

계속 가 보입시다~~~~

----------------------------------------- 절취선 -------------------------------------------

자.. 이번엔 조건식에 관해서 이야기를 해보도록 하자.. 조건식은 무엇일까?
말그대로 어떤 조건에 따라서 다른일을 하도록 하는데.. 이걸 분기문이라고도 해 (프로그램 진행이 나뉘니까)
자... 이제 계속 이야기를 풀어보자....
조건문은 왜 사용하는것일까?
그리고 어떻게 사용해야 하는것일까?

조건문의 사용이유 : 우리가 프로그램을 짜다보면... 언제나 길이 하나로 나오지는 않아...
 여러가지 경우의 수가있지... 가령... 내가 서울에서 부산으로 놀러간다고해봐....
기차를 타고 갈려고해... 근데... 내가 돈이 얼마나 있느냐에 따라서....
내가 KTX를 탈지... 새마을을 탈지.. 무궁화를 탈지... 아님 걍 걸어갈지-_-;;;; 경우의 수가 나오지않겠니?
이걸 프로그램으로 해석해본다면...(물론 난 한가지만 택한다고 가정해)
내가 ktx를 탈 돈이 있는가? -> 1. 있다.  -> ktx를 타고 간다
                                          2. 없다.  -> ktx를 타지 않는다
그러면 나는 새마을을 탈 돈이 있는가? ->1.있다 -> 새마을을 탄다
                                                        2. 없다 -> 새마을을 타지않는다
이런식이겠지?
이렇게 조건을 주어 분기를 시킬때 쓰는 문장이 분기문.. 혹은 조건문... 이렇게 불러
 가장 처음에 배우는것이... 그리고 만만하게 많이 쓰는것이... if문이야. else랑 한쌍을 이루지
 영어사전을 찾아보면... if : 만약 ~ 하다면이라는 뜻을 가지고 else : 그렇지않다면.. 대략 이런의미야...
자... 그럼 if문부터 파헤쳐볼까?
if문의 사용예는...
if( 조건식){
   ....
}
이렇게 사용되는데... 자... 조건식이라 쓰인 부분이 if의 ~하다면의 ~라고 생각하면 될듯해...
저말은... 만약 ~하다면 ...을 실행해라~ 라는 말이 되겠지..
저 기차타기를 보면... 가령... ktx 5만원 새마을4만원이라고 가정하자.. 그리고 내 가진돈은 money라는변수.
그럼 저 문제를 C언어 코드로 써보면
if( money >= 50000){
      printf("ktx를 탑니다");
}
if( money >= 40000){
      printf("새마을을 탑니다");
}
이렇게 되겠지? 근데 여기서... 한가지 문제가 있어.. 바로.....
내가 5만원이 있으면... 저 실행결과는... ktx도 타고 새마을도 타... 내가 한번에 두개를타... 분신술을 익힌건가? 뭐 어쨌든.. 이건 아니지? 난 하나만 탈거니까... 저경우는 두개의 if를 다 검사해봐... 만약 첫번쨰 조건이
맞다면 두번째 조건은 검사하게하고싶지않은데말이지... 그럴때 else를 붙여서 이게 아니면~ 다음거 보자~
이렇게 써줘보는거지... 바로... 다음처럼
if( money >= 50000){
      printf("ktx를 탑니다");
}else{
     if( money >= 40000){
           printf("새마을을 탑니다");
     }
     else{
          ....
     }
}
대충 이런식이겠지? 근데... 여기서 한가지 튜닝을 해보자....
우리가... 지금 열심히 조건을 검사했어... else 하고... 그안에 if를 넣었어.. 그치?
근데 보면... else 다음에 바로 if문을 넣잖아... 줄수가 너무 많아... 엔터키를 한번 더쳤잖아... 저렇게 분기되는 경우는... else if로 묶어서 쓸수있어... 영어 그대로 보면... 그렇지않고 만약 ~하다면 이런 의미를 가지게되겠지.. 그렇지? 그럼 저렇게 튜닝을 해보면....
if( money >= 50000){
    printf("ktx를 탑니다.");
}else if(money >= 40000){
    printf("새마을을 탑니다.");
}else if( money >= 20000){
   printf("무궁화를 탑니다.");
}else{
   printf("걍 걸어가셈");
}
뭐 이런식으로 쓸수있겠지.. 이게 좀 더 깔끔해 보이지?
이렇게 if문을 쓸수 있다는거~ 저거는 내가 돈이 5만원 이상인가? 그렇다면 ktx를 타고.. 아니고 만약 4만원 이상인가? 그렇다면 새마을을 타고... 그렇지않고 만약 2만원 이상이있나? 그러면 무궁화를 타고.. 그렇지않다면 걍 걸어간다... 이런식으로 생각하게 되는거지.
이상으로 if/else에 대해 적어보았고... if와 else를 사용하는데 있어서 가장 중요한것...
지금의 밑의 코드를 보자....
x = -1; y = 1;
if( x > 0)
    if( y > 0)
        printf("둘다양수");
else
       printf("x는음수");
라는 코드가 있다고 해보자... 씨언어 시간에 봐서 익숙하지?
이 프로그램의 실행 결과는 아무것도 출력되지 않음이 정상이야...
왜냐하면 녹색 else절이 어디의 if랑 쌍을 이루게 되는가 하면... 검은색 if가 아닌 파란색 if랑 엮여...
else문은 자기랑 가장 가까운 if문과 한 쌍을 이루게 되어... (기본적으로)
그럼 저걸 내 뜻대로 튜닝해보자.. (녹색과 검은색이 쌍을 이루도록)
if( x > 0){
    if( y > 0)
        printf("둘다양수");
}
else
       printf("x는음수");

이렇게 하면 녹색과 검은색이 쌍을 이루게 된단다... 그리고 if문에서 {}로 묶어주지 않으면... if문의 조건의
영향을 받는절은... 바로밑에 한줄뿐이란다..
즉.. 다시말해서..
x = 1;
if(x < 0)
    printf("x는 음수");

    printf("다시입력해주세요");
이렇게 되어서...  다시입력해주세요~ 라는 말은 출력이 된다는거지... 녹색부분끼리 한 쌍이라 보아 ㅋ
그현상을 막을라면
x = 1;
if(x < 0){
    printf("x는 음수");

    printf("다시입력해주세요");
}
이렇게 수정해야할것이고....
중요한 팁 한가지... if문을 쓰면 항상 {}로 블럭을 묶어줘....
나중에 소스코드볼때 좀 더 편해... (나만그런가? ㅋㅋㅋ)
자... if문에 대한 설명이 다 되었네....
근데 내용이 무지길다...
조건문 이어서 switch case문 바로 고고하자... 우선 스크롤의 압박이있지만 마지막까지 화이팅 ^^
switch case의경우는 여러 선택중 한가지를 실행할때 쓰는거야....
가령 우리가 평점을 계산한다고 해보자...(a,b,c,d로만나눌게)
a = 4, b=3, c=2, d=1 이런식이야...
이걸 if문으로 쓰게 된다면... (내학점  char는 grade)
char grade;
if( grade == 'a'){
   printf("평점은4점입니다");
}else if(grade == 'b'){
   printf("평점은3점입니다");
}else if(grade == 'c'){
   printf("평점은2점입니다");
}else if(grade == 'd'){
   printf("평점은1점입니다");
}else{
   printf("평점은0점입니다");
}
이렇게 긴 코드가 나왔어... 저렇게 if문 안에 ==로 비교하는것이 있다면..., switch case문이 좋아
사용예제는
switch( 변수){
  case 값1:
      할일1;
      break;
  case 값2:
      할일2;
      break;
  case 값3:
      할일3;
      break;
   default:
      할일4;
      break;
}
이렇게 쓰여... 만약 변수가 가진 값이 값1이면 할일1을 실행, 값이 2라면 할일2를 실행... 저 학점을 예로들면
switch( grade){
    case 'a':
        printf("평점은4점입니다");
        break;
    case 'b':
        printf("평점은3점입니다");
        break;
    case 'c':
        printf("평점은2점입니다");
        break;
    case 'd':
        printf("평점은1점입니다");
        break;
    default:
        printf("평점은0점입니다");
        break;
}
이렇게 바뀔거야...  자... 여기서 break라는 새로운것이 등장해썽... 이것은 현재 {}로 쌓인 부분을 뛰쳐나가겠다~ 라는 말인데.. 이걸 왜 써주느냐하면... 만약 break가 다 빠진상태면... 만약 grade가 a일때.. 평점은4점입니다. 3점입니다. 2점입니다. 1점입니다. 0점입니다가 출력이 되고... 만약 grade가 c라면... 평점은 2점입니다 평점은 1점입니다 평점은 0점입니다가 출력되... break가 없다면... 제일 위에서부터 조건이 매치되는지 보잖아.. 그 조건에 맞으면 그 밑에줄도 다 실행해버리려고하는 속성이 있어.. switch case문이라는것이...
이 속성을 잘 활용하면 유용하게 써먹을수 있겠지 ^^
그리고 if를 switch case로 변환하고싶다면... if와 else if의 모든 조건이 a == 4이면 a==3이면 등등의 ==으로만 연결된 조건이 나와야해 그런것만 switch case로 사용할수있단다.
그리고 저 default: 부분은 매치되는게 하나도 없을때 실행되는 구문(if else를 사용한 곳에서 마지막에 남는 else랑 같다고 보면 될거야)이야.

  오늘 내용이 좀 기네....
   내용 중요한거 요약...
  if문의 사용예는 if(조건식1){...} else if(조건식2){....}else{...}이라는거... 그리고 if문은...
 항상 블럭을 지정해주는 습관을 가지라는것...
   switch case문은...
  switch (변수명){
     case 값1:
         할일1;
         break;
.....
     default:
         기본할일;
          break;
  }
이런식으로 사용된다~ 이것만 기억해~ 다음번에는 이제 루프들어갑니다(반복문)
Posted by 모니터에습기찼어

자 기본 입출력과 데이터타입도 보았으니까...
이제 막장 레슨5입니다....
중반에 다가가는군요... 여튼 시작합니다. 슈슈슝-

--------------------------------- 절취선 ------------------------------------------------------

 오늘 다루어볼 이야기는 기본연산과 연산의 우선순위에 관해서야.
자.. 기본연산부터 보자..
기본 연산은 +,-,*,/ (더하기,빼기,곱하기,나누기)...;;
말그대로 더하고 빼고, 곱하고, 나누고 ㅋㅋㅋ
사칙연산이 존재하고.. 그리고
대입연산인 = 가 있어
a = b+c; 라는 줄은 b랑 c를 더해서 a에 '대입' 한다. 즉.. a는 b+c의 값을 가진다. 이말이지
여기까지 매우 쉬워요 ㅋㅋ 그치?
앞으로도 쉬워 -_-;
오늘은 좀 외울께 많지만 기본적인거는 다 알것이고... 그러니 별로 어려울건 없어 ^^
잠시 대입연산으로 이야기가 새어나갔지만..
다시 계산이야기로 가서 ^^
++과 --연산이 있어 사용법은 ++i, i++ (각각 i의 값을 1 증가) , --i, i--(i값 1 감소)
자 이것은 ++면 1증가 --면 1감소 이게 땡이야... 매우 간단하지?
다만 ++(혹은 --)가 앞에붙고 뒤에붙고 차이가 무엇이 있는가.. 를 보면
음....
예문을 하나 들어볼게
i = 3;
printf("%d\n",i++);
printf("%d\n",i);
를 실행해보면 3하고 4가 출력이 되고
i = 3;
printf("%d\n",++i);
printf("%d\n",i);
를 실행해보면 4와 4가 나와.. 지금처럼 i가 사용되면서 같이 ++이 붙어있을때 차이가 생기는데
++i는 i를 먼저 값을 증가 시키고 사용, i++은 i를 먼저 사용하고 나서 i값 증가.
이런 차이야... 그리고 계산하고 관련된 연산 한가지 더
%가 있어.. 이 %연산은 다름이 아니라... 나머지 구하기야...
5%3이라고 하면 5나누기3의 나머지..  즉 2가 나오는거지...
여기까지가 계산연산이고
논리적 연산은...
!가 있어 (참->거짓, 거짓->참)으로 변하지... 즉 not의 의미를 가져...
!참 = 거짓이 된다는거지 ^^ 그리고
&& (AND), || (OR)가 있어.. &&은 a && b 처럼 쓰는데 a와 b가 둘다 참이면... 참.. 하나라도 거짓이면 거짓이 되지.. 그리고 OR의 경우 a || b로 쓰는데.. 이것은 둘중 하나만 참이면 무조건 참.
그리고.. 비교연산을 보자..
<,<=,>.>= 가 있어 사용법은 a<b, a>b, a<=b, a>=b  이런식이지.. 그냥 이거는 둘이 비교해봐서
결과가 참인지 거짓인지 나오는거지
아.. 그리고 하나 더...(두개 더구나 ㅋㅋㅋ)
==하고 !=이 있어 a ==b (a와 b가 같으면 참 아님 거짓), a != b(a와b가 다르면참 같으면 거짓)으로 사용하지
참.. 그리고 가장 중요한것... 우리가 수학문제풀때...
3+5한값을 2배하고싶으면... (3+5)*2라고 쓰지? c언어에서도 이런 사용이 가능해
우리가 사칙연산할때도 더하기보다는 곱하기를 먼저하지?
이런 규칙이 씨언어에도 있어... 연산자 우선순위라고 부르는데... 계산을 할때 우선순위를 가지는 것들이지
순서를 보면....

높음   (), [] , ->, .(dot)
          !, ~, ++, --, (casting), &, sizeof, *(pointer)
          *, /, %
          +,-
          <<, >>(bitshift)
          <, <=, >, >=
          ==, !=
         & (bit연산 and)
          | (bit연산 or)
         ^ (bit XOR)
         &&
         ||
         ?
         =, +=, -=, *=, /=
낮음   ,

이렇게 되는데 여기서 좀 이상한거있지? 못봤던것도 보이고,... 그런건 잠시 제끼자..
지금 기억하거나 알지않아도 되는 연산자들은... [], .(dot), ->, ~, (casting), &, *(pointer)
<<, >> (bitshift)랑 &,|,^(bit연산)은 알지 않아도 괜찮아
기억할것은... 빨간색으로 표시된것만 우선 알아두면 될거야..
우선순위가 높은거부터 가장 우선적으로 연산이 수행되는거니까 참고하고...
기본적으로 괄호가 가장 높고.. 뒤집기(!), ++,--연산이 높고, 그리고 곱셈/나눗셈이 높고 그다음이 덧셈,뺄셈..
그리고 비교연산, 그다음 논리연산, 그다음 대입연산의 순으로 계산이 된단다.
 자 근데 여기서 못보던게 등장했어.. 하나하나 봐보자..
? 연산인데..
 조건식? 문장1: 문장2;
 조건식이 참이면 문장1이 실행, 아니면 문장2가 실행되는거지...
 가령..
 a>b? printf("a"): printf("b");
 이런 구문이 있다고 할떄... a > b이면 a가 출력되고,, a<b이면 b가 출력되는거지
 그리고 그 밑에있는 대입의 연산을 보자...
 a += i; 라고 한다면...
 이것은  a = a + i ;야.. 줄여서 표현한거뿐이야.. 그러면 a -= i 는 a = a - i;
 a *= i 는 a = a * i;이고... a /= i 는 a = a /i;
이렇게 된다는거지...  이렇게해서 연산자와 연산자 우선순위에 대해서 살펴보았어..
그러면 다음에는... 조건식에 대해 파헤쳐보자

Posted by 모니터에습기찼어
진도가 많이 늦습니다. 오늘 하루에 두개 업뎃-_-a

음.. 썰을 잘 풀수있을라나 ㅋㅋㅋ

-------------------------- 절취선 ----------------------------------------------------

자 기본 데이터타입까지 살펴보았지?
이번에는 우리가 볼게 기본 입출력에 관해서 보자. 기본 입력과 출력에 관해서 ^^
자... 우선 기본 출력부터...
여러분들이 제일 처음에 짠 소스코드
printf("Hello, World"); 이것을 기억하시는가? ㅋㅋㅋㅋ
자... 기본 출력중에 출력...
printf를 보자꾸나 ^^
printf("...");라는 말은  ""안의 ...를 출력해라는 뜻이야. 근데.. 지금처럼 보면 Hello, world라거나 이런거만
출력해줬잖아... 근데 만약 우리가 어떤 계산을 하고 그 결과를 알고싶어. 그러면 어떻게 출력해야할까?
그걸 위해서 C언어에서는 출력형식지정자(맞나?)인가를 써서 해결을해.. 자... 이제 새로운단어나왔다..
외우지마라..
 너네가 int형 데이터를 출력하고싶다 (정수값을 출력하고싶다)면 %d
 char형 데이터를 출력하고 싶다(문자값을 출력하고싶다)면 %c
 실수형 (float)형 데이터를 출력하고싶다면 %f
 좀긴실수(double)형 데이터를 출력하고싶다면 %f나 %lf (%lf추천)으로 출력을 해준다고 우선 외워두고 보자
 그리고 번외적으로 %x출력은 16진수로 변환해서 출력해주는것이고 (이건 나중에 배우게 될것이야)

 예)
  int a,b,c;
  a = 2; b=3; c = a+b;
  printf("%d + %d = %d\n",a,b,c);
  이 결과는 출력이 2 + 3 = 5 라고 나올거야
  감이 좀 오려나? 음... 정수(int)를 printf를 이용하여 출력하고싶다면 %d로 사용한다는거
  그리고 저기서 보면 알겠지만 %d가 3개면  int 데이터도 3개가 되야해.
  음.. %d의 의미는 이자리에 int형 데이터의 값을 출력해줄래~ 하는것이기떄문에...
  %d가 하나있으면 그자리에 값을 출력해줄 데이터가 1개, %d가 두개있으면 데이터가 2개
  여기서 만약.... 음... 정수와 실수를 동시에 섞어서 쓸수있나요? 라고 물어본다면..
  가능해
  printf("%d / %d = %f\n",int,int,float); 이런식으로 사용이 가능하다는것이지
 
  출력문은 이것저것 많이 출력해보도록 하고.. 그리고 한가지 주의사항은
  %d로 출력할게 해놓고 float이나 double을 위치시키면...
  예)
  float a;
  printf("%d\n",a);
  이렇게... 그러면 아마 결과가 잘 나오진 않을거야 데이터타입떄 이야기했지? 우리가 int나 이런것을
  지정해주는 이유는 그것을 어떻게 표현해줄까~ 하고 결정하려하는것이라고. 어떻게 읽어들여올지
  그것을 지정하는것이기때문에... 데이터타입은 맞춰야해.
  그러나 %c와 int의 조합은 정상적인 출력이 가능(int가 char의 표현범위를 넘어서지만 않는다면)
  %d와 char의 조합도 가능(이경우는 글자가 출력이되는것이 아니라 해당 글자의 코드값이 출력된다오)
   %x는 어떤타입도 가능해. 이걸 직접 말로만 하려니까 힘드네.. 흠.....
  그리고 번외적인 이야기 하나 \n이란걸 쳤자나.. 이거는 무슨역할을 하냐하면...
  우리가 막 글을 쓰다가 엔터키를 치면 커서가 다음줄 젤 앞으로 이동하지?
  그리고 막 글을 또 쓰면 거기서부터 써지기시작할거고.
  화면에 출력한다는것은 프로그램이 화면에 글씨를 쓰는거야
  자... \n은 여기서 엔터키랑 같은 역할을 해. 한줄 넘겨서 새줄에 새로이 글자를 출력하려고할때
  \n이라는 printf에서의 엔터키를 같이써주는거지. \다음에 바로 오는 문자에 따라서 특수한 키의 역할을 하는일을 해줘(tab키,엔터키등등) 엔터키역할은 \n, tab키역할을 \t라고 써주는거지.
 그리고 한가지 더 있다면 \"도 있어 이것은 화면에 "를 출력해 주는 녀석이고. 만약 우리가 \ 라는 문자를 화면에 출력하고싶다면 \\ 로 써야하고... 이거는 그냥 한번 써봐 ^^
 궁금한건 질문- ㅎㅎㅎㅎㅎ (이거 강좌 맞아? ㅋㅋㅋㅋ)

 그리고나서 이제 입력을 보자. 입력은 우리가 컴퓨터한테 무언가를 알려주고싶을떄 사용하는것 ^^
 가장 많이쓰는 scanf를 보고 오늘 1부는 여기서 마무리 ㅋㅋㅋㅋ
  사용예제
  scanf("타입",&변수); 이렇게 기억해
  여기서 타입이라는것은 아까 위에서 본 %c,%d,%f정도만 기억해두자고 ㅋㅋ
  scanf는 내가 어떤값을 어떻게 받아들여서 이걸 변수에 저장할게- 하는거야
  그러면 내가 만약 정수값을 받고싶다면 int a라는 변수를 선언해두고
  scanf("%d",&a); 라고 써주는거지.
  그럼 내가 한번에 두개를 읽어오고싶다. 그러면 어떻게 읽어오면 될까?
   printf처럼.. 붙이면 된단다.
  scanf("%d%d",&a,&b); 이렇게 ^^
  단 여기서 주의할사항은 %d%d라고 쓰고.. printf때처럼 \n을 같이 넣어주면 예상치 못한 결과가
  나올수가 있으니까 주의하도록 하고 ^^
  scanf("%d%d\n",&a,&b)라고 하며는 우리가 a입력하고, b입력하고 엔터키를 쳐야 그것이 전부 인식이 되는걸로 떠. 그래서 엔터키를 두번 땅땅 떄려줘야하는.. 그런일이 생기지. 잊지말아야할것... scanf에서는 \n을 붙이지 않는다.
 그리고 또한가지 중요사항... 음.. 버그사항?
 만약 우리가 입력한값이 잘 안나왔어... 그러면 &가 붙었는지 아닌지 확인을 꼭 해보길 바래 ^^
 그리고 음... 입력받는 데이터 타입은 좀 맞춰야할거야..
  while(scanf("%d",&n) != EOF){
       printf("%d\n",n);
  }
  라는 코드가있어.. 이 코드가 하는 역할은 정수를 입력받으면 바로 출력을 해주는 구문인데...
  1 2 3 4 5 a 1 2 3 이라고 입력을 주면..
  이코드는 1,2,3,4,5,5,5,5,5... 이런식의 출력을 보여주게 될거야
  이 이유는 설명하기 조금 복잡한데...
  scanf해서 처음에 1을 입력받아 n에 저장하고 n을 출력 2를 입력받아 n에 저장하고 그걸출력 출력.. 잘 되가고있었어...  자 이번에 5가 입력되서 n에 저장하고 n을 출력했어... 그다음에 a가 입력되었지?
  근데 a는 n에 저장이 안되었어. 따라서 n은 5를 가지고 출력 (우선 입력은 있었으니까) 그리고 a는 날아가지않고 대기 버퍼에 잠시 들어가있어.. 그러면 scanf가 받아올 내용이 담긴 버퍼에는 a , 1 이렇게 남아있어..
 그러면 다시 또 a를 읽어버렸는데 안되니까 5가 다시한번더 출력... 그다음 입력이 또 들어왔는데 받아올 버퍼에는 a , 1, 2가 남아서 또 이 scanf가 a를 읽을라고 시도해... 계속 a를 읽을라고 시도하는일이 생긴단다.
  결국 치명적인 버그가 남게되는것이지. 음.. 이거는 굳이 이해하지 않아도 좋아.. 다만 내가 말해주고싶은것은
 데이터타입을 맞춰라~ 정수를 읽겠다고 했으면 정수를 입력시켜줘 문자넣지말고. 안그럼 뻑난다~
  오늘내용은 직접 이것저것 입력해보고 출력해보고 하면서 익힐것!
  그럼 이제 이어서 바로 오늘 막장강의 2부 시작할게
Posted by 모니터에습기찼어



Google