Home > CS > CS50 > πŸ›οΈ [CS50] Lecture 2 μš”μ•½: λ©”λͺ¨λ¦¬μ™€ λ°°μ—΄

πŸ›οΈ [CS50] Lecture 2 μš”μ•½: λ©”λͺ¨λ¦¬μ™€ λ°°μ—΄
CS Harvard CS50

πŸ›οΈ [CS50] Lecture 2 μš”μ•½: λ©”λͺ¨λ¦¬μ™€ λ°°μ—΄

ν•˜λ²„λ“œ λŒ€ν•™κ΅ CS50 μ„Έ 번째 κ°•μ˜ - David Malan ꡐ수


πŸ“‹ κ°•μ˜ κ°œμš”

ν…μŠ€νŠΈ 읽기 μˆ˜μ€€ 뢄석

  • 1ν•™λ…„ μˆ˜μ€€: β€œOne fish, two fish, red fish, blue fish”
  • 3ν•™λ…„ μˆ˜μ€€: β€œCongratulations. Today is your day…”
  • 10ν•™λ…„ μˆ˜μ€€: μ‘°μ§€ μ˜€μ›°μ˜ 1984 첫 ꡬ절
  • ν…μŠ€νŠΈ νŠΉμ„± 뢄석: 단어 길이, λ¬Έμž₯ 길이, κ΅¬λ‘μ μœΌλ‘œ 읽기 μˆ˜μ€€ νŒλ‹¨ κ°€λŠ₯

이번 μ£Ό 핡심 주제

  • 컴파일 κ³Όμ •μ˜ 심화 이해: μ†ŒμŠ€μ½”λ“œμ—μ„œ κΈ°κ³„μ–΄κΉŒμ§€μ˜ 4단계
  • λ©”λͺ¨λ¦¬ ꡬ쑰: 컴퓨터가 데이터λ₯Ό μ €μž₯ν•˜λŠ” 방법
  • λ°°μ—΄κ³Ό λ¬Έμžμ—΄: μ—°μ†λœ 데이터 ꡬ쑰의 이해
  • μ•”ν˜Έν™” 기초: 데이터 λ³΄μ•ˆμ˜ κΈ°λ³Έ 원리

πŸ”§ 컴파일 κ³Όμ •μ˜ 4단계

κΈ°μ‘΄ 이해: make의 μ§„μ‹€

# κΈ°μ‘΄ 방식
make hello
./hello

# μ‹€μ œλ‘œλŠ” μ΄λ ‡κ²Œ λ™μž‘
clang hello.c -o hello
./hello

Clang 컴파일러 직접 μ‚¬μš©ν•˜κΈ°

# κΈ°λ³Έ 컴파일 (a.out 생성)
clang hello.c

# 좜λ ₯ 파일λͺ… μ§€μ •
clang -o hello hello.c

# CS50 라이브러리 링크
clang -o hello hello.c -l cs50

컴파일의 4단계 λΆ„ν•΄

1단계: μ „μ²˜λ¦¬ (Preprocessing)

#include <stdio.h>  // 이 라인이
// μ‹€μ œλ‘œλŠ” printf의 ν”„λ‘œν† νƒ€μž…μœΌλ‘œ ꡐ체됨:
// int printf(const char *format, ...);

#include <cs50.h>   // 이 라인이
// μ‹€μ œλ‘œλŠ” get_string의 ν”„λ‘œν† νƒ€μž…μœΌλ‘œ ꡐ체됨:
// string get_string(const char *prompt);

μ „μ²˜λ¦¬κΈ° μ—­ν• :

  • #include μ§€μ‹œλ¬Έμ„ μ°Ύμ•„ ν•΄λ‹Ή 파일 λ‚΄μš©μ„ 볡사-λΆ™μ—¬λ„£κΈ°
  • 헀더 파일의 ν•¨μˆ˜ ν”„λ‘œν† νƒ€μž…μ„ μ†ŒμŠ€μ½”λ“œμ— μ‚½μž…

2단계: 컴파일 (Compiling)

  • C μ†ŒμŠ€μ½”λ“œλ₯Ό μ–΄μ…ˆλΈ”λ¦¬ μ–Έμ–΄λ‘œ λ³€ν™˜
  • μ–΄μ…ˆλΈ”λ¦¬: κΈ°κ³„μ–΄λ³΄λ‹€λŠ” 읽기 μ‰½μ§€λ§Œ μ—¬μ „νžˆ μ €μˆ˜μ€€ μ–Έμ–΄
  • κ³Όκ±°μ—λŠ” ν”„λ‘œκ·Έλž˜λ¨Έκ°€ 직접 μ–΄μ…ˆλΈ”λ¦¬λ‘œ μ½”λ”©

3단계: μ–΄μ…ˆλΈ”λ§ (Assembling)

  • μ–΄μ…ˆλΈ”λ¦¬ μ½”λ“œλ₯Ό 기계어(0κ³Ό 1)둜 λ³€ν™˜
  • a.out 파일λͺ…μ˜ 유래: β€œassembler output”

4단계: 링킹 (Linking)

  • μ—¬λŸ¬ 개의 기계어 νŒŒμΌμ„ ν•˜λ‚˜λ‘œ κ²°ν•©
  • hello.c, cs50.c, stdio.c의 기계어λ₯Ό μ—°κ²°
  • μ΅œμ’… μ‹€ν–‰ κ°€λŠ₯ν•œ 파일 생성

πŸ› 디버깅 기법

1. printf 디버깅 (기초)

for (int i = 0; i <= 3; i++)  // 버그: <= μ‚¬μš©
{
    printf("i is %i\n", i);   // λ””λ²„κΉ…μš© 좜λ ₯
    printf("#\n");
}
// 좜λ ₯: i=0,1,2,3 총 4번 (μ˜λ„: 3번)

printf의 ν•œκ³„:

  • 맀번 재컴파일 ν•„μš”
  • μž„μ‹œ μ½”λ“œ μΆ”κ°€/μ‚­μ œμ˜ λ²ˆκ±°λ‘œμ›€
  • λ³΅μž‘ν•œ λ²„κ·Έμ—λŠ” λΉ„νš¨μœ¨μ 

2. debug50 μ‚¬μš© (ꢌμž₯)

# 디버거 μ‹€ν–‰
debug50 ./program_name

디버거 μ‚¬μš©λ²•:

  1. 브레이크포인트 μ„€μ •: μ½”λ“œ μ™Όμͺ½ μ—¬λ°± 클릭
  2. Step Over: ν˜„μž¬ 라인 μ‹€ν–‰ ν›„ λ‹€μŒ 라인으둜
  3. Step Into: ν•¨μˆ˜ λ‚΄λΆ€λ‘œ λ“€μ–΄κ°€κΈ°
  4. λ³€μˆ˜ λͺ¨λ‹ˆν„°λ§: μ‹€μ‹œκ°„μœΌλ‘œ λ³€μˆ˜ κ°’ 확인

λ””λ²„κ±°μ˜ μž₯점:

  • μ½”λ“œ μˆ˜μ • 없이 μ‹€ν–‰ μƒνƒœ 확인
  • λ³€μˆ˜ κ°’μ˜ μ‹€μ‹œκ°„ 좔적
  • 단계별 μ‹€ν–‰μœΌλ‘œ 논리 였λ₯˜ 발견

3. λŸ¬λ²„λ• 디버깅

  • κ°œλ…: 무생물(고무 였리)μ—κ²Œ μ½”λ“œ μ„€λͺ…ν•˜κΈ°
  • 효과: 말둜 μ„€λͺ…ν•˜λŠ” κ³Όμ •μ—μ„œ 논리적 였λ₯˜ 발견
  • CS50 Duck: cs50.aiμ—μ„œ AI 도움 λ°›κΈ°

πŸ’Ύ λ©”λͺ¨λ¦¬μ™€ 데이터 νƒ€μž…

데이터 νƒ€μž…λ³„ λ©”λͺ¨λ¦¬ 크기

bool     // 1 byte (λΉ„νš¨μœ¨μ : 1 bitλ©΄ μΆ©λΆ„ν•˜μ§€λ§Œ)
char     // 1 byte
int      // 4 bytes (32 bits)
float    // 4 bytes
double   // 8 bytes
long     // 8 bytes
string   // κ°€λ³€ 크기 (문자 수 + 1)

λ©”λͺ¨λ¦¬ μ£Όμ†Œ κ°œλ…

λ©”λͺ¨λ¦¬ = κ±°λŒ€ν•œ 격자 (μΊ”λ²„μŠ€)
각 λ°”μ΄νŠΈλŠ” κ³ μœ ν•œ μ£Όμ†Œ(인덱슀)λ₯Ό 가짐

μ£Όμ†Œ:  0  1  2  3  4  5  6  7  ...
데이터: H  e  l  l  o  \0 72 73 ...

점수 ν”„λ‘œκ·Έλž¨ 예제

// λ‚˜μœ 방법: λ³€μˆ˜ κ°œλ³„ μ„ μ–Έ
int score1 = 72;
int score2 = 73;
int score3 = 33;
float average = (score1 + score2 + score3) / 3.0;

// κ°œμ„ λœ 방법: λ°°μ—΄ μ‚¬μš©
int scores[3];
scores[0] = 72;
scores[1] = 73;
scores[2] = 33;

πŸ“Š λ°°μ—΄ (Arrays)

λ°°μ—΄μ˜ κΈ°λ³Έ κ°œλ…

// λ°°μ—΄ μ„ μ–Έκ³Ό μ΄ˆκΈ°ν™”
int scores[3];          // 크기 3인 μ •μˆ˜ λ°°μ—΄
scores[0] = 72;         // 첫 번째 μš”μ†Œ (인덱슀 0)
scores[1] = 73;         // 두 번째 μš”μ†Œ (인덱슀 1)
scores[2] = 33;         // μ„Έ 번째 μš”μ†Œ (인덱슀 2)

// μ‚¬μš©μž μž…λ ₯으둜 λ°°μ—΄ μ±„μš°κΈ°
for (int i = 0; i < 3; i++)
{
    scores[i] = get_int("Score: ");
}

λ°°μ—΄μ˜ μž₯단점

μž₯점:

  • κ΄€λ ¨ 데이터λ₯Ό λ…Όλ¦¬μ μœΌλ‘œ κ·Έλ£Ήν™”
  • 반볡문으둜 효율적 처리
  • λ©”λͺ¨λ¦¬μ— μ—°μ†μ μœΌλ‘œ μ €μž₯λ˜μ–΄ λΉ λ₯Έ μ ‘κ·Ό

단점:

  • Cμ—μ„œλŠ” λ°°μ—΄ 크기λ₯Ό μžλ™μœΌλ‘œ μ•Œ 수 μ—†μŒ
  • λ°°μ—΄ 경계λ₯Ό λ²—μ–΄λ‚˜λŠ” μ ‘κ·Ό μ‹œ μœ„ν—˜
  • 크기가 고정적 (컴파일 μ‹œμ μ— κ²°μ •)

μƒμˆ˜μ™€ μ „μ—­ λ³€μˆ˜ ν™œμš©

#include <stdio.h>

const int N = 3;  // μ „μ—­ μƒμˆ˜ (λŒ€λ¬Έμž κ΄€λ‘€)

int main(void)
{
    int scores[N];
    
    // λ°°μ—΄ μž…λ ₯
    for (int i = 0; i < N; i++)
    {
        scores[i] = get_int("Score: ");
    }
    
    // 평균 계산
    float average = 0;
    for (int i = 0; i < N; i++)
    {
        average += scores[i];
    }
    average /= N;
    
    printf("Average: %.2f\n", average);
}

ν•¨μˆ˜μ— λ°°μ—΄ μ „λ‹¬ν•˜κΈ°

float calculate_average(int array[], int length)
{
    int sum = 0;
    for (int i = 0; i < length; i++)
    {
        sum += array[i];
    }
    return (float) sum / length;
}

int main(void)
{
    int scores[3] = {72, 73, 33};
    float avg = calculate_average(scores, 3);
    printf("Average: %.2f\n", avg);
}

πŸ”€ λ¬Έμžμ—΄ (Strings)

문자의 본질 이해

// λ¬ΈμžλŠ” μˆ«μžλ‹€
char c1 = 'H';  // ASCII 72
char c2 = 'I';  // ASCII 73
char c3 = '!';  // ASCII 33

printf("%c%c%c\n", c1, c2, c3);  // HI!
printf("%i %i %i\n", c1, c2, c3); // 72 73 33

λ¬Έμžμ—΄ = 문자 λ°°μ—΄

// λ¬Έμžμ—΄μ˜ μ‹€μ œ ꡬ쑰
string s = "HI!";
// λ©”λͺ¨λ¦¬: ['H']['I']['!']['\0']
//          72   73   33    0

// λ°°μ—΄λ‘œ μ ‘κ·Ό κ°€λŠ₯
printf("%c\n", s[0]);  // H
printf("%c\n", s[1]);  // I
printf("%c\n", s[2]);  // !
printf("%c\n", s[3]);  // '\0' (null terminator)

NUL μ’…λ£Œ 문자 (\0)

  • λͺ©μ : λ¬Έμžμ—΄μ˜ 끝을 ν‘œμ‹œ
  • κ°’: 8개의 0 λΉ„νŠΈ (ASCII 0)
  • μ€‘μš”μ„±: λ¬Έμžμ—΄ 길이 κ²°μ •, λ©”λͺ¨λ¦¬ μ˜€λ²„λŸ° λ°©μ§€
  • 크기: λ¬Έμžμ—΄ 길이 + 1λ°”μ΄νŠΈ

λ¬Έμžμ—΄ 길이 계산

#include <string.h>

// μˆ˜λ™μœΌλ‘œ 길이 계산
int string_length(string s)
{
    int length = 0;
    while (s[length] != '\0')
    {
        length++;
    }
    return length;
}

// 라이브러리 ν•¨μˆ˜ μ‚¬μš© (ꢌμž₯)
int main(void)
{
    string name = get_string("Name: ");
    int len = strlen(name);  // string.h의 strlen ν•¨μˆ˜
    printf("Length: %i\n", len);
}

λ¬Έμžμ—΄ 처리 예제

#include <string.h>

// λ¬Έμžμ—΄ 각 문자 좜λ ₯
string s = get_string("Input: ");
printf("Output: ");

for (int i = 0, n = strlen(s); i < n; i++)
{
    printf("%c", s[i]);
}
printf("\n");

νš¨μœ¨μ„± κ°œμ„ :

// λΉ„νš¨μœ¨μ : strlen을 맀번 호좜
for (int i = 0; i < strlen(s); i++)

// 효율적: ν•œ 번만 계산
for (int i = 0, n = strlen(s); i < n; i++)

πŸ”„ λ¬Έμžμ—΄ μ‘°μž‘

λŒ€λ¬Έμž λ³€ν™˜ ν”„λ‘œκ·Έλž¨

#include <ctype.h>

// 방법 1: ASCII κ°’ 직접 μ‘°μž‘
for (int i = 0, n = strlen(s); i < n; i++)
{
    if (s[i] >= 'a' && s[i] <= 'z')
    {
        printf("%c", s[i] - 32);  // μ†Œλ¬Έμžλ₯Ό λŒ€λ¬Έμžλ‘œ
    }
    else
    {
        printf("%c", s[i]);       // κ·ΈλŒ€λ‘œ 좜λ ₯
    }
}

// 방법 2: ctype 라이브러리 μ‚¬μš© (ꢌμž₯)
for (int i = 0, n = strlen(s); i < n; i++)
{
    printf("%c", toupper(s[i]));  // μžλ™μœΌλ‘œ λŒ€λ¬Έμž λ³€ν™˜
}

2차원 λ°°μ—΄: λ¬Έμžμ—΄ λ°°μ—΄

// λ¬Έμžμ—΄ λ°°μ—΄ μ„ μ–Έ
string words[2];
words[0] = "HI!";
words[1] = "BYE!";

// 2차원적 μ ‘κ·Ό
printf("%c", words[0][0]);  // 'H' (첫 번째 λ‹¨μ–΄μ˜ 첫 번째 문자)
printf("%c", words[1][2]);  // 'E' (두 번째 λ‹¨μ–΄μ˜ μ„Έ 번째 문자)

⌨️ λͺ…령쀄 인수 (Command Line Arguments)

기본 ꡬ쑰

#include <stdio.h>

int main(int argc, string argv[])
{
    // argc: argument count (인수 개수)
    // argv: argument vector (인수 λ°°μ—΄)
}

κ°„λ‹¨ν•œ 인사 ν”„λ‘œκ·Έλž¨

int main(int argc, string argv[])
{
    if (argc == 2)
    {
        printf("Hello, %s!\n", argv[1]);
    }
    else
    {
        printf("Hello, world!\n");
    }
    return 0;
}

μ‹€ν–‰ μ˜ˆμ‹œ:

./greet David        # Hello, David!
./greet             # Hello, world!
./greet David Malan # Hello, world! (argc = 3μ΄λ―€λ‘œ)

argv λ°°μ—΄ ꡬ쑰

λͺ…λ Ήμ–΄: ./greet David Malan

argv[0] = "./greet"    (ν”„λ‘œκ·Έλž¨ 이름, 항상 포함)
argv[1] = "David"      (첫 번째 인수)
argv[2] = "Malan"      (두 번째 인수)
argc = 3               (총 인수 개수)

λͺ¨λ“  인수 좜λ ₯ν•˜κΈ°

int main(int argc, string argv[])
{
    for (int i = 0; i < argc; i++)
    {
        printf("argv[%i]: %s\n", i, argv[i]);
    }
    return 0;
}

μ’…λ£Œ μƒνƒœ (Exit Status)

int main(int argc, string argv[])
{
    if (argc != 2)
    {
        printf("Missing command-line argument\n");
        return 1;  // 였λ₯˜ μƒνƒœ
    }
    
    printf("Hello, %s!\n", argv[1]);
    return 0;  // 성곡 μƒνƒœ
}

μ’…λ£Œ μƒνƒœ 확인:

./status David
echo $?  # 0 (성곡)

./status
echo $?  # 1 (μ‹€νŒ¨)

πŸ” μ•”ν˜Έν™” 기초 (Cryptography)

μ•”ν˜Έν™”μ˜ κ°œλ…

평문(Plaintext) β†’ [μ•”ν˜Έν™” μ•Œκ³ λ¦¬μ¦˜ + ν‚€] β†’ μ•”ν˜Έλ¬Έ(Ciphertext)

핡심 μš”μ†Œ:

  • 평문: μ›λž˜ λ©”μ‹œμ§€ (예: β€œHI!”)
  • μ•”ν˜Έλ¬Έ: μ•”ν˜Έν™”λœ λ©”μ‹œμ§€ (예: β€œIJ!”)
  • ν‚€: μ•”ν˜Έν™”/λ³΅ν˜Έν™”μ— μ‚¬μš©λ˜λŠ” λΉ„λ°€ κ°’
  • μ•Œκ³ λ¦¬μ¦˜: μ•”ν˜Έν™” 방법 (예: Caesar cipher)

Caesar Cipher (μ‹œμ € μ•”ν˜Έ)

// μ•”ν˜Έν™”: 각 문자λ₯Ό ν‚€λ§ŒνΌ 이동
char plaintext = 'H';  // ASCII 72
int key = 1;
char ciphertext = plaintext + key;  // 'I' (ASCII 73)

// λ³΅ν˜Έν™”: ν‚€λ§ŒνΌ μ—­λ°©ν–₯ 이동
char decrypted = ciphertext - key;  // 'H'

ROT13 μ•”ν˜Έν™”

#include <ctype.h>

void rot13(string text)
{
    for (int i = 0, n = strlen(text); i < n; i++)
    {
        if (isalpha(text[i]))
        {
            if (islower(text[i]))
            {
                // μ†Œλ¬Έμž 처리 (a=97, z=122)
                printf("%c", (text[i] - 'a' + 13) % 26 + 'a');
            }
            else
            {
                // λŒ€λ¬Έμž 처리 (A=65, Z=90)
                printf("%c", (text[i] - 'A' + 13) % 26 + 'A');
            }
        }
        else
        {
            printf("%c", text[i]);  // λ¬Έμžκ°€ μ•„λ‹Œ 경우 κ·ΈλŒ€λ‘œ
        }
    }
}

μ•”ν˜Έν™” ν”„λ‘œκ·Έλž¨ 예제

int main(int argc, string argv[])
{
    if (argc != 2)
    {
        printf("Usage: ./caesar key\n");
        return 1;
    }
    
    int key = atoi(argv[1]);  // λ¬Έμžμ—΄μ„ μ •μˆ˜λ‘œ λ³€ν™˜
    string plaintext = get_string("Plaintext: ");
    
    printf("Ciphertext: ");
    for (int i = 0, n = strlen(plaintext); i < n; i++)
    {
        if (isalpha(plaintext[i]))
        {
            // μ•ŒνŒŒλ²³ 문자만 μ•”ν˜Έν™”
            char base = isupper(plaintext[i]) ? 'A' : 'a';
            printf("%c", (plaintext[i] - base + key) % 26 + base);
        }
        else
        {
            printf("%c", plaintext[i]);  // κ·Έ μ™ΈλŠ” κ·ΈλŒ€λ‘œ
        }
    }
    printf("\n");
    
    return 0;
}

🎯 ν”„λ‘œκ·Έλž˜λ° 원칙과 λͺ¨λ²” 사둀

효율적인 μ½”λ“œ μž‘μ„±

// λΉ„νš¨μœ¨μ : ν•¨μˆ˜λ₯Ό 반볡 호좜
for (int i = 0; i < strlen(s); i++)
{
    // strlen이 맀번 호좜됨
}

// 효율적: ν•œ 번만 계산
for (int i = 0, n = strlen(s); i < n; i++)
{
    // strlen이 ν•œ 번만 호좜됨
}

μƒμˆ˜ μ‚¬μš©ν•˜κΈ°

// λ‚˜μœ 예: 맀직 λ„˜λ²„
int scores[3];
for (int i = 0; i < 3; i++) { /* ... */ }
float average = sum / 3.0;

// 쒋은 예: μƒμˆ˜ μ‚¬μš©
const int N = 3;
int scores[N];
for (int i = 0; i < N; i++) { /* ... */ }
float average = sum / (float) N;

λ²”μœ„(Scope) 관리

// μ „μ—­ λ³€μˆ˜ (λͺ¨λ“  ν•¨μˆ˜μ—μ„œ μ ‘κ·Ό κ°€λŠ₯)
const int MAX_STUDENTS = 50;

int main(void)
{
    // μ§€μ—­ λ³€μˆ˜ (main ν•¨μˆ˜μ—μ„œλ§Œ μ ‘κ·Ό κ°€λŠ₯)
    int scores[MAX_STUDENTS];
    
    for (int i = 0; i < MAX_STUDENTS; i++)  // iλŠ” λ£¨ν”„μ—μ„œλ§Œ 유효
    {
        scores[i] = get_int("Score: ");
    }
    // printf("%d", i);  // 였λ₯˜: iλŠ” μ—¬κΈ°μ„œ μ ‘κ·Ό λΆˆκ°€
}

πŸš€ λ‹€μŒ 단계

이번 μ£Όμ°¨μ—μ„œ 배운 핡심 κ°œλ…

  1. 컴파일 κ³Όμ •: μ „μ²˜λ¦¬ β†’ 컴파일 β†’ μ–΄μ…ˆλΈ” β†’ 링킹
  2. λ©”λͺ¨λ¦¬ ꡬ쑰: λ°”μ΄νŠΈ λ‹¨μœ„μ˜ μ£Όμ†Œ 체계
  3. λ°°μ—΄: μ—°μ†λœ λ©”λͺ¨λ¦¬μ— 같은 νƒ€μž… 데이터 μ €μž₯
  4. λ¬Έμžμ—΄: null μ’…λ£Œ 문자 λ°°μ—΄
  5. 디버깅: printf, debugger, rubber duck
  6. λͺ…령쀄 인수: ν”„λ‘œκ·Έλž¨ μ‹€ν–‰ μ‹œ λ§€κ°œλ³€μˆ˜ 전달
  7. μ•”ν˜Έν™”: 데이터 λ³΄μ•ˆμ˜ κΈ°λ³Έ 원리

μ•žμœΌλ‘œ 배울 λ‚΄μš©

  • 포인터: λ©”λͺ¨λ¦¬ μ£Όμ†Œ 직접 μ‘°μž‘
  • 동적 λ©”λͺ¨λ¦¬ ν• λ‹Ή: mallocκ³Ό free
  • 자료ꡬ쑰: μ—°κ²° 리슀트, μŠ€νƒ, 큐
  • μ•Œκ³ λ¦¬μ¦˜: μ •λ ¬, 검색, μž¬κ·€
  • 파일 μž…μΆœλ ₯: 데이터 μ˜μ†μ„±

싀무 연결점

  • μ‹œμŠ€ν…œ ν”„λ‘œκ·Έλž˜λ°: 운영체제, λ“œλΌμ΄λ²„ 개발
  • μž„λ² λ””λ“œ μ‹œμŠ€ν…œ: IoT, 마이크둜컨트둀러
  • κ²Œμž„ 개발: λ©”λͺ¨λ¦¬ μ΅œμ ν™”, μ„±λŠ₯ νŠœλ‹
  • λ³΄μ•ˆ: μ•”ν˜Έν™”, ν•΄μ‹œ ν•¨μˆ˜, λ””μ§€ν„Έ μ„œλͺ…

πŸ’‘ 마무리 λ©”μ‹œμ§€

이번 κ°•μ˜μ—μ„œλŠ” μ»΄ν“¨ν„°μ˜ λ‚΄λΆ€ λ™μž‘ 원리λ₯Ό 깊이 있게 μ‚΄νŽ΄λ³΄μ•˜μŠ΅λ‹ˆλ‹€. μ†ŒμŠ€μ½”λ“œκ°€ μ–΄λ–»κ²Œ μ‹€ν–‰ κ°€λŠ₯ν•œ ν”„λ‘œκ·Έλž¨μ΄ λ˜λŠ”μ§€, λ©”λͺ¨λ¦¬μ—μ„œ 데이터가 μ–΄λ–»κ²Œ μ €μž₯되고 κ΄€λ¦¬λ˜λŠ”μ§€ μ΄ν•΄ν•˜κ²Œ λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

λ°°μ—΄κ³Ό λ¬Έμžμ—΄μ€ ν”„λ‘œκ·Έλž˜λ°μ˜ 기초 μ€‘μ˜ κΈ°μ΄ˆμž…λ‹ˆλ‹€. 이듀을 잘 μ΄ν•΄ν•˜λ©΄ 더 λ³΅μž‘ν•œ μžλ£Œκ΅¬μ‘°λ„ μ‰½κ²Œ 이해할 수 μžˆμŠ΅λ‹ˆλ‹€. Cμ–Έμ–΄μ—μ„œ λ¬Έμžμ—΄μ΄ λ‹¨μˆœνžˆ 문자 λ°°μ—΄μ΄λΌλŠ” 사싀을 μ΄ν•΄ν–ˆλ‹€λ©΄, λ‹€λ₯Έ μ–Έμ–΄μ˜ λ¬Έμžμ—΄ μ²˜λ¦¬λ„ 훨씬 λͺ…ν™•ν•΄μ§ˆ κ²ƒμž…λ‹ˆλ‹€.

디버깅은 ν”„λ‘œκ·Έλž˜λ° μ‹€λ ₯의 ν•΅μ‹¬μž…λ‹ˆλ‹€. printf둜 μ‹œμž‘ν•΄μ„œ 전문적인 디버거 μ‚¬μš©λ²•κΉŒμ§€ μ΅ν˜”λ‹€λ©΄, λ³΅μž‘ν•œ 버그도 μ²΄κ³„μ μœΌλ‘œ ν•΄κ²°ν•  수 μžˆμŠ΅λ‹ˆλ‹€. λŸ¬λ²„λ• λ””λ²„κΉ…μ²˜λŸΌ κ°„λ‹¨ν•œ 기법도 λ†€λΌμšΈ μ •λ„λ‘œ νš¨κ³Όμ μž„μ„ κΈ°μ–΅ν•˜μ„Έμš”.

λ©”λͺ¨λ¦¬ 관리와 νš¨μœ¨μ„± κ³ λ €λŠ” 쒋은 ν”„λ‘œκ·Έλž˜λ¨Έμ˜ ν•„μˆ˜ 덕λͺ©μž…λ‹ˆλ‹€. strlen을 반볡 ν˜ΈμΆœν•˜μ§€ μ•ŠκΈ°, μƒμˆ˜ μ‚¬μš©ν•˜κΈ° λ“±μ˜ μž‘μ€ μŠ΅κ΄€λ“€μ΄ λͺ¨μ—¬ 큰 차이λ₯Ό λ§Œλ“­λ‹ˆλ‹€.

λ§ˆμ§€λ§‰μœΌλ‘œ μ•”ν˜Έν™”λŠ” ν˜„λŒ€ λ””μ§€ν„Έ μ„Έμƒμ˜ ν•„μˆ˜ μš”μ†Œμž…λ‹ˆλ‹€. κ°„λ‹¨ν•œ Caesar cipherλΆ€ν„° μ‹œμž‘ν–ˆμ§€λ§Œ, 이것이 RSA, AES 같은 ν˜„λŒ€ μ•”ν˜Έν™” 기술의 κΈ°μ΄ˆκ°€ λ©λ‹ˆλ‹€. 데이터 λ³΄μ•ˆμ˜ μ€‘μš”μ„±μ„ 항상 염두에 두고 ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜μ„Έμš”.