1.단순 출력문인 printf와 형식지정자가 들어가있는 printf의 차이
printf는 기본적으로 ""사이에 있는 문자열을 출력하는 일 밖에 안하는데, 형식지정자가 들어가게 되는 printf는 선언한 변수도 같이 들어가게된다.다시 말해서 형식지정자가 들어가있으면 그거에 맞는 숫자(혹은 다른 자료형) 변수를 넣어줘야된다.그리고 형식지정자 수만큼 변수의 수도 늘어나며, 순서도 통일시켜줘야한다.이건 printf나 scanf나 똑같은 규칙임.
2.sacnf가 실행되면 사용자의 입력이 들어올 때까지는 실행이 안되고 코드가 계속 멈춰있다.입력을 해야 다음 줄이 실행된다.(컴퓨터는 우리가 무슨 값을 입력할 지 모르기에 기다릴 수 밖에 없는 당연한 이유)
scanf는 큰따옴표 안에 형식지정자 밖에 없다.(입력할 값의 자료형 관련된 걸 입력하면됨)
scanf는 문구 같은거 없고 형식지정자 설정해주면 사용자가 입력한 그 값을 오른쪽 변수에다가 넣어주는 것 밖에 안하는 역할이다.
scanf를 호출 -> 커서 깜빡 -> 사용자가 입력 -> 입력값이 오른쪽 변수에 들어감(컴이 입력했구나 내가 이걸 어디에 넣지?하고 생각했을때 엔드연산자를 참고) -> 이 변수에 입력값을 넣어줘라 라는 명령 작동 -> 함수가 작동
3.&(엔드연산자)
=변수의 주소값
프로그램을 짤 때 변수들을 선언하면서 컴퓨터 램으로부터 메모리를 빌려온다.이진수 밖에 모르는 컴퓨터는 램에서 이진수로 기록을 하는데 변수를 선언해서 가져오고싶으면 선언한 변수의 자료형 만큼 기록지를 메모리공간으로부터 때준다.결국은 빌려주는건데 빌려준 메모리의 위치가 있을것이고 우리는 언제든지 거기를 다시 찾아갈 수 있어야한다.
엔드연산자가 붙냐 안붙냐의 차이?
변수를 선언하고 호출할때도 이름만 때오는데 이때, 엔드연산자가 없는 이유는 이름 자체가 주소값처럼 쓰이기 때문이다. 이런 상황에서는 우리가 빌려온 메모리의 주소를 정확히 몰라도 되는 이유는 메모리는 내가 관리하는게 아니라 컴퓨터가 관리하기에 굳이 신경쓸 필요는 없다.이름만 말해도 컴퓨터가 대략 알아듣고 그걸 호출 시키는 것이다.(택시를 잡고 어디지역의 레미안 아파트를 말하면 정확한 주소를 몰라도 데려다주는것과 같다.)
여튼 내가 접근은 할 수 있어야되니깐 이름이란걸 저장해놓은 것(이것도 실제로 주소가 존재하긴함) -> 평소에는 주소가 아닌 이름으로만 우리가 접근을 한다.
근데 왜 scanf에는 주소값이 필요할까?
우리가 선언한 변수 즉,프로그래머가 만든 변수는 사실 컴퓨터 상에 1개가 아니다.왜냐면 컴퓨터에선 많은 프로그램이 돌아가고 그 속엔 동일명의 변수들이 프로그램마다 있다.
이 상황에서 이름만 말하고 내가 입력한 값을 그 이름의 메모리 공간으로 보내달라하면 컴퓨터 입장에선 어디 지역의 레미안 아파트를 말안해주고 레미안아파트로 보내라는 말을 들은것과 똑같아지는 것이다. 정리하자면 우리가 값을 컴퓨터한테 입력해줄때는 정확한 메모리 주소를 붙여서 알려줘야한다.
C언어에서 이러한 이유로 그 변수의 정확한 주소값을 가져오는 장치를 만들었는데 그게 바로 엔드연산자이다.
주소값 : 메모리 어느 공간에 저장되어있어?라는 뜻
근데 주소면 주소지 왜 주소값이라 부르냐?
상수값이 변하지않는 수의 값이라고 생각할 때,주소값도 알고보면 숫자의 조합임
16진수로 알파벳+숫자 조합으로 되어있음 그래서 값이라고 부르는 것
주의할 점 : 주소값에 데이터가 들어가는게 절대 아님!!! 말할때는 주소값에 해당하는 그 변수에 넣어준다고 말해야 됨.
그리고 이름만 넣으면 그 이름 속 데이터 값을 주소로 받고 잘못된 주소인 거기로 들어가서 비정상적으로 동작함.
내가 오해하고 있는 점 : 형식지정자에는 값이 들어가는게 아니다.얘는 그저 자료형(선언한 변수의 자료형)을 설정해주는 역할만 하는 애일뿐 값은 옆에 변수로 들어가는거야
(형식지정자 : 형식을 지정해주는 애 이것 외 아무것도 아님)
참고사항 : c++에선 &가 다른문법으로 쓰임.
4.printf와 scanf의 띄어쓰기 규칙
scanf에 입력값을 2번 눌러야될 때 방법이 scanf 2줄로 하나하나씩 하는 방법이 있고,scanf 하나에 형식지정자 2개, &변수 2개 써주는 방법이 있는데
scanf("%d %d", &num1, &num2)
이때 형식지정자들 사이에는 쉼표없이 띄어쓰기만 처리했고,변수들은 쉽표처리만 했음
-> scanf에서 형식지정자는 ,를 쓰지않는다! 형식지정자만 필요하기에 다른 기호가 필요없는건데 그럼 띄어쓰기를 해준 이유는 형식지정자들끼리 구분은 해야되니깐 띄어쓰기를 해준 것이다.(붙여썻을때를 상상하면된다. -> 5와3을 입력하고싶은데 붙이면 입력할때 53을 입력하고 컴퓨터는 53을 하나의 값으로 알아들어버림 그래서 띄어쓰기가 필요한 것)
-> 변수들끼리는 쉽표 처리해준 이유
형식지정자와 순서와짝을 맞춰야된다고 했으니 목록화를 위해 쉼표가 필요한 것
이때, 띄어쓰기는 붙히든지 띄든지 상관없다.
-> printf는 ""안에 문자를 그대로 출력하는애이기 때문에 쉽표를 써도 상관없다
5,3이나 5 3이나 보는 입장에선 같음
5.보통 메모리공간을 말할 때 메모리공간 하나가 1바이트인지? 1비트인지?
1비트. 근데,변수든 자료형이든 무조건 한칸씩 먹는게 아니다. 자료형 중 정수형 보면 short는 2바이트 int는 4바이트 long long이 8바이트임 이걸 비트로 바꾸면 short는 16비트 int는 32비트 long long이 64비트임 이렇게 다 다름.그리고 대부분 비트가 아니라 바이트 단위로 차지하는 영역을 표시한다.(문자 하나 당 8비트(1바이트) 차지)
6.printf는 문자열로 받는 함수긴 한데, 문자''도 받을 수 있다. 어차피 문자열이라는게 문자가 모인거니깐 문자열을 찍을 수 잇으면 문자를 여러번 찍는 것과 같다는 로직이 성립함."5"도 가능 문자가 하나 이상이 있으면 문자열 성립해서 큰따옴표나 따옴표 차이가 없음.
그럴거면 문자열하고 문자는 왜 구분해놓은거지?
문자열 일부 한 문자를 수정할 때 도 그문자를 따로 지정해서 코드를 칠 때가 있어서 문자도 따로 설정해준 것
결론 : 문자와 문자열이 단위를 쪼개놓은 것 뿐,다르게 써야되는 그런건 아니다.
다만, 형식지정자를 쓸 때는 문자열과 문자 구분을 정확히 해줘야된다.안그러면 이상한 값이 나옴. 변수명이 test같은 문자열이면 %s를 써야되고 t같은 문자면 %c를 써야됨!!!
-변수값을 출력하고 싶을 때, printf에 고정된 값이 아닌 입력값에 따른 여러가지 결과를 위해 형식 제어 문자열과 변수를 이용한 printf와 scanf를 쓰는게 맞는지 ?
-형식제어문자열과 변수를 이용하는 이유는 한 코드에 여러가지 인수를 입력해도 일정한 동작이 구현할 수 있게 하기위해서인지?
-> 저말도 맞지만 무조건 저 한가지의목적을 위해서 쓰는게 아님.얘넨 여러군대에 쓰일 수 있는 도구다.printf만 쓸 수 있는것 아닌가? 입력만 받을 수 있는거 아닌가?
딱 한가지 용도로 쓰이는 거라고 정의하면 안되고,러프하게
"printf는 화면에 뭔갈 출력하기 위해 쓰는애다"라고만 알고 있어야 됨
지금 예시가 단순하고 쉬워서 그렇지 일정한 동작도 무조건 구현되는게 아니라 if문 같은 조건문에선 조건에 따라(홀수냐 짝수냐) 써야되는 코드가 달라지는 경우가 있음 이럴땐 일정한 동작이 아닌 다른 동작이 일어남.(세분화 기능이 많음)
다시말하지만, 형식제어자의 원래 목적은 내가 입력받고자하거나 출력받고자하는애의 자료형을 표기하기위해서 존재하는 애다.
8.코드가 실행될 때마다 즉 프로그램이 실행될 때마다 우리가 쓴 코드에서 필요한 메모리를 빌려오는 것(메모리가 부족하면 컴퓨터가 오류메세지를 띄우면서 꺼버림)
9.내가 오해하고 있는 점 : 값은 변수 안에 있을 때만 쓰일 수 있다?(x)
-> 아마 내가 본 건 그냥 상수만 코드로 쳤을때 안되니 변수 안에 대입해서 써줘야된단 말을 잘못 오해한 것 같음. 함수쓸 때 매게변수 값에 상수만 들어갈 수도 있음!
상수는 주도적으로 못쓴다.
10.함수에 변수를 넣어줄 때 이게 마치 요리란 함수에 재료란 변수를 넣어주는 것처럼 보이지만 그게 아니라 똑같은 변수를 복사해서 넣어주는 것이다.무슨 말이냐면 내가 함수에다가 변수를 넣는다고 변수 선언했던 값이 변하진않음.(=재료가 사라지진않는다.)
num1이라는 변수를 A함수에 넣은 코드가 있고,num1이라는 변수를 B함수에 넣었을때 이 변수들이 똑같은 애들(or 똑같은 재료)이 아니라 복사해서 넣어준 것임 값은 같지만 존재는 다른 느낌!
상수는 함수에 넣으면 재활용 못하고 그냥 거기서 끝임
다른 함수에서 같은 상수 넣으면 그건 재활용한거 아니냐? 그건 다른 존재다.
11.주소값을 알고 싶을때 쓰는 형식지정자 : %p
12.우리가 변수 선언을 하면 동작하는 과정이 해당 변수의 주소의 메모리로 컴퓨터가 가서 자료형 변수명이 적힌 포스트잇을 붙힌다.다 쓰면 포스트잇을 때버린다.-> 프로그램이 끝나면 메모리가 반납이 된다.
만약 프로그램이 안꺼지면 그건 메모리가 없어서 안꺼지는 것
13.상수의 종류 : 실수 상수, 정수 상수, 문자 상수, 문자열 상수 등이 있음
이 말은 곧 변수 뿐만 아니라 자료형에 따라 상수도 존재할 수 있다는 것임
내가 int형 변수를 선언할 땐 정수 상수만 들어갈 수 있음!
이름 있는 상수 = 기호 상수
14.서로 다른 자료형끼리 넣고 받을려면 정상적으로 안들어간다.그래서자료형이란게존재함
여기서 정수형 변수에 실수값을 넣고 실수형 변수에 정수값을 넣는게 안된다 이건 X
기능적으론 동작하지만 정상적인 값이 들어가진 않는다.
(예로 들어 정수형 변수에 실수값을 넣으면 소수점 이하로의 숫자를 다 자르고 그냥 정수값만 들어간다.현직자들이 코드스킬로 이렇게 쓰기도 한다.내가 실수값에서 정수만 쓰고싶어 그럴땐 저렇게 쓰는 사람도 있음)
15.프로그래밍의 실수는 부동소수점을 쓴다.
부호가 있다는건 음의정수,0,양의정수를 포함한다는 뜻
unsigned를 붙히는 순간 부호가 없는 애가 나온다.(결국 양수)
-> 이걸 굳이 나눈 이유?
크기가 다르기 때문!
범위를 보면 short보다 unsigned short는 음의 정수가 없는 만큼 양의 정수의 표현 크기를 더 쓰게 해줄 수 있음!그래서 이걸 쓰는 것
옛날에는 컴퓨터 메모리가 적어서 메모리를 아낄려고 cd난 플로피디스크에 이런거를 정 해서 메모리를 확보했던 것
지금은 메모리를 아낄 수 있는 용도보단 음의정수를 안쓰게끔 강제할 수 있어서 쓰는게 더 크다.(예로들어 -가 없는 자동차 속도같은 변수들의 값을 쓸 때)
요즘은 long 말고 long long(8바이트)를 씀
long long은 코드에 칠때 특별하게 띄어쓰기가 가능함
정수형에서도 각자 표현할 수 있는 범위가 있는데
쇼트는 -3만 2천대에서부터 3만 2천대까지 커버가 가능하고(여기서 넘는 숫자를 입력 하면 오버플로우나 언더플로우가 생기는 것)
인트는 -21억대에서 21억대까지 커버 가능
여기서 범위 숫자를 외우기보다는 각 자료형 바이트 크기를 외우는게 중요하다!
보통은 돈을 다루지않는 이상은 21억 넘는 숫자를 쓸 일이 별로 없어 int를 많이 씀
(아니면 억 단위를 없앨때도 있음)
long은 int랑 차이없는 4바이트 그래서 안씀
문자형인데 문자형 및 정수라고 표현하는 이유?
캐릭터형도 정수가 들어갈 수 있는데 그럼 들어가면 앞처럼 안맞는거아니냐 생각할 수 있지만 들어갈 수 있다.사실 문자형 변수는 숫자랑 문자를 일대일 대응시켜준 것과 같기 때문이다.그게 바로 아스키코드(숫자에 대응되는 문자를 만들어놓음 숫자를 넣어놓으면 문자가 대신 찍힘 대신 영어문자 몇가지(알파벳,특수기호 등)만 대응해놓은거임)
char num1 = 'A';
printf("%c", num1);
이렇게 치면 A에 대응되는 값인 65가 출력됨
만약 변수를
char num1 = 'A'+1;로 하면 66이 출력됨
16.고정소수점 : 우리가 보통 쓰는 고정되어있는 소수들
부동소수점 : 실수를 표현하는 방식이 다름 지수부,가수부,정수부로 나누고 소수점 범 위를 따로 표기함
지금 알아야할 것은 우리는 실수형 자료형을 부동소수점의 float(4바이트)과 double(8바이트)로 이용한다
얘네의 범위는 정수형과 범위가 다르기보다는 소수점 몇째자리까지 커버할 수 있냐가 다르다.float은 소수점 넷째자리까지 유효한걸로 침 double은 소수점 8~12자리까지
이거 두개를 잘 선택해야된다 플롯같은 경우는 오차가 있고 더블 같은 경우는 정밀성은 높지만 메모리 점유 용량이 큰게 문제 즉 내가 오차와 메모리 용량 이 2개를 각자 더 중요시하는걸 골라 그에 따라 2개중 하나를 쓰면된다.(현업에서 플롯쓰면 오차가 난다는 사실을 알고있어야지 일을 할 수 있음. 즉 회사분야가 오차에 민감한 곳인지에 따라 다름)
17.키워드 : c언어에서 고유한 의미를 가지고 있는 특별한 단어(=예약어)
자료형이나 sizeof같은 것 - 굳이 다 외울 필요없음
18.초기화할 때 0말고 원래 넣을 값있으면 그걸로 초기화해도 상관없다.
19.변수를 지금은 함수 중간에도 선언할 수 있다!!!(함수앞에만 XXXX)
20.현직에 가서도 종종 이해안가는 코드,이상한 코드 이런것들이 보일 때가 있는데 이런거에 의도만 파악하고 너무 신경쓰지말기 왜 그렇게했는지 너무 집착하지말고 그냥 있나보다생각하자!
21.sizeof 스탠다드 제공함수로서 자료형 크기를 알려주는 함수다.변수의 자료형 크기도 알려준다!
22.int형 자료형 범위 중 경우의수 범위
중요한건 int형은 4바이트고 +21억 -21억을 커버하는 것 -> 암기해야될 것
아래건 외울 필욘없고 규칙일뿐
Int형은 32비트 즉 메모리공간이 32칸이 있고 비트는 이 한 칸당 0과1밖에 못들어간다.
즉 한 비트에 두가지의 경우의수가 들어가면서 32비트의 총 경우의수는 2를 32번 곱하는걸로 2^32으로 나타낼 수 있음.근데 예시에 왜 31승으로 되어있냐?
-2^31,...,-2,-1,0,1,2,...,2^31-1
이건 바로 부호비트 때문이다. 부호비트는 이 이진수들이 나타내는 값들도 음수 아니면 정수로 구분이 되어있을탠데 그걸 구분하기 위해서 맨 앞에 비트칸에 들어가는 경우의 수 2개는 부호(+:1 -:0)로 취급하고 갯수에서 제외시키는 것이다.
22222*..... 이렇게 32번 곱하는 수식에서 맨 앞 2를 빼니깐 31승이 되는 것임
근데 왜 오른쪽 정수 쪽에 -1을 빼주냐?
이건 '0'때문인데 우린 지금 숫자를 32칸(2^32) 까지만 표현을 해야된다.(이때는 부호비트도 갯수에 포함)근데 0이 껴있으면 갯수가 2^32 +1이 되는거 그래서 부호비트 제외한 2^31승에서 -1을 빼줌으로서 갯수를 맞춰준것이다.
0을 제외하고 음수의 경우의수와 양수의 경우의수의 총합은 아래와 같은
2^31 + 2^31 = 2^31 * 2 =2^32
-2147483648 ≤ n ≤ +2147483648