C/Fundamentals

C Basics 2/ (μ—΄ν˜ˆ Cν”„λ‘œκ·Έλž˜λ°)

metamong 2023. 6. 26.

πŸ₯Έ μ €λ²ˆ ν¬μŠ€νŒ…μ—μ„œ 1μž₯λΆ€ν„° 3μž₯κΉŒμ§€ λ‹€λ£¨μ—ˆλ‹€. 이번 ν¬μŠ€νŒ…μ—μ„œλŠ” 4μž₯λΆ€ν„° 5μž₯κΉŒμ§€ λ‹€λ£¨μž!


4. 데이터 ν‘œν˜„λ°©μ‹μ˜ 이해

β‘  μ§„λ²•μ˜ 이해

2μ§„μˆ˜λŠ” 두 개의 기호(0κ³Ό 1)λ₯Ό μ΄μš©ν•΄ 데이터λ₯Ό ν‘œν˜„ν•˜λŠ” 방식. μ»΄ν“¨ν„°λŠ” 2μ§„μˆ˜λ₯Ό 기반으둜 데이터λ₯Ό ν‘œν˜„ν•˜κ³  μ—°μ‚° 진행

→ 이와 μœ μ‚¬ν•˜κ²Œ 10μ§„μˆ˜λŠ” 10개의 기호 / 16μ§„μˆ˜λŠ” 16개의 기호(1λΆ€ν„° 10κΉŒμ§€μ˜ 숫자 + A ~ F λŒ€μ†Œλ¬Έμž ꡬ뢄 x)λ₯Ό μ‚¬μš©

ex) 즉 10μ§„μˆ˜λ‘œ 10은 16μ§„μˆ˜λ‘œ A둜 ν‘œν˜„ν•˜κ³  / 10μ§„μˆ˜λ‘œ 17은 16μ§„μˆ˜λ‘œ 11둜 ν‘œν˜„ν•œλ‹€

 

Q. 16μ§„μˆ˜κ°€ ν•„μš”ν•œ 이유?

2μ§„μˆ˜λ‘œλ§Œ ν‘œν˜„ν•˜λ©΄ λ°μ΄ν„°μ˜ 길이가 κΈΈμ–΄μ§€λ―€λ‘œ ν•œλˆˆμ— νŒŒμ•…ν•˜κΈ° 어렀움. λ”°λΌμ„œ 2μ§„μˆ˜ λ„€ κ°œλŠ” 16μ§„μˆ˜ 1개둜 κ°„κ²°νžˆ ν‘œν˜„ κ°€λŠ₯ν•˜λ―€λ‘œ 16μ§„μˆ˜λ₯Ό 많이 μ‚¬μš©

 

β‘‘ λ°μ΄ν„°μ˜ ν‘œν˜„ λ‹¨μœ„ - bit와 byte

λΉ„νŠΈ(bit)λŠ” 컴퓨터가 ν‘œν˜„ν•˜λŠ” λ°μ΄ν„°μ˜ μ΅œμ†Œλ‹¨μœ„(λ©”λͺ¨λ¦¬μ˜ μ΅œμ†Œλ‹¨μœ„)λ‘œμ„œ 2μ§„μˆ˜ κ°’ ν•˜λ‚˜λ₯Ό μ €μž₯ν•  수 μžˆλŠ” λ©”λͺ¨λ¦¬μ˜ 크기

λ°”μ΄νŠΈ(byte)λŠ” λΉ„νŠΈλ₯Ό 8개 λͺ¨μ€ 것

ex) 즉 1bit둜 ν‘œν˜„ν•  수 μžˆλŠ” λ°μ΄ν„°μ˜ μˆ˜λŠ” 2개 / 2bit둜 ν‘œν˜„ν•  수 μžˆλŠ” λ°μ΄ν„°μ˜ μˆ˜λŠ” 4개 / 1byte둜 ν‘œν˜„ν•  수 μžˆλŠ” λ°μ΄ν„°μ˜ μˆ˜λŠ” $2^8$개

λ”°λΌμ„œ n개의 bit둜 ν‘œν˜„ν•  수 μžˆλŠ” λ°μ΄ν„°μ˜ μˆ˜λŠ” $2^n$개

 

β‘’ 8μ§„μˆ˜μ™€ 16μ§„μˆ˜μ˜ 데이터 ν‘œν˜„

0x둜 μ‹œμž‘ν•˜λ©΄ 16μ§„μˆ˜μ˜ ν‘œν˜„ / 0으둜 μ‹œμž‘ν•˜λ©΄ 8μ§„μˆ˜μ˜ ν‘œν˜„

ex) μ•„λž˜μ˜ μ½”λ“œ μ˜ˆμ‹œλ₯Ό 보면 ν‘œν˜„λ°©λ²•λ§Œ λ‹€λ₯Ό 뿐 μ»΄ν“¨ν„°λŠ” λ‚΄λΆ€μ μœΌλ‘œ 2μ§„μˆ˜μ˜ ν˜•νƒœλ‘œ λ™μΌν•œ 값을 μ €μž₯ν•œλ‹€

(%d둜 λ‚˜νƒ€λ‚΄μ—ˆκΈ°μ— 10μ§„μˆ˜ ν˜•νƒœλ‘œ λ‚˜νƒ€λ‚Έ 것이닀)

#include <stdio.h>

int main(void) {
  int num1 = 10;
  int num2 = 0xA;
  int num3 = 012;

  printf("%d, %d, %d\n", num1, num2, num3);
  
  return 0;
}

 

β‘£ μ •μˆ˜μ™€ μ‹€μˆ˜μ˜ ν‘œν˜„ 방식

μ •μˆ˜μ˜ ν‘œν˜„λ°©μ‹

: λ§Œμ•½ 1λ°”μ΄νŠΈμ˜ λ©”λͺ¨λ¦¬ 곡간에 μ •μˆ˜λ₯Ό μ €μž₯ν•˜λ € ν•œλ‹€λ©΄ κ°€μž₯ μ™Όμͺ½μ— μ‘΄μž¬ν•˜λŠ” bitλŠ” λΆ€ν˜Έ ν‘œν˜„μ— μ‚¬μš©. μ–‘μˆ˜λΌλ©΄ 1, 음수라면 0을 μ €μž₯ν•œλ‹€. 이 bitλ₯Ό κ°€λ¦¬μΌœ MSB(Most Significant Bit)라고 ν•œλ‹€. 그리고 κ°€μž₯ μ™Όμͺ½ bitλ₯Ό μ œμ™Έν•œ λ‚˜λ¨Έμ§€ bitλŠ” λ°μ΄ν„°μ˜ 크기λ₯Ό λ‚˜νƒ€λ‚Έλ‹€. 
 

ex) 10μ§„μˆ˜λ‘œ 10μ΄λΌλŠ” μ–‘μ˜ μ •μˆ˜λ₯Ό ν‘œν˜„ν•˜κ³  μ‹Άλ‹€λ©΄ μ•„λž˜μ™€ 같이 000001010으둜 ν‘œν˜„ν•  수 μžˆλ‹€.

 

: 음의 μ •μˆ˜λ₯Ό ν‘œν˜„ν•˜κ³  μ‹Άλ‹€λ©΄ 2의 보수λ₯Ό μ·¨ν•΄μ•Ό ν•œλ‹€. μ•„λž˜μ˜ μ„Έ μ°¨λ‘€ 과정을 '2의 λ³΄μˆ˜λ²•'이라 뢀름

(1) λ¨Όμ € μ–‘μ˜ μ •μˆ˜λ₯Ό ν‘œν˜„ν•œλ‹€

(2) 1의 보수λ₯Ό μ·¨ν•œλ‹€

(3) 1을 λ”ν•œλ‹€ 

ex) μ •μˆ˜ -5λ₯Ό ν‘œν˜„ν•˜κ³  μ‹Άλ‹€λ©΄ μ •μˆ˜ +5인 00000101μ—μ„œ 1의 보수λ₯Ό μ·¨ν•œ 11111010둜 λ‚˜μ˜¨ λ‹€μŒ, 1을 λ”ν•œ 결과인 11111011이 μ •λ‹΅

ex) 음의 μ •μˆ˜ 10101001κ³Ό 11110000은 각각 10μ§„μˆ˜λ‘œ -87κ³Ό -16이 λœλ‹€. (μœ„ 2의 λ³΄μˆ˜λ²•μ„ 거꾸둜 λ”°λ₯΄λ©΄ λœλ‹€)

: 즉 μ–‘μˆ˜μ—μ„œ 음수둜 λ°”κΏ€ λ•Œ 1을 0으둜 λ°”κΎΈκ³ , 0을 1둜 λ°”κΎΌ λ‹€μŒ + 1 / μŒμˆ˜μ—μ„œ μ–‘μˆ˜λ‘œ λ°”κΏ€ λ•ŒλŠ” λ°˜λŒ€λ‘œ -1을 ν•œλ‹€μŒ 1을 0으둜 λ°”κΎΈκ³  0을 1둜 λ°”κΎΌλ‹€. 이 λ•Œ 음수둜 λ¨Όμ € 1을 0으둜 λ°”κΎΈκ³ , 0을 1둜 λ°”κΎΌ λ‹€μŒ +1 해도 κ°€λŠ₯ν•˜λ‹€! (μ•„λž˜ 예제 μ°Έμ‘°)

 

μ‹€μˆ˜μ˜ ν‘œν˜„λ°©μ‹

: μš°λ¦¬κ°€ ν‘œν˜„ν•˜κ³ μž ν•˜λŠ” μ‹€μˆ˜μ˜ 값을 μ •ν™•νžˆ ν‘œν˜„ν•  수 μ—†μœΌλ―€λ‘œ, μ΄λŸ¬ν•œ 였차λ₯Ό '뢀동 μ†Œμˆ˜μ  였차'라고 ν•œλ‹€. λΆ€ν˜Έ λΉ„νŠΈ(sign bit), μ§€μˆ˜ λΉ„νŠΈ(exponent bit)κ°€ e, κ°€μˆ˜λΉ„νŠΈ(fraction, significant, mantissa bit)κ°€ m을 λœ»ν•œλ‹€.

 

β‘€ λΉ„νŠΈ μ—°μ‚°μž

→ 주둜 ν•˜λ“œμ›¨μ–΄ κ΄€λ ¨ ν”„λ‘œκ·Έλž˜λ°μ— ν™œμš©λ˜μ§€λ§Œ, λ©”λͺ¨λ¦¬ κ³΅κ°„μ˜ νš¨μœ¨μ„± λ†’μ΄κ±°λ‚˜ μ—°μ‚°μ˜ 수λ₯Ό 쀄일 λ•Œ 많이 μ‚¬μš©λ˜κΈ°λ„ ν•œλ‹€.

μ—°μ‚°μž μ—°μ‚°μž κΈ°λŠ₯
& AND μ—°μ‚°
| OR μ—°μ‚°
^ XOR μ—°μ‚°(두 개의 bitκ°€ λ‹€λ₯΄λ©΄ 1 λ°˜ν™˜)
~ ν”Όμ—°μ‚°μžμ˜ λͺ¨λ“  λΉ„νŠΈ λ°˜μ „
<< ν”Όμ—°μ‚°μžμ˜ λΉ„νŠΈ 열을 μ™Όμͺ½μœΌλ‘œ 이동
>> ν”Όμ—°μ‚°μžμ˜ λΉ„νŠΈ 열을 였λ₯Έμͺ½μœΌλ‘œ 이동

 

~ NOT μ—°μ‚°μžλ₯Ό μ‚¬μš©ν•  λ•Œ 맨 μ•žμ˜ MSB도 λ°˜μ „λ˜μ–΄ λΆ€ν˜Έλ§ˆμ € λ°”λ€œμ— 주의!

 

<<λŠ” λΉ„νŠΈλ₯Ό μ™Όμͺ½μœΌλ‘œ 이동: μ™Όμͺ½μœΌλ‘œ μ΄λ™ν•˜λ©° μƒκΈ°λŠ” 였λ₯Έμͺ½ λΉˆμΉΈμ€ 0으둜 μ±„μ›Œμ§€κ³  λ°€λ €λ‚˜λŠ” μ™Όμͺ½ λΉ„νŠΈλ“€μ€ κ·Έλƒ₯ 버렀진닀. 그리고 μ™Όμͺ½μœΌλ‘œ 1μΉΈμ”© 이동할 λ•Œλ§ˆλ‹€ μ •μˆ˜μ˜ 값은 두 λ°°κ°€ λœλ‹€. λ”°λΌμ„œ 상황에 따라 κ³±μ…ˆ λ‚˜λˆ—μ…ˆ 연산은 λΉ„νŠΈμ˜ μ΄λ™μ—°μ‚°μœΌλ‘œ λŒ€μ²΄λ˜λ©° μ„±λŠ₯ ν–₯상. CPU μž…μž₯μ—μ„œλŠ” κ³±μ…ˆκ³Ό λ‚˜λˆ—μ…ˆμ΄ λΉ„νŠΈμ˜ 이동보닀 λΆ€λ‹΄μŠ€λŸ½κΈ° λ•Œλ¬Έ.

 

>>λŠ” λΉ„νŠΈλ₯Ό 였λ₯Έμͺ½μœΌλ‘œ 이동: 였λ₯Έμͺ½μœΌλ‘œ 1μΉΈμ”© 이동할 λ•Œλ§ˆλ‹€ μ •μˆ˜λŠ” 2둜 λ‚˜λˆ„μ–΄μ§„λ‹€. κ·ΈλŸ¬λ‚˜ 음수라면 였λ₯Έμͺ½μœΌλ‘œ 이동할 λ•Œ λΆ€ν˜Έ bitλ₯Ό 1둜 μœ μ§€ν•˜λŠ” CPUκ°€ 있고, μ•„λ‹Œ CPUκ°€ 쑴재. 

 

* 예제)

#include <stdio.h>

int main(void) {
  int num1 = 15;
  int num2 = 20;
  int num3 = num1 & num2;
  int num4 = -16;

  printf("num1 AND num2: %d\n", num3); //00000100 = 4
  printf("num1 OR num2: %d\n", num1|num2); //00011111 = 31
  printf("num1 XOR num2: %d\n", num1^num2); //00011011 = 27
  printf("~ num2: %d\n", ~num2); //-21 (after +1 -> -21)
  printf("after moving 1 bit(right-wise): %d\n", num4>>1);
  return 0;
}

 

* μž…λ ₯받은 μ •μˆ˜ κ°’μ˜ λΆ€ν˜Έλ₯Ό λ°”κΏ” 좜λ ₯ν•˜λŠ” ν”„λ‘œκ·Έλž¨

#include <stdio.h>

int main(void) {
  int num;
  printf("enter your num: ");
  scanf("%d",&num);

  num = ~ num;
  num += 1;

  printf("the result is: %d\n", num);
  return 0;
}

 

* 주어진 x와 yμ—μ„œ shift operatorλ§Œμ„ ν™œμš©ν•˜μ—¬ 1, 2, 3, 4, 5, 6을 λͺ¨λ‘ 좜λ ₯ν•˜κΈ° (>>의 κ²°κ³Ό 2둜 λ‚˜λˆˆ λͺ«μ΄ λ‚˜μ˜¨λ‹€)

#include <stdio.h>

int main(void) {
  int x = 7, y = 10;
  printf("%d\n",y>>3); //1
  printf("%d\n",(y>>3)<<1); //2
  printf("%d\n",x>>1); //3
  printf("%d\n",(y>>3)<<2); //4
  printf("%d\n",y>>1); //5
  printf("%d\n",(x>>1)<<1); //6
  return 0;
}

5. μƒμˆ˜μ™€ κΈ°λ³Έ μžλ£Œν˜•

β‘₯ μžλ£Œν˜•μ€ 데이터λ₯Ό ν‘œν˜„ν•˜λŠ” 방법

→ λ³€μˆ˜λ₯Ό λ§Œλ“€κΈ° μœ„ν•΄ λ©”λͺ¨λ¦¬ 곡간을 ν• λ‹Ήν•  λ•Œ (1) μ •μˆ˜ μ €μž₯인지 / μ‹€μˆ˜ μ €μž₯인지 확인 + (2) μ €μž₯ν•˜κΈ° μœ„ν•΄ λͺ‡ λ°”μ΄νŠΈλ₯Ό μ‚¬μš©ν•  것인지

→ κΈ°λ³Έ μžλ£Œν˜•μ˜ μ’…λ₯˜μ™€ λ°μ΄ν„°μ˜ ν‘œν˜„λ²”μœ„(VC++ compiler κΈ°μ€€)

μžλ£Œν˜• 크기 κ°’μ˜ ν‘œν˜„λ²”μœ„
char (μ •μˆ˜ν˜•) 1 byte -128 ~ +127
short (μ •μˆ˜ν˜•) 2 byte -32768 ~ +32767
int (μ •μˆ˜ν˜•) 4 byte -2147483648 ~ + 2147483647
long (μ •μˆ˜ν˜•) 4 byte / 8 byte -2147483648 ~ + 2147483647
long long (μ •μˆ˜ν˜•) 8 byte - 9223372036854775808 ~
+ 9223372036854775807
float (μ‹€μˆ˜ν˜•) 4 byte ~
double (μ‹€μˆ˜ν˜•) 8 byte ~
long double (μ‹€μˆ˜ν˜•) more than 8 bytes double μ΄μƒμ˜ ν‘œν˜„ λ²”μœ„

 

→ ν‘œν˜„μ— μ‚¬μš©λ˜λŠ” λ°”μ΄νŠΈμ˜ 크기가 클수둝 ν‘œν˜„ν•  수 μžˆλŠ” κ°’μ˜ λ²”μœ„κ°€ 넓어진닀.

→ μžλ£Œν˜• λ³„λ‘œ 크기λ₯Ό μ •ν™•νžˆ μ œν•œν•˜κ³  μžˆμ§€λŠ” μ•Šλ‹€. compilerλ³„λ‘œ μ•½κ°„ λ‹€λ₯΄λ‹€.

→ 데이터 ν‘œν˜„ 방식이 λ‹€λ₯΄λ―€λ‘œ μ΅œμ†Œ 2 개 μ΄μƒμ˜ μžλ£Œν˜•μ„ λ§Œλ“€μ–΄μ•Ό ν•˜κ³ (μ •μˆ˜ν˜• / μ‹€μˆ˜ν˜•), λ©”λͺ¨λ¦¬μ˜ μ μ ˆν•œ μ‚¬μš©μ„ μœ„ν•΄ λ‹€μ–‘ν•œ 크기의 μžλ£Œν˜• ν•„μš”

 

⑦ μ—°μ‚°μž sizeof(ν•¨μˆ˜ x)

→ μžμ‹ μ΄ μ‚¬μš©ν•˜λŠ” compiler의 μžλ£Œν˜•λ³„ byte 크기 확인 κ°€λŠ₯ - λ©”λͺ¨λ¦¬ κ³΅κ°„μ—μ„œ μ†Œλͺ¨ν•˜λŠ” λ©”λͺ¨λ¦¬μ˜ 크기λ₯Ό μ•Œ 수 있음

#include <stdio.h>

int main(void) {
  int num = 10;
  int sz1 = sizeof(num);
  int sz2 = sizeof(int);

  printf("size of int type: %d\n", sz2);
  printf("size of num variable: %d\n", sz1);
  return 0;
}

/*
size of int type: 4
size of num variable: 4
*/

 

⑧ μ •μˆ˜λ₯Ό ν‘œν˜„ 및 μ²˜λ¦¬ν•˜κΈ° μœ„ν•œ 일반적인 μžλ£Œν˜•μ˜ 선택

→ κ°’μ˜ λ²”μœ„λ§Œ 가지고 μ–΄λ–€ μžλ£Œν˜•μœΌλ‘œ ν‘œν˜„ν•  수 μžˆμ„ μ§€λŠ” λͺ¨λ₯Έλ‹€. 일반적으둜 CPUκ°€ μ²˜λ¦¬ν•˜κΈ°μ— κ°€μž₯ μ ν•©ν•œ 크기의 μ •μˆ˜ μžλ£Œν˜•μ„ int둜 μ •μ˜. intν˜• μ—°μ‚°μ˜ 속도가 λ‹€λ₯Έ μžλ£Œν˜•μ˜ 연산속도에 λΉ„ν•΄ λ™μΌν•˜κ±°λ‚˜ 더 λΉ λ₯΄λ‹€. λ”°λΌμ„œ int보닀 μž‘μ€ 크기의 λ°μ΄ν„°λŠ” intν˜• λ°μ΄ν„°λ‘œ λ°”κΏ”μ„œ(ν˜• λ³€ν™˜) 연산이 μ§„ν–‰λœλ‹€.

 

ex) μ•„λž˜ 예제 확인

#include <stdio.h>

int main(void){
  short num1 = 300, num2 = 200;
  char num3 = 4, num4 = 5;
  printf("size of num1 and num2: %d, %d\n",sizeof(num1), sizeof(num2));
  printf("size of num3 and num4: %d, %d\n",sizeof(num3), sizeof(num4));
  printf("size of char add: %d\n", sizeof(num1+num2));
  printf("size of short add: %d\n", sizeof(num3+num4));
}
/*
size of num1 and num2: 2, 2
size of num3 and num4: 1, 1
size of char add: 4
size of short add: 4
*/

 

→ κ·ΈλŸ¬λ‚˜ intν˜•λ³΄λ‹€ λ²”μœ„κ°€ μž‘μ€ short, char ν˜•μ€ λ°μ΄ν„°μ˜ 양이 λ§Žμ•„μ„œ μ—°μ‚°μ†λ„λ³΄λ‹€λŠ” λ‹Ήμž₯의 데이터 크기λ₯Ό μ€„μ΄λŠ” 것이 더 μ€‘μš”ν•  경우 많이 μ‚¬μš©λœλ‹€. 즉, 크기에 λ―Όκ°ν•œ 데이터λ₯Ό μ‚¬μš©ν•  λ•Œ

 

⑨ μ‹€μˆ˜λ₯Ό ν‘œν˜„ 및 μ²˜λ¦¬ν•˜κΈ° μœ„ν•œ 일반적인 μžλ£Œν˜•μ˜ 선택

→ μ‹€μˆ˜ μžλ£Œν˜•μ— μžˆμ–΄μ„œ κ°€μž₯ μ€‘μš”ν•œ μš”μ†ŒλŠ” 정밀도이닀. μ •λ°€λ„λž€, 'μ˜€μ°¨κ°€ λ°œμƒν•˜μ§€ μ•ŠλŠ” μ†Œμˆ˜μ  μ΄ν•˜μ˜ 자릿수' , 즉 λͺ‡ μžλ¦¬κΉŒμ§€λŠ” μ˜€μ°¨κ°€ λ°œμƒν•˜μ§€ μ•ŠμŒμ„ 보μž₯ν•˜λŠ” λ²”μœ„μ΄λ‹€.

μ‹€μˆ˜ μžλ£Œν˜• μ†Œμˆ˜μ  μ΄ν•˜ 정밀도 λ°”μ΄νŠΈ 수
float 6자리 4
double 15자리 8
long double 18자리 12

 

double이 보편적으둜 μ‚¬μš©λœλ‹€. float보닀 정밀도가 λ†’μœΌλ©΄μ„œλ„ long doubleλ³΄λ‹€λŠ” 뢀담이 덜 되기 λ•Œλ¬Έ

 

* 예제) μ›μ˜ λ°˜μ§€λ¦„μ„ μž…λ ₯ λ°›μ•„μ„œ μ›μ˜ 넓이λ₯Ό 좜λ ₯ν•˜λŠ” 문제

#include <stdio.h>

int main(void) {
  double rad, area;
  printf("enter radius: ");
  scanf("%lf",&rad);

  area = rad * rad * 3.1415;
  printf("area of the circle is: %f\n", area);
  return 0;
}

/*
enter radius: 2.2
area of the circle is: 15.204860
*/

 

β‘© unsigned

→ μ •μˆ˜ μžλ£Œν˜•μ— ν•œν•΄μ„œ, μ•žμ— unsigned 선언을 μΆ”κ°€ν•˜λ©΄ 0 μ΄μƒμ˜ κ°’λ§Œ ν‘œν˜„ν•˜λŠ” μžλ£Œν˜•μ΄ λœλ‹€. λ”°λΌμ„œ μ •μˆ˜λ‘œ ν‘œν˜„ν•  수 μžˆλŠ” κ°’μ˜ λ²”μœ„κ°€ μ–‘μ˜ μ •μˆ˜ λ°©ν–₯으둜 2λ°° λ„“μ–΄μ§€κ²Œ λœλ‹€. 예λ₯Ό λ“€μ–΄ charν˜•μ€ -128 ~ +127κΉŒμ§€ ν‘œν˜„μ΄ κ°€λŠ₯ν–ˆλŠ”λ°, unsigned charκ°€ 되면 ν‘œν˜„ν•  수 μžˆλŠ” κ°’μ˜ λ²”μœ„κ°€ 0이상 +255κ°€ λœλ‹€.

→ unsigned 값을 뢙이면 맨 μ•žμ˜ MSBκ°€ κ°’μ˜ 크기λ₯Ό λ‚˜νƒ€λ‚Ό 수 μžˆλŠ” bit둜 μ‚¬μš©ν•˜κ²Œ λ˜λ©΄μ„œ ν‘œν˜„ν•  수 μžˆλŠ” 값이 0 μ΄μƒμ˜ λ²”μœ„λ‘œ 두 λ°°κ°€ λœλ‹€. (즉 defaultλŠ” signed이며 signet intλ‚˜ intλ‚˜ 동일)

 

β‘ͺ ASCII μ½”λ“œ

→ 문자λ₯Ό ν‘œν˜„ν•˜λ €λ©΄ μˆ«μžμ™€ 문자λ₯Ό mappingν•΄μ£Όμ–΄μ•Ό ν•œλ‹€. 문자λ₯Ό ν‘œν˜„ν•˜κΈ° μœ„ν•΄μ„œλŠ” μž‘μ€ λ”°μ˜΄ν‘œ, printf()둜 좜λ ₯ν•˜κΈ° μœ„ν•΄μ„œλŠ” conversion specifier둜 %c μ‚¬μš©. 문자λ₯Ό μ €μž₯ν•  λ•ŒλŠ” char ν˜• μ‚¬μš©

λ¬ΈμžλŠ” μ •μˆ˜λ‘œλ„ 좜λ ₯이 κ°€λŠ₯ν•˜κ³ , 이 λ•Œ mappingν•œ ASCII ν‘œμ€€μ— 따라(예λ₯Ό λ“€μ–΄ AλŠ” 65번) %c인지, %d인지에 따라 좜λ ₯λœλ‹€.

#include <stdio.h>

int main(void) {
  char ch1 = 'A';
  int ch2 = 90;
  printf("%c %d\n", ch1, ch1);
  printf("%c %d\n", ch2, ch2);
  return 0;
}
/*
A 65
Z 90
*/

 

* μ°Έκ³ ) ASCII ν‘œ

 

β‘« μƒμˆ˜

* μƒμˆ˜λž€ '변경이 λΆˆκ°€λŠ₯ν•œ 데이터'

<1> 이름이 μ—†λŠ” μƒμˆ˜ (literal μƒμˆ˜ / literal)

ex) int num = 30 + 40;

→ λ¨Όμ € 첫번째둜 μ •μˆ˜ 30κ³Ό 40이 λ©”λͺ¨λ¦¬ 곡간에 μƒμˆ˜μ˜ ν˜•νƒœλ‘œ μ €μž₯λœλ‹€. κ·Έ λ‹€μŒ 두 μƒμˆ˜λ₯Ό 기반으둜 λ§μ…ˆμ΄ μ§„ν–‰λ˜κ³ , λ§μ…ˆμ˜ 결과둜 얻어진 μ •μˆ˜ 70이 λ³€μˆ˜ num에 μ €μž₯λœλ‹€.

→ 즉, 30κ³Ό 40을 μ„œλ‘œ μ—°μ‚°ν•˜κΈ° μœ„ν•΄μ„œλŠ” 일단은 λ©”λͺ¨λ¦¬μ— μ˜¬λ €μ•Ό CPUκ°€ 연산을 μ§„ν–‰ν•œλ‹€. 이 λ•Œ λ³€μˆ˜λ₯Ό λ”°λ‘œ λ§Œλ“€μ§€ μ•Šμ•˜κΈ° λ•Œλ¬Έμ— λ³€μˆ˜μ˜ 이름이 μ—†λŠ” μƒμˆ˜κ°€ λ˜μ–΄μ„œ λ©”λͺ¨λ¦¬μ— μ˜¬λΌκ°€κ²Œ λœλ‹€.

#include <stdio.h>

int main(void) {
  int num1 = 3 + 4;
  int num2 = 7 + num1;
  double num3 = 2.12 + 7.49;
  return 0;
}

 

: λ”°λΌμ„œ μœ„ μ½”λ“œμ—μ„œ μƒμˆ˜μ˜ κ°œμˆ˜λŠ” 5κ°œκ°€ λœλ‹€.

 

sizeof()λ₯Ό μ΄μš©ν•΄μ„œ literal constant의 크기λ₯Ό 확인할 수 μžˆλ‹€.

#include <stdio.h>

int main(void) {
  printf("%d\n",sizeof('A')); //4
  printf("%d\n",sizeof(7)); //4
  printf("%d\n",sizeof(7.14)); //8
  return 0;
}

 

: 문자 'A'λŠ” 65둜 λ°”λ€Œμ–΄μ„œ 4λ°”μ΄νŠΈ 크기의 intν˜•μœΌλ‘œ ν‘œν˜„λ¨μ„ μ•Œ 수 μžˆλ‹€.

 

→ 기본적으둜 intν˜• / doubleν˜•μœΌλ‘œ 각각 μ •μˆ˜μ™€ μ‹€μˆ˜ 연산을 μ§„ν–‰ν•˜λ―€λ‘œ λ§Œμ•½ float라고 λͺ…μ‹œν•΄μ„œ μ•„λž˜μ™€ 같이 μ½”λ“œλ₯Ό μž‘μ„±ν•œλ‹€λ©΄,

#include <stdio.h>

int main(void) {
  float num1 = 5.789;
  float num2 = 3.24 + 5.12;
  return 0;
}

 

: 기본적인 double ν˜•νƒœμ˜ μ‹€μˆ˜λ₯Ό floatν˜• λ³€μˆ˜μ— μ €μž₯ν•˜λ―€λ‘œ 데이터가 μž˜λ €λ‚˜κ°ˆ 수 μžˆλŠ” κ²½κ³  λ©”μ‹œμ§€κ°€ λœ¬λ‹€. λ”°λΌμ„œ μžλ™μ μœΌλ‘œ doubleν˜• μƒμˆ˜κ°€ λ˜λŠ” μƒμˆ˜λ₯Ό floatν˜• μƒμˆ˜λ‘œ λ°”κΎΈλ €λ©΄ μƒμˆ˜μ˜ 뒀에 f(F)λ₯Ό λΆ™μ—¬ μ£Όλ©΄ λœλ‹€.

 

→ 이와 같이 μƒμˆ˜κ°€ λ‹€μ–‘ν•œ μžλ£Œν˜•μ„ ν‘œν˜„ν•  수 μžˆλ„λ‘ 뒀에 λ‹€μ–‘ν•œ 접미사λ₯Ό λΆ™μ΄κ²Œ ν•  수 μžˆλ‹€.

접미사 μžλ£Œν˜• μ‚¬μš©μ˜ 예
U unsigned int unsigned int n = 1025U
L long long n = 2467L
UL unsigned long unsigned long n = 3456UL
LL long long long long n = 5768LL
ULL unsigned long long unsigned long long n = 8979ULL
F float float f = 3.15F
L long double long double f = 5.789L

 

<2> 이름을 μ§€λ‹ˆλŠ” 심볼릭 μƒμˆ˜ (symbolic μƒμˆ˜ / const)

const ν‚€μ›Œλ“œλ₯Ό μ΄μš©ν•΄μ„œ μƒμˆ˜λ₯Ό λ§Œλ“€ 수 μžˆλ‹€(맀크둜 μ΄μš©μ€ λ‚˜μ€‘μ—!)

→ μƒμˆ˜μ΄κΈ° λ•Œλ¬Έμ— μ„ μ–Έκ³Ό λ™μ‹œμ— μ΄ˆκΈ°ν™” ν•„μˆ˜

 

β€» λ³€μˆ˜μ™€ λ‹€λ₯΄κ²Œ μƒμˆ˜λŠ” κ°’μ˜ 변경이 λΆˆκ°€λŠ₯ν•˜λ‹€. μƒμˆ˜μ˜ 이름은 λͺ¨λ‘ λŒ€λ¬Έμž / λ‘˜ μ΄μƒμ˜ λ‹¨μ–΄λ‘œ μ—°κ²°ν•  λ•ŒλŠ” 언더바 μ΄μš©ν•΄μ„œ 단어 ꡬ뢄

 

ex) μ•„λž˜ 예제 확인

#include <stdio.h>

int main(void) {
  double r;
  const double PI = 3.141592;
  double area;
  
  printf("enter the radius: ");
  scanf("%lf",&r);

  area = PI * r * r;
  printf("area is %.2f\n", area);
  
  return 0;
}

 

⑬ μžλ£Œν˜•μ˜ λ³€ν™˜

<1> μžλ™ ν˜• λ³€ν™˜

→ λŒ€μž… μ—°μ‚°μžμ˜ μ™ΌνŽΈκ³Ό 였λ₯ΈνŽΈ 각각의 두 ν”Όμ—°μ‚°μžμ˜ μžλ£Œν˜•μ΄ μΌμΉ˜ν•˜μ§€ μ•ŠμœΌλ©΄, μ™ΌνŽΈμ— μžˆλŠ” ν”Όμ—°μ‚°μžλ₯Ό λŒ€μƒμœΌλ‘œ ν˜• λ³€ν™˜μ΄ μžλ™μœΌλ‘œ μΌμ–΄λ‚œλ‹€. (μ €μž₯μ†Œμ˜ μžλ£Œν˜•μ˜ μš°μ„ μˆœμœ„κ°€ 더 λ†’κΈ° λ•Œλ¬Έ)

 

ex) double num1 = 245; (intν˜• μ •μˆ˜λ₯Ό doubleν˜•μœΌλ‘œ μžλ™ ν˜• λ³€ν™˜: 245κ°€ 245.0으둜 λ³€ν™˜λ˜μ–΄ num1에 μ €μž₯)

ex) int num2 = 3.1415; (doubleν˜• μ‹€μˆ˜λ₯Ό intν˜•μœΌλ‘œ μžλ™ ν˜• λ³€ν™˜: 3.1415κ°€ 3으둜 λ³€ν™˜λ˜μ–΄ num2에 μ €μž₯)

 

→ μ΄λ ‡κ²Œ μ‹€μˆ˜ν˜• 데이터λ₯Ό μ •μˆ˜ν˜• λ°μ΄ν„°λ‘œ λ³€ν™˜ν•˜λŠ” κ³Όμ •μ—μ„œλŠ” 'μ†Œμˆ˜λΆ€μ˜ 손싀'이 λ°œμƒν•œλ‹€.

 

λ°”μ΄νŠΈ 크기의 크기가 큰 μ •μˆ˜λ₯Ό 크기가 μž‘μ€ μ •μˆ˜λ‘œ ν˜• λ³€ν™˜μ„ μ§„ν–‰ν•˜λŠ” 경우 μƒμœ„ λ°”μ΄νŠΈκ°€ λ‹¨μˆœνžˆ μ†Œλ©Έλœλ‹€. μƒμœ„ λ°”μ΄νŠΈμ˜ μ†μ‹€λ‘œ λΆ€ν˜Έκ°€ λ°”λ€” μˆ˜λ„ μžˆλ‹€. λ°˜λŒ€λ‘œ λ°”μ΄νŠΈ 크기가 μž‘μ€ μ •μˆ˜λ₯Ό 큰 μ •μˆ˜λ‘œ λ³€ν™˜μ„ ν•  λ•ŒλŠ” λ°μ΄ν„°μ˜ 손싀이 λ°œμƒν•˜μ§€λŠ” μ•ŠλŠ”λ‹€.

 

ex)

#include <stdio.h>

int main(void) {
  int num3 = 129;
  char ch = num3;
  printf("%d\n", ch); //-127 10000001
  
  return 0;
}

 

: 129λ₯Ό intν˜• μžλ£Œν˜• λ³€μˆ˜μ— λ„£μ—ˆλŠ”λ° charν˜•μœΌλ‘œ μžλ£Œν˜•μ„ λ°”κΎΈλ‹ˆ -127둜 λ‚˜μ™”λ‹€.

 

μ •μˆ˜μ˜ 승격(Integral Promotion)

: CPUκ°€ μ²˜λ¦¬ν•˜κΈ°μ— κ°€μž₯ μ ν•©ν•œ 크기의 μ •μˆ˜ μžλ£Œν˜•μ„ int둜 μ •μ˜ν•΄μ„œ, intν˜• μ—°μ‚°μ˜ 속도가 λ‹€λ₯Έ μžλ£Œν˜•μ˜ 연산속도에 λΉ„ν•΄μ„œ λ™μΌν•˜κ±°λ‚˜ 더 λΉ λ₯΄λ‹€.

 

ex) short num1 = 15, num2 = 25; short num3 = num1 + num2;

: μœ„ μ½”λ“œμ—μ„œλŠ” num1+num2 μ—°μ‚° 과정은 intν˜•μœΌλ‘œμ˜ μžλ™ ν˜• λ³€ν™˜μ΄ λ°œμƒν•˜κ³  λ‹€μ‹œ shortν˜•μœΌλ‘œ ν˜• λ³€ν™˜μ΄ μΌμ–΄λ‚œλ‹€. λ”°λΌμ„œ, short → int → short둜 두 μ°¨λ‘€μ˜ μžλ™ ν˜• λ³€ν™˜ λ°œμƒ

 

ν”Όμ—°μ‚°μžμ˜ μžλ£Œν˜• 뢈일치

: λ°μ΄ν„°μ˜ 손싀을 μ΅œμ†Œν™”ν•˜λŠ” λ°©ν–₯으둜 μ§„ν–‰ν•œλ‹€. 예λ₯Ό λ“€μ–΄μ„œ intν˜• μ •μˆ˜μ™€ longν˜• μ •μˆ˜λ₯Ό λŒ€μƒμœΌλ‘œ λ§μ…ˆμ—°μ‚°μ„ μ§„ν–‰ν•œλ‹€λ©΄ ν™”μ‚΄ν‘œ λ°©ν–₯에 λ”°λΌμ„œ intν˜• μ •μˆ˜κ°€ longν˜• μ •μˆ˜λ‘œ μžλ™ ν˜• λ³€ν™˜λœλ‹€. λ§Œμ•½ charν˜• μ •μˆ˜μ™€ shortν˜• μ •μˆ˜λ₯Ό λŒ€μƒμœΌλ‘œ 연산을 μ§„ν–‰ν•œλ‹€λ©΄ 무쑰건 μ •μˆ˜μ˜ μŠΉκ²©μ— μ˜ν•΄μ„œ intν˜• μ •μˆ˜λ‘œ ν˜• λ³€ν™˜λœλ‹€. μ‹€μˆ˜ μžλ£Œν˜•μ΄ 데이터 손싀을 μ΅œμ†Œν™”ν•˜λ―€λ‘œ 4λ°”μ΄νŠΈ 크기의 float이 8λ°”μ΄νŠΈ 크기의 long long보닀 ν˜• λ³€ν™˜ μš°μ„ μˆœμœ„κ°€ λ†’λ‹€.

 

<2> λͺ…μ‹œμ  ν˜• λ³€ν™˜: κ°•μ œλ‘œ μΌμœΌν‚€λŠ” ν˜• λ³€ν™˜

ν˜• λ³€ν™˜ μ—°μ‚°μž(type casting operator)λ₯Ό μ΄μš©ν•΄μ„œ κ°•μ œλ‘œ ν˜• λ³€ν™˜μ„ λͺ…λ Ήν•œλ‹€. 

 

ex)

#include <stdio.h>

int main(void) {
  int num1 = 3, num2 = 4;
  double res;
  res = num1 / num2;
  printf("result is: %f\n", res);
  
  return 0;
}
//result is: 0.000000

 

: intν˜• μ •μˆ˜λ₯Ό λŒ€μƒμœΌλ‘œ λ‚˜λˆ—μ…ˆμ„ μ§„ν–‰ν•΄μ„œ λ‚˜λˆ—μ…ˆ κ²°κ³ΌλŠ” 0이 λœλ‹€. 그리고 double둜 μžλ™ ν˜• λ³€ν™˜λ˜μ–΄ 좜λ ₯ν•˜λ©΄ 0.000000이 λ‚˜μ˜¨λ‹€.

 

→ λ”°λΌμ„œ, λ³€μˆ˜ ν•œ 곳에 (double)을 뢙이면 μ‚°μˆ μ—°μ‚°μ˜ ν˜• λ³€ν™˜ κ·œμΉ™μ— μ˜ν•΄ num2에 μ €μž₯된 값도 μžλ™μœΌλ‘œ double둜 μžλ™ ν˜• λ³€ν™˜. λ”°λΌμ„œ 결과둜 0.75κ°€ λ‚˜μ˜¨λ‹€. (μžλ™ ν˜• λ³€ν™˜μ΄ λ°œμƒν•˜λŠ” κ²½μš°λ„ ν˜• λ³€ν™˜μ„ λͺ…μ‹œν•΄μ£ΌλŠ” 것이 μ’‹λ‹€. μ½”λ“œμ˜ 뢄석을 λ•λŠ” 효과)

#include <stdio.h>

int main(void) {
  int num1 = 3, num2 = 4;
  double res;
  res = (double)num1 / num2;
  printf("result is: %f\n", res);
  
  return 0;
}//result is: 0.750000

* λ‚΄μš© 전체 좜처 <μœ€μ„±μš°μ˜ μ—΄ν˜ˆ C ν”„λ‘œκ·Έλž˜λ°>

* 사진 일뢀 좜처 https://donghwada.tistory.com/44

 

λŒ“κΈ€