2016년 12월 26일 월요일

Day3

비트 논리 연산자
어째선지 교사가 이부분은 매우 빠르게 언급만 하고 지나갔습니다. 추측컨데 잘 쓰지 않는 기능이나, 알긴 알아야 하는 기능인거 같습니다.
기능을 들어는 봤다 와 전혀 모르는건 엄청난 치이가 맞더군요.
비트 : 2진수 표기법
입니다! 간단하죠? 비트논리연산자, 그러니깐 2진수를 이용한 논리 연산자입니다!

~ NOT, 10, 01이 되는 기적!
& AND 비교를 위한 두개의 비트가 1일때만 1이 출력
! OR 두 비트중 하나만 1이어도 1 출력
^ XOR 두개의 비트가 전혀 다를경우 1
10진수 논리 연산자랑 거업나 비슷합니다!
10진수에서 && 가 비트에선 & !! 키야 차암 쉽죠잉?
못보던 녀석을 주목하겠습니다.
XOR 입니다. 해석하자면 Exclusive OR 독특한 OR 입니다!
두 수를 비고해서 같지 않으면 1이 나오는 엉뚱한 친구입니다.
NOT AND OR 로 조합할 순 있겠지만, 쉽게하라고 지정해 줬으니 쓰는게 인지상정!

이건 예제 실습도 뛰어넘었네요. 덕분에 저도 더 이상 모르는;;
디음은
비트 시프트 연산자
이건 조금 자세히 다뤘기 때문에 서술을 해야할거 같습니다.
예를 들어 7이 있습니다. 이 숫자를 반으로 나눕니다. 3.5가 나오지만, 답답한 컴퓨터님 께서는, 특별히 지정해 주지 않는 이상 쿨하게 소숫점을 씹어먹습니다. => 3이 됩니다1
반대로 7을 곱해 봅니다. => 14가 나오는군요!
72진수화를 시킬 경우
0111 이 나오네요!
32진수 화 시키면
0011 !
142진수화 시키면
1110 이 됩니다!
14(10진수)
7
3
1110(2진수)
0111
0011

느끼실 수도 못느끼 실수도 있겠지만, 2진수의 자릿수를 땡겼습니다.
7의 배수로 갈때는 <← 왼쪽 방향으로 7을 나눌경우엔 →> 방향으로 말이죠!
잘 모를수도 있으니 조금 더 높은 값을 이용해 봅니다.
250 ← 50 ← 25 → 12 → 6 →
0110 0100 0011 0010 0001 1001 0000 1100 0000 0110

이제 패턴이 조금 보입니다.
왼쪽으로 2진수를 한 칸 밀때마다 2배가 되며, 오른쪽으로 한칸 밀 때 마다 ½ 배가 됩니다!

이게 바로 비트 시프트!
컴퓨터 용어로는 << >> 입니다.
연산자 의미
<< 왼쪽 시프트 연산자, a << b 일 경우 a값을 b 횟수만큼 배수 곱한다는 의미입니다.
>> 오른쪽 시프트 연산자, a >> b 일 경우 a값을 b 횟수만큼 나눠줍니다

배수만큼 값이 나눠지거나 증가할때 이 연산자를 응용하면 엄청 작업이 수월해 지더군요!

캐스트 연산자
캐스팅 하는거죠~ 마법의 주문을 외워주는겁니다! 어따다? 다른 데이터 타입끼리 계산할때!
예를들어 평균을 구하기 위해서는 우리는 실수부분도 나와야 되겠죠? 하지만 점수는 보통 정수로만 나오고요,


이런경우에 캐스팅을 하는데 5 라인에서 (float) 라고 적어져 있습니다. 이게 캐스팅을 한다는 뜻 입니다. Int 형의 a 와 b를 float로 인식시켜서 계산하는거죠!
이렇게 케스팅 없이 두가지 다른 데이터 타입을 연산할 경우, 오류 혹은 미친값이 나옵니다!
답은 아마 41.5555555 와 비슷하게 나올것 입니다.
소숫점이 굉장히 나오네요! 이런 지저분한것들이 싫다면 6번 라인에서 %f 사이에 숫자들을 몇개 넣으면 되요!
%2.2f 처럼 말이죠!
앞의 숫자는 정수형 부분은 최대 몇자가 나올지, 뒤의 숫자는 소숫점은 몇자까지 나올지 정하는 방법이랍니다~
이렇게 값을 바꾸어 나타내면 결과는 41.55 로 깨끗하게 보여질것 입니다! 

2016년 12월 25일 일요일

[C basic] day2

연산자의 종류
연산자의 종류도 다양한데, 우선적으로 사용할 것부터 알고 넘어갑니다.
증감연산자
기본적으로 사칙연산을 위한 연산자 + - * / 가 있고, 또 %가 있습니다. 전자는 누구나 다 알지만 %는 해깐해깐 할 건데요, %는 나눈 8%3 은 8을 3으로 나눈뒤 남은값인 2가 나오게 되는거죠.
그다음 특히 c는 반복하는것을 무진장 싫어한다고 합니다. 예를들어 8+1+1 따위 말이죠,
일반인도 싫기는 매 한가지겠지만..
이럴때 우리는 증가/감산 연산자를 이용합니다. ++ 나 -- 를 사용합니다. 8+1 을 8++ 나 ++8 따위로 적을수 있겠습니다, 연산자가 앞과 뒤에 붙는 차이는 계산의 순서입니다.
다 예상되겠지만 9번 줄은 좀 이상합니다.
분명 계산대로라면 5가 나와야 하지만 값은 4로 뜨더군요.
이유는 이러합니다. 컴퓨터는 단순하게 적힌순서대로 읽는것 이었습니다.
printf 응 먼저 읽은뒤, 출력하라는것을 인식합니다. 이후 따옴표 안의 %d 를 읽것이고, %d 형 그러니깐 10진수 형태로 출력을 한다 는 뜻임을 알게됩니다, 그럼 무엇을 읽는가? 에 대해서는 그 뒤의 콤마 뒤를 읽게 되는데요, a 가 앞에 있기때문에, 우리 성급하신 콤푸타님꼐서는 다짜고짜 a를 출력하는것입니다. 하지만 일단 문법상 오류가 없는 이상은 글을 끝까지 읽을것이며, 출력한 뒤에는 a 위의 ++ 를 읽게 됩니다. 그리고 뒤늦게 값을 바꾸게 되고, 우리는 출력은 4로 떠있지만 값은 5가 되어있는 사태를 마주하게 됩니다.
이를 확인 하기위해 10번 라인에 다시 printf("%d",a); 를 찍게되면 5가 나옴을 알수 있어요.
비교연산자
비교를 위한 연산자 입니다. < 와 >, ==와 != <= 와 >= 입니다.
일반적인 교육을 받은 우리들은 쉽게 알수 있습니다.
수학이랑 똑같거나 비슷한게 많네요!
>= 를 붙혀쓸 방법이 없기때문에 그대로 쓰는거에요. 근데 반대로는 =< 인가? 하실탠데, 그럼 =(대입한다)<(비교) 가 되기에 꼬여버리고 오유를 토해냅니다! 비교 연산자 먼저, 대입연산자 다음 입니다! <= 이나 >= 같이 말이죠!.
또 수학에서는 a=b 라고 쓰지만 콤퓨타는 이렇게 쓰면 a에 b를 넣는다! 가 되어버리기 때문에 는 이 두개 들어갑니다! a==b 이렇게 말이죠!
컴퓨터에서 Not 은 ! 이기때문에, 같지 않다는 != 로 쓰여요.
간단하지만 잘 쓰이더군요.
또 하다보니 알게 된건데, a+b=c; 이런방식도 수학에서 쓰였지만, 이러면 컴퓨터가 멘붕을 합디다.
대입할 대상을 항상 좌측에다가 쓰는게 오류를 안보는 가장 간단한 방법이더군요!
c=a+b; 처럼 말이죠!

논리연산자
쉽습니다! 몇개 없기도 하구요!.
논리 연산자는 AND OR NOT 이 있으며, 이 새개를 응용해서 몇가지 더 있습니다만, 기초는 이것들 뿐이네요!.
A AND B = A와 B
A OR B = A혹은 B
NOT A = A가 아님
뜻은 이렇구요,

AND 는 && 로 씁니다.
OR은 || 로 쓰며,
NOT은 바로 위에 언급되었지만 ! 입니다.

위 조건들이 맞으면 값은 1이 나오고, 아닐경우 0 이 나옵니다.
여기서 조금 거시기 한게, C 에서는 맞을때의 값이 항상 1이 아닙니다. 틀릴떄는 항상 0인반면, 그 이외의 값은 다 true가 됩니다.
C 이후 프로그래밍 언어에서는 통일되어 true 는 false 는 0 으로 바뀌었다고 합니다.
하지만 C는 그지같으니. C를 배울떄 만큼은 유념해 둬야 할 상황 같습니다.



요놈을 보면 우리가 입력하는 num1 과 num2 로 비교를 해본 녀석입니다.
예를 들어 두 값을 순서대로 1 ,20 을 써봅니다.
8번 라인을 해석해보면 num4는 1<20 이고 1<10 이다.
논리적으로 다 맞는 말 이기때문에, 값은 1이 나옵니다!

10번 라인을 보도록 하죠! 
num4는 1<20 이거나 1 < 10 이다.
역시 맞네요! 답은 1이 나옵니다!.

만약 값을 9와 1로 쓴다면?
8번 라인은 num4는 9<1 이고 9<10 이다. 뒤에껀 맞는데 앞은 틀렸네요, AND 연산자 이기때문에, 두개다 맞아야 합니다. 이런 경우는 num4=0 이 됩니다!.
10번 라인은 num4는 9<1 이거나 9<10 이다.
OR 비교 연산자 이기때문에, 전자는 틀렸어도 후자는 맞기 때문에 1이 나옵니다!

쉽죠?
마치기전에 예외사항이 있습니다.
컴퓨터는 코드를 순서대로 읽는다고 말 했었습니다. 그렇기 때문에 OR 연산자에서, 첫번째 비교 값이 True 일 경우 후자를 아예 읽지 않는 사태가 발생합니다.
언제 이런걸 쓸지는 모르겠다만, OR 의 후자에서 값이 변하는 경우에는 이게 문제를 유발할 수 있다는것을 유의해야 할거 같습니다.

day5까지 진도가 나갔지만, 도저히 이걸 쓰고있을 시간이 없기때문에 걱정입니다. 미칠듯한 과제폭풍..

2016년 12월 20일 화요일

[C basic] day1

2개월 반 정도의 기간동안 단기로 C 와, Java, 그리고 알고리즘을 배우게 되었습니다.
교사의 조언에 따라 배운 내용을 시간을 틈틈히 내어 작성하는 버릇을 가져보기로 했습니다.
3개월이라는 비교적 상당히 짧은시간 덕분인지 이틀간 진도가 미친듯이 나아갔기 때문에 상당히 조급합니다;;
그리고 작성자는 자극히 프로그래밍에 정보도 생각도 부족한 모자란놈 입니다. 아래에 나오게될 정보의 신빙성 혹은 코드의 완벽한 작동을 보장하지 않습니다. 그리고 이 모든 블로그에 올라오는 코맨트에 대해서는 가능한 한 토론 형식으로 답변을 달 생각입니다만, 코맨트의 수준에 따라 제가 답을 하지 못할 가능성, 답변이 늦을 가능성이 있음을 알려드리고 싶습니다.

우선, 조언에 따라 최대한 비쥬얼 베이직과 사용하는 언어는 영어를 이용하려고 노력합니다. 그렇기 때문에, 바쁘지 않다는 가정하에, 영어로 작성이 될 수 도 있다고 봅니다.

첫날은 솔직히 배운것 보다는 설명을 많이 들었는데, 이중 옮겨 적을만한 것들을 남겨봅니다.

C는 40년이 넘은 오래된 언어인데, 이놈을 아직까지 배워야 하는 이유는 단순하게도, 현제 사용되는 모든 언어의 기초는 C에서 파생되었기 떄문이라고 합니다. 기본적으로 대부분의 기능들과 작동원리는 비슷하기 때문에, C를 배우면 이후 언어들은 바뀐 몇가지 점들과 추가된 것들만 배운다면 된다고 합니다. 프로그램의 빌드 순서는 이러하다고 합니다.

인간이 알아먹을수 있는 고급언어를 기계가 알아먹을수 있는 기계언어로 변환하여, 작동을 합니다. 프로그래머가 작성하는 헤더파일 과 cpp 파일이며, 비쥬얼베이직을 통해서 컴파일을 해서, 목적파일인 obj 파일로 변환을 합니다.
이후, 목적파일과 라이브러리를 참조(linker)한뒤, exe로 만들어 실행을 합니다. 프로그램을 실행할때 나오는 에러는 이때 컴파일과 링커 단계에서 나타나게 되는데, 대부분 컴파일 단계에서 오류는 typo이며, 낮은 확률로 논리오류 등도 해당합니다. typo를 해결하여 정상작동을 하거나, 후발단계인 linker에서 나타난 애러의 대부분은 논리적으로 따질때 오류가 있거나, 혹메모리 할당 오류가 대부분을 차지하며, 가끔 typo문제가 다시 나타날 때도 있습니다.

.c 파일의 제일 기초적인 구조는 이럴것 입니다.

#include 는 이 파일에 include 합니다, <stdio.h>stdio라고 하는 헤더 파일을.
보다싶이 특정해주는 파일을 참조하게 만드는 것이며, 아무것도 없는 백지 상태에서는 우리가 쓰는 고급언어를 아무리 이쁘게 휘갈겨 써넣어도, 기계어는 번역을 시도 할수조차 없습니다. 그렇기 때문에, 미리우리가 쓰는 고급용어로 기계어를 번역해둔 이른바 도서관(library)을 불러와끼고 번역을 하라고 지정해 주는것 입니다.
C에서 주로 쓰게될 stdio.h 는 Standard Input Output 의 약자로 기본 입출력 전반에 대하여 적혀진 매우 필수적인 라이브러리가 됩니다.
이런것들을 선처리분 라고 부르게 되며,
선처리부는 방금 서술된 것 말고도 몇가지를 더 이용 할 수 있는데,
1.방금 기술되었던 Header file 을 불러올수 있고,
2.전역함수
3.메크로
4.사용자 정의 지정 함수
5.사용자 정의 지정 데이터 파일
가 되시겠습니다.
뭔 개소리인지는 추후 서술해 볼것(잊어먹지 않는다면)입니다. 우리가 명심할것은 그저 이것뿐, 작성전에 이 파일에 대한 환경설정을 미리 짜두는 곳 정도로 보면 됩니다.

전역함수 다음 나타나는 void main() 입니다. 이것은스타트 포인트 라고 생각하시면 됩니다.
해당 프로잭트의가장 처음 출발지점입니다. 그렇기 때문에, 이것은 단 한번 사용하게 됩니다.
다른 .c 파일을만들어도 main함수는 단 한번만 선언합니다. 앞의 void 는 비어있다의 의미로, 모든 형식을 집어넣을수 있는 공간을 의미합니다. 이 출발지점의 시작과 끝을 중괄호로 나타냅니다.

더 들어가기 앞서 상수와 변수에 대해 적어봅니다.
정식교육중 나왔던 수학적의미인 상수와 변수로 생각하면 되지만,

데이터타입에 대해서.

데이터타입은 기본형, 유도형으로 대분류가 되며, 중분류로 기본형 에서는 정수형, 문자형, 실수형, void형 네가지가 있습니다.

 기본형  
  • 정수형 : 일반적인 정수형 숫자 1, 100 ,-100, -1 따위
  • 문자형 : 말 그대로 문자 a, B, ccC, ㅁ, 아 따위
  • 실수형 : 소숫점이 있는 숫자 1.1, -1.1111111 따위
  • void형 : 타입이 정해져있지 않은 자료들
요기다가 각 데이터 타입마다 소분류로 나눠지는데, 이중 요즈음 쓰는것들을 나눈다면
 기본형  
  • 정수형 : int, long
  • 문자형 : char
  • 실수형 :float, double 
정도가 있다고 합니다.
각 타입별로 지원하는 크기와 범위또한 다양한데요.
int 는 4바이트 long int 4이상 char 1바이트(최신언어 대부분은 2바이트를지원), float 4바이트 double는 8바이트,
멘붕이 올건데 간단하게: int ,char, double 정도만 알고있고, 나머지는 필요할때마다 확인해서 쓰는정도면 될거 같습니다.
각 타입별로 범위는 정말 쓰기 싫을정도로 미친듯한 숫자들이 나오더군요.
int는 -128~127 까지라던가 같이 말이죠,
이것들은 틈틈히 책을 보고 알아내면 된다고 생각하지만, 우선적으로 이게 다 무슨뜻이고 왜 하냐는게 저에겐 가장 큰 의문이었습니다.

가장 큰 이유는 최적화...였습니다.
말인즉슨 : c로 프로그래밍하던 예전에는 요즘처럼 어마무시하게 행복한 수준의 램을 보유하고 있지 않았습니다. 그런이유로 램의 꼼꼼한 활용에 따라 작동중지에서부터 사양감소 등의큰 온도차가 존재했었습니다.
가령 우리가 a 라는 문자를 프로그램에 저장하게 되었습니다, 그냥 저장해라고 쓴다고 프로그램에 저장되는것이 아닌, 우리는 램에 우선적으로 할당을 해야합니다.  그렇기 위해서는 우선 빈 박스를 프로그램의 시작 당시에 램의 빈 자리에다가 던져놓습니다. 자리를 찜해둔거죠. 이후 프로그램이 작동하면서 아까 던져논 상자에 a를 던져놓고, 필요에따라 꺼내쓸수 있게 됩니다.
처음에 우리가 쓸쑤있는 램이라는 방은 한평짜리였고, 프로그램을 돌리기위해서는 더 많은 상자들이 요구되었습니다. 그렇기에 우리는 한평수준의 큰 상자에 a 따위의 작은 값을 넣는 낭배 대신, a에 맞게 작은 수를 넣을 상자를 깍아서 넣기 시작했습니다.
이것이 데이터 타입입니다.
지금은 램이라는 방이 4기가~32기가 정도의 어마무시한 수준의 넓은 방을 얻게 되었기 때문에, 엄청 작은 수를 보관하는 short같은것을 사용할 이유가 없어졌습니다.
하지만 이것또한 쌓이고 쌓이다보면 최적화가 부족한 영향이 생길수도 있는법입니다. 그렇기 때문에 우리는 int와 double만 쓰지않고 다른 타입도 있다는것을 알고, 필요에 따라 사용할 수는 있어야 합니다.

이제 데이터타입의 사용처를 알게되었습니다. 우리가 프로그래밍을 하며 만드는 값들을 (일시적이든 영구적이든) 저장하기 위한 공간을 마련하는 행위가 되시겠습니다. 만약 올바른 상자에 넣지 않는다면, 값은 미쳐버리거나, 렌덤한 값이 들어가는(결과적으로 모든값이 바뀌어 버리는 대참사 따위의) 악몽이 일어날수 있기때문에, 중요한 부분이라고 합니다.


3번과 4번 라인을 보면 int형식의 상자를 하나 만들어 상자에 1을 넣는 행위를 실행한 내용입니다.

앞서 장황하게 설명했지만, 작성은 매우 간단했습니다.
응용하여 우리는 5번 라인처럼 선언과 초기화를 동시에 할 수 있습니다.
여기서 초기화는 우리가 아는 초기화의 뜻과는 살짝 다릅니다. 램에서 빈 공간에 상자를 던졌는데, 그 공간에 임의의 값이 들어가 있는 경우따위가 있고, 경우에따라 상자가 비어있는 상태로 프로그래밍을 할때 문제를 일으킬 때도 있습니다.
그렇기 때문에 반드시 초기화를 할 필요는 없지만, 필요에따라 초기화를 해야만 할 상황도 찾아옵니다.
6번 라인처럼 2개이상을 선언도 가능하며
7번처럼 2개 이상을 선언/초기화도 가능합니다.
8번라인을 보다싶이 다른 형식도 쉽게 만들수 있습니다.

이번 코드에서는 아까보지 못하고 설명이없던 ; 와 //가 있습니다.
각 명령어를 끝냈을때 우리는 그 명령어가 끝이라는 신호로 ; 를 써주게 됩니다.
세미콜론 ; 이 없다는것은 이 줄의 명령어가 끝이나지 않은것으로 컴퓨터는 간주하기 때문에, 이는 곧 오류를 일으키는 가장 흔한 요인중 하나가 된답니다.
// 는 주석입니다. // 의 뒤에있는 모든 글, 명령어는 무효화 됩니다.
몇가지 라인을 모조리 주석을 치는 방법은 /*로 시작해서 */ 로 끝을 내는 방법입니다.

주석을 이용하는 이유는 길고 긴 코딩자료를 혼자서 작업하는도중, 다시 수정 혹은 찾아야할때, 멘붕을 덜하거나, 타인이 내가 만든 작업물을 봐야할때, 찢어버리고 싶은 강력한 충동을(그러니깐 짜르고싶은 충동을) 막기 위한 노트입니다.
이것은 개발자 본인과 동료를 위한기능이기때문에 본인의 의도를 주석으로 잘 표현하는것이 좋은 코더가 되는 길중 하나라고 합니다. 왜냐하면 아무리 고수라고 해도 코딩을 혼자 다하고 끝까지 책임지는 경우는 없다시피 하기 때문입니다.


이제 데이터 자료형을 이용해 값을 저장했으니, 불러오는 방법을 알아야 할 차례일것 입니다.
화면에 출력하는 방법은 몇가지가 있는데,여기서는 단순하게 콘솔창에서 뽑는방법으로 할것인가봅니다.

3라인에서 int형a를 선언후 1로 초기화 했습니다.
이 1을 확인하는방법은
4번라인의 printf 명령어를 이용하는것 입니다.
printf( 출력합니다. "a is%d" 라고 출력합니다. 이때 %d 는 a 를 참조합니다 );
로 풀이할수 있는데요, %d 는 표준 문자열 출력 방식입니다.
말이 또 빈혈 일으키게 생겼는데, 간단하게 d방식으로 문자를 출력한다 입니다.
그럼 방식은 무엇이 있는가? 하면 많습니다...겁나 많아요 자료형만큼 많지만, 1장과 2장(예상)에서 주로 사용하는 몇가지만 소개합니다.

%c %s %d %f
c는 문자 즉 a 나 B 따위의 단일 문자
s는 문자열 즉 asd 나 AsD 따위의 문자열
d는 10진수 형식 정수 즉 1 -10 따위의 정수
f는 소숫점 즉 1.2345 따위의 소수

다시 4번 라인을 쳐다보면 이제 읽어지길 :
a is %d 를 출력하는데, %d에다가 a에 선언된 값을 대입한다
로 풀이합니다.
위에서 우리는 a를 선언했습니다. 3번라인에서 1로 말이죠,
출력을 하면 우리는 a is 1 이라는 결과를 보게 됩니다!
와우! 그럼 6번 7번 라인도 봅니다.
똑같은데 소숫점 방식일 뿐이라는것을 알수 있습니다.
출력을 하면 우리는 b is 1.2345 가 나오는것을 볼수 있습니다!

이렇게 기본적인 작동방식을 겉핥기로 읽어갔습니다. 2장은 배우느라 피똥쌌는데, 이걸 정리할 생각을 하니 벌써부터 눈물이 나네요..