Post

🐒 chap2. μ†ŒμŠ€ μ½”λ“œμ—μ„œ 이진 파일둜

⭐ 2.1 ν‘œμ€€ 컴파일 νŒŒμ΄ν”„λΌμΈ

λ„€ 가지 μš”μ†Œλ‘œ κ΅¬μ„±λœ νŒŒμ΄ν”„λΌμΈ

  • μ „μ²˜λ¦¬κΈ°
  • 컴파일러
  • μ–΄μ…ˆλΈ”λŸ¬
  • 링컀
    • νŒŒμ΄ν”„λΌμΈ λ‚΄λΆ€μ˜ 각 μ»΄ν¬λ„ŒνŠΈλŠ” 이전 μš”μ†Œλ‘œλΆ€ν„° νŠΉμ •ν•œ μž…λ ₯값을 λ°›κ³ , λ‹€μŒ μ»΄ν¬λ„ŒνŠΈλ₯Ό μœ„ν•œ νŠΉμ • 결괏값을 μƒμ„±ν•©λ‹ˆλ‹€.
    • μ»΄ν¬λ„ŒνŠΈ 쀑 μ–΄λŠ μž‘μ€ ν•œ 단계라도 μ‹€νŒ¨ν•œλ‹€λ©΄ μ΄λŠ” 컴파일 μ‹€νŒ¨ λ˜λŠ” 링크 μ‹€νŒ¨λ‘œ 이어지고, 그에 κ΄€λ ¨λœ 였λ₯˜ λ©”μ‹œμ§€κ°€ λ“±μž₯ν•©λ‹ˆλ‹€.
      • 재배치 κ°€λŠ₯ν•œ λͺ©μ νŒŒμΌκ³Ό 같은 μ–΄λ–€ 쀑간 결과물은 μ†ŒμŠ€νŒŒμΌ ν•˜λ‚˜κ°€ μ„Έ 가지 μš”μ†Œ(μ „μ²˜λ¦¬κΈ°, 컴파일러, μ–΄μ…ˆλΈ”λŸ¬)만 μ„±κ³΅μ μœΌλ‘œ ν†΅κ³Όν•˜λ©΄ λ§Œλ“€μ–΄μ§‘λ‹ˆλ‹€.
      • λ§μ»€λŠ” 더 큰 결과물을 λ§Œλ“€ λ•Œ μ‚¬μš©ν•˜λŠ”λ°, μ‹€ν–‰ κ°€λŠ₯ν•œ λͺ©μ  파일이라고 ν•©λ‹ˆλ‹€. μ†ŒμŠ€ νŒŒμΌμ„ λΉŒλ“œν•˜λ©΄ ν•˜λ‚˜ λ˜λŠ” μ—¬λŸ¬κ°œμ˜ λͺ©μ νŒŒμΌμ„ λ§Œλ“€ 수 μžˆμŠ΅λ‹ˆλ‹€.
  • ν”Œλž«νΌ

    ν•˜λ“œμ›¨μ–΄μ—μ„œ μ‹€ν–‰λ˜λŠ” 운영체제의 κ²°ν•©.

    • 크둜슀 ν”Œλž«νΌμ™€ 이식 κ°€λŠ₯ν•œμ˜ 차이점 : 크둜슀 ν”Œλž«νΌμ€ 각 ν”Œλž«νΌμ— 따라 λ‹€λ₯Έ μ΄μ§„νŒŒμΌκ³Ό μΈμŠ€ν†¨λŸ¬κ°€ μžˆμŠ΅λ‹ˆλ‹€. 이식 κ°€λŠ₯ν•œ μ†Œν”„νŠΈμ›¨μ–΄λŠ” λͺ¨λ“  ν”Œλž«νΌμ—μ„œ 같은 이진 파일과 μΈμŠ€ν†¨λŸ¬λ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.
      • gcc와 clang 같은 Cμ»΄νŒŒμΌλŸ¬λŠ” 크둜슀 ν”Œλž«νΌ, μžλ°”μ˜ λ°”μ΄νŠΈ μ½”λ“œλŠ” 이식 κ°€λŠ₯ν•©λ‹ˆλ‹€.
      • C/C++μ½”λ“œκ°€ 이식 κ°€λŠ₯ν•˜λ‹€ 함은 μ†ŒμŠ€ μ½”λ“œμ— μ–΄λ–€ν•œ λ³€κ²½μ΄λ‚˜ μˆ˜μ •μ„ κ±°μΉ˜μ§€ μ•Šκ³  μ„œλ‘œ λ‹€λ₯Έ ν”Œλž«νΌμ—μ„œ 컴파일 ν•  수 μžˆλ‹€λŠ” λ§μž…λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ μ΅œμ’… λͺ©μ νŒŒμΌμ— 이식성이 μžˆλ‹€λŠ” μ˜λ―ΈλŠ” μ•„λ‹™λ‹ˆλ‹€.

2.1.1 ν”„λ‘œμ νŠΈ λΉŒλ“œν•˜κΈ°

β˜‘οΈ 헀더 파일 vs μ†ŒμŠ€ 파일

  • 헀더 파일 : ν™•μž₯μžκ°€ .h인 파일
  • μ†ŒμŠ€ 파일 : ν™•μž₯μžκ°€ .c인 파일

헀더 νŒŒμΌμ€ 주둜 μ—΄κ±°ν˜•, 맀크둜, ν˜•μ‹ μ •μ˜, ν•¨μˆ˜μ˜ μ„ μ–Έ, μ „μ—­ λ³€μˆ˜, ꡬ쑰체도 ν¬ν•¨ν•©λ‹ˆλ‹€. ν”„λ‘œκ·Έλž˜λ° μš”μ†Œμ˜ 선언을 νŒŒμΌμ— μ •λ¦¬ν•΄λ‘‘λ‹ˆλ‹€.

β€»μ†ŒμŠ€ 파일 μ•ˆμ— λ‹€λ₯Έ μ†ŒμŠ€ νŒŒμΌμ„ ν¬ν•¨ν•˜λŠ” 것은 잘λͺ»λœ κ²½μš°μž…λ‹ˆλ‹€.

ν•¨μˆ˜ 선언은 λ°˜ν™˜ν˜•κ³Ό ν•¨μˆ˜ μ‹œκ·Έλ‹ˆμ²˜λ‘œ κ΅¬μ„±λ©λ‹ˆλ‹€.

1
dobule average(int*, int);

β˜‘οΈν•¨μˆ˜ μ •μ˜

1
2
3
4
5
6
7
8
9
10
double average(int* array, int length){
	if(length <= 0 ){
		return 0;
	}
	double sum = 0.0;
	for(int i = 0; i<length; i++){
		sum += array[i];
	}
	return sum/ length;
}

μ€‘κ΄„ν˜Έλ‘œ 감싸인 λͺΈμ²΄κ°€ 있으면 μ •μ˜μž…λ‹ˆλ‹€.

  • mainν•¨μˆ˜

    μ†ŒμŠ€ 파일 쀑 ν•˜λ‚˜λŠ” main ν•¨μˆ˜λ₯Ό ν¬ν•¨ν•˜λŠ”λ°, ν”„λ‘œκ·Έλž¨μ˜ μ§„μž…μ μž…λ‹ˆλ‹€. mainν•¨μˆ˜ μ—†μ΄λŠ” ν”„λ‘œκ·Έλž¨μ˜ μ‹€ν–‰ νŒŒμΌμ„ κ°€μ§ˆ 수 μ—†μŠ΅λ‹ˆλ‹€. μ»΄νŒŒμΌλŸ¬λŠ” ν”„λ‘œκ·Έλž¨ μ‹œμž‘μ μœΌλ‘œ main을 μ°ΎμŠ΅λ‹ˆλ‹€.

  • μ „λ°© μ„ μ–Έ

    ν•¨μˆ˜λ₯Ό μ •μ˜ν•˜κΈ° 이전에 ν•¨μˆ˜λ₯Ό μ„ μ–Έν•˜λŠ” ν–‰μœ„

  • 헀더 κ°€λ“œλ¬Έ

    헀더 파일이 컴파일 될 λ•Œ 두 번 λ˜λŠ” κ·Έ 이상 ν¬ν•¨λ˜λŠ” 것을 λ°©μ§€ν•©λ‹ˆλ‹€.

  • κ·œμΉ™ 1 : μ†ŒμŠ€ 파일만 컴파일, ν—€λ”νŒŒμΌμ€ 컴파일 ν•˜μ§€ μ•ŠλŠ”λ‹€.
  • κ·œμΉ™ 2 : 각 μ†ŒμŠ€ νŒŒμΌμ„ λ”°λ‘œλ”°λ‘œ 컴파일 ν•©λ‹ˆλ‹€., ν•œ λ²ˆμ— μ—¬λŸ¬ νŒŒμΌμ„ 컴파일 ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

β˜‘οΈ 2.1.2 1단계 : μ „μ²˜λ¦¬

1
2
3
4
5
6
7
8
컴파일 νŒŒμ΄ν”„λΌμΈμ˜ 첫 단계 : μ „μ²˜λ¦¬ μž…λ‹ˆλ‹€. 컴파일이 μ‹œμž‘λ˜κΈ° 전에 μ „μ²˜λ¦¬κΈ°κ°€ 헀더 파일의 λ‚΄μš©μ„ λͺ¨μ•„μ„œ ν•˜λ‚˜μ˜  Cμ½”λ“œ λͺΈμ²΄λ‘œ λ§Œλ“­λ‹ˆλ‹€. 그리고, μ „μ²˜λ¦¬κΈ° μ§€μ‹œμž(#include, #defineλ“±)λŠ” 이 λ‹¨κ³„μ—μ„œ λ°˜λ“œμ‹œ ν•΄κ²°λ˜μ–΄μ•Ό ν•©λ‹ˆλ‹€. μ „μ²˜λ¦¬λœ μ½”λ“œλŠ” λ³€ν™˜λ‹¨μœ„λΌκ³  ν•©λ‹ˆλ‹€. λ³€ν™˜λ‹¨μœ„λŠ” 컴파일 λ‹¨μœ„λΌκ³ λ„ ν•©λ‹ˆλ‹€.

```c
$ gcc -E ExtremeC_examples_chapter2_1.c
λ³€ν™˜λ‹¨μœ„ 생성
```

μž…λ ₯κ°’ : μ†ŒμŠ€ 파일, 좜λ ₯κ°’ : λ³€ν™˜λ‹¨μœ„
  • 2.1.3 2단계 : 컴파일

    μž…λ ₯κ°’: λ³€ν™˜λ‹¨μœ„, 좜λ ₯κ°’: μ–΄μ…ˆλΈ”λ¦¬ μ½”λ“œ

    μ»΄νŒŒμΌλŸ¬λŠ” λ³€ν™˜λ‹¨μœ„λ₯Ό ꡬ문 뢄석parseν•˜κ³  이λ₯Ό λŒ€μƒ μ•„ν‚€ν…μ²˜μ— λ§žλŠ” μ–΄μ…ˆλΈ”λ¦¬ μ½”λ“œλ‘œ λ³€ν™˜ν•©λ‹ˆλ‹€.

    λŒ€μƒ μ•„ν‚€ν…μ²˜(호슀트 μ•„ν‚€ν…μ²˜) : ν”„λ‘œκ·Έλž¨μ΄ μ»΄νŒŒμΌλ˜μ–΄ 싀행될 ν•˜λ“œμ›¨μ–΄λ‚˜ CPUλ₯Ό λœ»ν•©λ‹ˆλ‹€.

    1
    2
    3
    
      $ gcc -S ExtermeC_examples_chapter2_1.c
      $ cat ExtemreC_examples_chapter2_1.s
      컴파일 이후 보여진 μ–΄μ…ˆλΈ”λ¦¬ μ½”λ“œ P107
    

    λŒ€μƒ μ•„ν‚€ν…μ²˜ : μ†ŒμŠ€ 파일이 μ»΄νŒŒμΌλ˜μ–΄ 싀행될 μ•„ν‚€ν…μ²˜

    λΉŒλ“œ μ•„ν‚€ν…μ²˜ : μ†ŒμŠ€λ₯Ό 컴파일 ν•  λ•Œ μ‚¬μš©ν•˜λŠ” μ•„ν‚€ν…μ²˜

    예λ₯Ό λ“€μ–΄ : ARM 32 λΉ„νŠΈ λ¨Έμ‹ (λΉŒλ“œμ•„ν‚€ν…μ²˜)μ—μ„œ AMD 64λΉ„νŠΈ ν•˜λ“œμ›¨μ–΄(λŒ€μƒ μ•„ν‚€ν…μ²˜)λ₯Ό μœ„ν•œ Cμ†ŒμŠ€λ₯Ό 컴파일 ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

  • 2.1.4 3단계: μ–΄μ…ˆλΈ”λ¦¬

    μž…λ ₯κ°’ : μ–΄μ…ˆλΈ”λ¦¬ μ½”λ“œ 좜λ ₯κ°’ : 재배치 κ°€λŠ₯ ν•œ λͺ©μ νŒŒμΌ ( 기계어 μ½”λ“œ, 쀑간 λͺ©μ  파일)

    λͺ©μ  파일 : 기계 μˆ˜μ€€μ˜ λͺ…λ Ήμ–΄λ₯Ό ν¬ν•¨ν•˜λŠ” νŒŒμΌμ„ λͺ©μ νŒŒμΌ μ΄λΌν•œλ‹€.

    이진 파일 λ˜λŠ” λͺ©μ νŒŒμΌ 기계 μˆ˜μ€€μ˜ λͺ…λ Ήμ–΄λ₯Ό ν¬ν•¨ν•˜λŠ” νŒŒμΌμ„ κ°€λ¦¬ν‚€λŠ” μ„œλ‘œ 같은 말이닀.

    μœ λ‹‰μŠ€ 계열 μš΄μ˜μ²΄μ œμ—μ„œ μ–΄μ…ˆλΈ”λŸ¬ λ„κ΅¬λŠ” asμž…λ‹ˆλ‹€.

    1
    2
    
      $ as ExtemreC_examples_chapter2_1.s -o ExtemreC_examples_chapter2_1.o
      $
    

    μ–΄μ…ˆλΈ”λ¦¬μ½”λ“œλ‘œ λͺ©μ νŒŒμΌμ„ 생성

    재배치 κ°€λŠ₯ν•œ λͺ©μ  νŒŒμΌμ€ .oν™•μž₯자(μœˆλ„μš°μ—μ„œλŠ” .obj)을 λΆ™μž…λ‹ˆλ‹€.

    컴파일러둜 -cμ˜΅μ…˜μ„ μ „λ‹¬ν•œλ‹€λ©΄ μ „μ²˜λ¦¬, 컴파일, μ–΄μ…ˆλΈ”λ¦¬λ₯Ό ν•œλ²ˆμ— μˆ˜ν–‰ν•©λ‹ˆλ‹€.

    λΉŒλ“œλŠ” 4단계(μ „μ²˜λ¦¬, 컴파일, μ–΄μ…ˆλΈ”λ¦¬, 링크)λ₯Ό μ˜λ―Έν•©λ‹ˆλ‹€.

    1
    2
    3
    
      $ gcc -c ExtremeC_examples_chapter2_1.c -o impl.o
      $ gcc -c ExtremeC_examples_chapter2_1_main.c -o main.o
      $
    

    μ†ŒμŠ€νŒŒμΌμ—μ„œ 재배치 κ°€λŠ₯ν•œ λͺ©μ νŒŒμΌ 생성

  • 2.1.5 4단계: 링크

    μž…λ ₯κ°’ : λͺ©μ νŒŒμΌ κ²°κ³Όκ°’ : μ‹€ν–‰νŒŒμΌ

    μƒˆλ‘œμš΄ μ•„ν‚€ν…μ²˜λ₯Ό μœ„ν•œ ν”„λ‘œκ·Έλž¨μ€ 2가지 쑰건을 μΆ©μ‘±ν•˜λ©΄ λΉŒλ“œ ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

    1. μ–΄μ…ˆλΈ”λ¦¬μ–΄κ°€ μ•Œλ €μ Έ μžˆμŠ΅λ‹ˆλ‹€.
    2. μ œμ‘°μ‚¬μ— μ˜ν•΄ 개발된 ν•„μˆ˜ μ–΄μ…ˆλΈ”λŸ¬ 도ꡬ가 μžˆμ–΄μ•Ό ν•©λ‹ˆλ‹€. 이λ₯Ό μ‚¬μš©ν•΄ μ–΄μ…ˆλΈ”λ¦¬ μ½”λ“œλ₯Ό 그에 ν•΄λ‹Ήν•˜λŠ” 기계어 μˆ˜μ€€ λͺ…λ Ήμ–΄λ‘œ λ³€ν™˜ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

    이 두 쑰건이 λ§Œμ‘±ν•˜λ©΄ μ†ŒμŠ€ μ½”λ“œμ—μ„œ κΈ°κ³„μˆ˜μ€€μ˜ λͺ…λ Ήμ–΄λ₯Ό 생성할 수 μžˆμŠ΅λ‹ˆλ‹€. κ·Έλž˜μ•Ό λͺ©μ  파일 포맷을 μ΄μš©ν•΄ λͺ©μ  파일 μ•ˆμ— 기계 μˆ˜μ€€μ˜ λͺ…λ Ήμ–΄λ₯Ό μ €μž₯ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 예λ₯Ό λ“€λ©΄ ELFλ˜λŠ” Mach-OλΌλŠ” ν˜•νƒœκ°€ 될 수 μžˆμŠ΅λ‹ˆλ‹€.

    기본링컀 ld μ‚¬μš©ν•˜κΈ°

    1
    2
    3
    4
    
      $ ld impl.o main.o
      113μͺ½
      $ gcc impl.o main.o
      $ ./a.out
    

⭐ 1.2 포인터 λ³€μˆ˜

1.2.1 문법

포인터: λ©”λͺ¨λ¦¬ μ£Όμ†Œλ₯Ό μ €μž₯ν•˜λŠ” λ‹¨μˆœν•œ λ³€μˆ˜

  • 예제 1-9

    1
    2
    3
    4
    5
    6
    7
    
      int main(int argc, char** argv) {
        int var = 100;
        int* ptr = 0;
        ptr = &var;
        *ptr = 200;
        return 0;
      }
    

    널 포인터 μ„ μ–Έ, μ°Έμ‘° μ—°μ‚°μž&, μ—­μ°Έμ‘° μ—°μ‚°μž*

    NULL 맀크둜 μ‚¬μš©: λ³€μˆ˜μ™€ 포인터λ₯Ό 더 μ‰½κ²Œ ꡬ뢄

1.2.2 포인터 λ³€μˆ˜μ˜ μ‚°μˆ μ—°μ‚°

μ‚°μˆ μ—°μ‚° 간격: 포인터가 1μ”© 증감할 λ•Œ μ›€μ§μ΄λŠ” λ°”μ΄νŠΈμ˜ 숫자, C μžλ£Œν˜•μ— μ˜ν•΄ 결정됨

  • 예제 1-10

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    
      #include <stdio.h>
        
      int main(int argc, char** argv) {
        int var = 1;
        
        int* int_ptr = NULL; // 포인터λ₯Ό λ„λ‘œ λ§Œλ“€κΈ°
        int_ptr = &var;
        
        char* char_ptr = NULL;
        char_ptr = (char*)&var;
        
        printf("Before arithmetic: int_ptr: %u, char_ptr: %u\n",
                (unsigned int)int_ptr, (unsigned int)char_ptr);
        
        int_ptr++;    // 일반적으둜 μ‚°μˆ μ—°μ‚° 간격은 4λ°”μ΄νŠΈ
        char_ptr++;   // 1λ°”μ΄νŠΈμ˜ μ‚°μˆ μ—°μ‚° 간격
        
        printf("After arithmetic: int_ptr: %u, char_ptr: %u\n",
                (unsigned int)int_ptr, (unsigned int)char_ptr);
        
        return 0;
      }
    

    μ‹€ν–‰ κ²°κ³Ό μ •μˆ˜ ν¬μΈν„°μ˜ μ—°μ‚° 간격은 4λ°”μ΄νŠΈ, λ¬Έμžμ—΄ ν¬μΈν„°λŠ” 1λ°”μ΄νŠΈ

1.2.3 μ œλ„€λ¦­ 포인터

μ œλ„€λ¦­ 포인터: void* μžλ£Œν˜•μ˜ 포인터, μ—­μ°Έμ‘° λΆˆκ°€λŠ₯

  • 예제 1-13

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
      #include <stdio.h>
        
      int main(int argc, char** argv) {
       int var = 9;
       int* ptr = &var;
       void* gptr = ptr;
         
       printf("%d\n", *gptr);
         
       return 0;
      }
    

    μ œλ„€λ¦­ 포인터λ₯Ό μ—­μ°Έμ‘°ν•˜λ©΄ 컴파일 였λ₯˜κ°€ 생성됨

1.2.4 ν¬μΈν„°μ˜ 크기

μ•„ν‚€ν…μ²˜μ— 따라 ν¬μΈν„°μ˜ 크기가 닀름

λŒ€μƒ μ•„ν‚€ν…μ²˜μ—μ„œ sizeof ν•¨μˆ˜ μ‚¬μš©

1.2.5 ν—ˆμƒ 포인터

좩돌 λ˜λŠ” μ„Έκ·Έλ©˜ν…Œμ΄μ…˜ 였λ₯˜ λ°œμƒ

  • 예제 1-15

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    
      #include <stdio.h>
        
      int* create_an_integer(int default_value) {
        int var = default_value;
        return &var;
      }
        
      int main() {
        int* ptr = NULL;
        ptr = create_an_integer(10);
        printf("%d\n", *ptr);
        return 0;
      }
    

    μ„Έκ·Έλ©˜ν…Œμ΄μ…˜ 였λ₯˜ 상황, ptr 포인터가 할당이 ν•΄μ œλœ var의 λ©”λͺ¨λ¦¬ μ˜μ—­μ„ 가리킴(ν—ˆμƒ 포인터)

⭐ 1.3 ν•¨μˆ˜

β˜‘οΈ ν•¨μˆ˜μ˜ ꡬ쑰

ν•¨μˆ˜: 이름과 μž…λ ₯ λ§€κ°œλ³€μˆ˜μ˜ λͺ©λ‘, 좜λ ₯ 결과의 λͺ©λ‘μ„ 가진 논리 μƒμž

C μ–Έμ–΄μ—μ„œ ν•¨μˆ˜λŠ” 단 ν•˜λ‚˜μ˜ κ°’λ§Œμ„ λ°˜ν™˜

λΈ”λ‘œν‚Ή ν•¨μˆ˜: 호좜된 ν•¨μˆ˜κ°€ μ’…λ£Œλ˜μ–΄μ•Όλ§Œ λ°˜ν™˜κ°’μ„ 호좜자 ν•¨μˆ˜κ°€ 받을 수 있음

λ…ΌλΈ”λ‘œν‚Ή ν•¨μˆ˜: 콜백 λ©”μ»€λ‹ˆμ¦˜, 비동기 ν•¨μˆ˜, 사건 기반 ν”„λ‘œκ·Έλž˜λ°(EDP)

β˜‘οΈ μ„€κ³„μ˜ μ€‘μš”μ„±

λ‘œμ§μ„ μž‘μ„± ν›„ λ‹€μ–‘ν•œ κ³³μ—μ„œ μ—¬λŸ¬ 번 μ‚¬μš© κ°€λŠ₯

좔상화: 기쑴의 λ‹€λ₯Έ λ‘œμ§μœΌλ‘œλΆ€ν„° 일뢀λ₯Ό μˆ¨κΉ€

β˜‘οΈ μŠ€νƒ 관리

μŠ€νƒ μ„Έκ·Έλ¨ΌνŠΈ β†’ λͺ¨λ“  지역 λ³€μˆ˜, λ°°μ—΄, ꡬ쑰체가 ν• λ‹Ήλ˜λŠ” κΈ°λ³Έ λ©”λͺ¨λ¦¬μ˜ μœ„μΉ˜.

μŠ€νƒ ν”„λ ˆμž„ β†’ μŠ€νƒ μ„Έκ·Έλ¨ΌνŠΈμ˜ κ°€μž₯ μœ„μ— 놓이고, ν•¨μˆ˜ 둜직이 μ‹€ν–‰λ©λ‹ˆλ‹€. 호좜이 λλ‚˜λ©΄ μŠ€νƒ ν”„λ ˆμž„μ€ 제거되며 직전 호좜 ν•¨μˆ˜λ‘œ 계속 μ΄μ–΄μ§‘λ‹ˆλ‹€.

  • μŠ€νƒ ν”„λ ˆμž„ μ˜ˆμ‹œ

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
      int main()
      {
      	func1();
      }
        
      void func1()
      {
      	func2();
      }
        
      void func2()
      {
        	
      }
    

μŠ€νƒ μ˜€λ²„ν”Œλ‘œ β†’ μŠ€νƒμ—μ„œλŠ” λ©”λͺ¨λ¦¬κ°€ ν•œμ •μ μž…λ‹ˆλ‹€. ν•˜μ§€λ§Œ ν•¨μˆ˜ ν˜ΈμΆœμ„ λ„ˆλ¬΄ 많이 μ‹€ν–‰ν•΄ μŠ€ν… ν”„λ ˆμž„μ˜ λͺ¨λ“  μŠ€νƒ μ„Έκ·Έλ¨ΌνŠΈλ₯Ό λ‹€ 써버린 κ²½μš°μ— λ°œμƒν•©λ‹ˆλ‹€.

β˜‘οΈ 값에 μ˜ν•œ 전달 vs 참쑰에 μ˜ν•œ 전달

Cμ—λŠ” μ°Έμ‘°κ°€ μ—†μ–΄, 참쑰에 μ˜ν•œ 전달은 μ‘΄μž¬ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

μ˜€λ‘œμ§€ 값에 μ˜ν•œ μ „λ‹¬λ§Œ μ‘΄μž¬ν•©λ‹ˆλ‹€.

  • 값에 μ˜ν•œ 전달 ν•¨μˆ˜ 호좜의 예

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    
      #include <stdio.h>
        
      void swap(int, int);
        
      int main(void)
      {
      	int a = 5, b = 3;
      	printf("before) a = %d, b = %d\n", a, b);
      	swap(a, b);
      	printf("after) a= %d , b = %d\n", a, b);
      	return 0;
      }
        
      void swap(int num1, int num2)
      {
      	int temp = num1;
      	num1 = num2;
      	num2 = temp;
        
      	printf("swap) a = %d , b = %d\n", num1, num2);
      }
        
      /******************************************************
      before) a = 5, b = 3
      swap) a = 3 , b = 5
      after) a= 5 , b = 3
      *******************************************************/
    

포인터λ₯Ό λ³€μˆ˜λ‘œ μ „λ‹¬ν•˜λŠ” 것이 포인터에 μ˜ν•œ μ „λ‹¬μž…λ‹ˆλ‹€.

  • 포인터에 μ˜ν•œ ν•¨μˆ˜ 호좜의 예

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    
      #include <stdio.h>
        
      void func(int* a)
      {
      	int b = 9;
      	*a = 5;     //포인터 μ—­μ°Έμ‘°
      	a = &b;
      }
        
      int main(void)
      {
      	int x = 3;
      	int* xptr = &x;
      	printf("the value before the call = %d \n", x);
      	printf("pointer value before the call = %p\n", xptr);
      	func(xptr);
      	printf("the value after the call = %d \n", x);
      	printf("pointer value after the call=%p \n", xptr);
      	return 0;
      }
        
      /******************************************************
      the value before the call = 3
      pointer value before the call = 0000007032AFF624
      the value after the call = 5
      pointer value after the call=0000007032AFF624
      *******************************************************/
    

    μœ„μ˜ κ²°κ³Όλ₯Ό 보면 ν¬μΈν„°μ˜ 값은 ν•¨μˆ˜ 호좜 이후에도 λ³€ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. μ΄λŠ” 포인터가 값에 μ˜ν•œ 전달 인수둜 μ „λ‹¬λ˜μ—ˆμŒμ„ μ˜λ―Έν•©λ‹ˆλ‹€. 포인터λ₯Ό μ—­μ°Έμ‘°ν•˜λ©΄ ν˜ΈμΆœν•˜λŠ” μͺ½μ˜ ν•¨μˆ˜μ˜ λ³€μˆ˜λ₯Ό μˆ˜μ •ν•  수 μžˆλ„λ‘ ν•©λ‹ˆλ‹€.

⭐ 1.4 ν•¨μˆ˜ 포인터

β˜‘οΈ ν•¨μˆ˜ 포인터

β†’ ν•¨μˆ˜μ˜ μ£Όμ†Œλ₯Ό μ €μž₯ν•˜λ©° ν•¨μˆ˜λ₯Ό κ°„μ ‘μ μœΌλ‘œ ν˜ΈμΆœν•  수 μžˆλ„λ‘ κ΅¬ν˜„ν•©λ‹ˆλ‹€.

β†’ μ΄λ‘œμΈν•΄ 각각의 κΈ°λŠ₯듀을 νŒŒμΌλ³„λ‘œ λ‚˜λ‰˜μ–΄ λ†“λŠ” μž‘μ—…μΈ λͺ¨λ“ˆν™”κ°€ κ°€λŠ₯ν•΄ μ‘ŒμŠ΅λ‹ˆλ‹€.

1
2
3
4
ν•¨μˆ˜ 포인터 λ³€μˆ˜ μ„ μ–Έ = int (*fptr) (int);
int - ν•΄λ‹Ή ν•¨μˆ˜μ˜ λ°˜ν™˜ν˜•
(*fptr) - 포인터 λ³€μˆ˜
(int) - ν•΄λ‹Ήν•¨μˆ˜μ˜ λ§€κ°œλ³€μˆ˜μ˜ ν˜•νƒœ
  • λ‹€λ₯Έ ν•¨μˆ˜ μ—¬λŸ¬ 개λ₯Ό ν˜ΈμΆœν•˜λŠ” ν•˜λ‚˜μ˜ ν•¨μˆ˜ 포인터

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    
      #include <stdio.h>
        
      int sum(int a, int b)     // νƒ€μž… λ³„μΉ­μœΌλ‘œ ν•΄λ‘λŠ” 편이 μ’‹μŠ΅λ‹ˆλ‹€.
      {
      	return a + b;
      }
        
      int subtract(int a, int b)
      {
      	return a - b;
      }
        
      int main()
      {
        
      	int(*func_ptr)(int, int);
      	func_ptr = NULL;          // ν•¨μˆ˜ 포인터도 NULL둜 μ΄ˆκΈ°ν™”λ₯Ό ν•΄μ£Όμ–΄μ•Όν•©λ‹ˆλ‹€.
        
      	func_ptr = &sum;
      	int result = func_ptr(5, 4);
      	printf("Sum = %d\n", result);
        
      	func_ptr = &subtract;
      	result = func_ptr(5, 4);
      	printf("subtract = %d\n", result);
        
      	return 0;
      }
        
      Sum = 9
      subtract = 1
    
  • μ—¬λŸ¬κ°œμ˜ λ‹€λ₯Έ ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜λŠ” ν•˜λ‚˜μ˜ ν•¨μˆ˜ 포인터

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    
      #include <stdio.h>
        
      typedef int bool_t;
      typedef bool_t(*less_than_func_t)(int, int);
        
      bool_t less_than(int a, int b)
      {
      	return a < b ? 1 : 0;
      }
        
      bool_t less_than_modular(int a, int b)
      {
      	return (a % 5) < (b % 5) ? 1 : 0;
      }
        
      int main(void)
      {
      	less_than_func_t func_ptr = NULL;
        
      	func_ptr = &less_than;
      	bool_t result = func_ptr(3, 7);
      	printf("%d\n", result);
        
      	func_ptr = &less_than_modular;
      	result = func_ptr(3, 7);
      	printf("%d\n", result);
      	return 0;
      }
        
      1
      0
    

⭐ 1.5 ꡬ쑰체

β˜‘οΈ μ™œ ꡬ쑰체인가?

β†’ μ›μ‹œ μžλ£Œν˜• (PDT) = 자료ꡬ쑰λ₯Ό 섀계할 수 있고, μ•Œκ³ λ¦¬μ¦˜μ„ μž‘μ„± ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

ex) int, double

β†’ μ‚¬μš©μž μ •μ˜ μžλ£Œν˜• (UDT) = 직접 μ •μ˜ν•œ μžλ£Œν˜•μ΄ ν•„μš”ν•˜κ³ , ν”„λ‘œκ·Έλž˜λ° μ–Έμ–΄μ˜ μžλ£Œν˜•μœΌλ‘œλŠ” μΆ©λΆ„ν•˜μ§€ μ•Šμ„ λ•Œ μ‚¬μš©ν•©λ‹ˆλ‹€. struct ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.

ex) ꡬ쑰체

(κ΅¬μ‘°μ²΄λŠ” ν•˜λ‚˜ μ΄μƒμ˜ λ³€μˆ˜λ₯Ό ν•˜λ‚˜λ‘œ 묢을 수 μžˆλŠ” 볡합 μžλ£Œν˜•μ΄λ―€λ‘œ κΈ°λ³Έ μžλ£Œν˜• λ³€μˆ˜λ₯Ό λ¬Άμ–΄μ„œ μƒˆλ‘œμš΄ μžλ£Œν˜•μ„ λ§Œλ“  것이기 λ•Œλ¬Έμ— μ‚¬μš©μž μ •μ˜ μžλ£Œν˜•μœΌλ‘œ κ΅¬λΆ„λ©λ‹ˆλ‹€.)

β†’ λ‹€μ–‘ν•œ ν˜•νƒœμ˜ 데이터λ₯Ό μ²˜λ¦¬ν•  λ•Œ μœ μš©ν•©λ‹ˆλ‹€.

β˜‘οΈ μ™œ μ‚¬μš©μž μ •μ˜ μžλ£Œν˜•μΈκ°€?

같은 λŒ€μƒμ— μ„œλ‘œ μ—°κ΄€λœ 속성을 그룹으둜 λ¬ΆλŠ”κ²ƒμ΄ 가독성이 μ’‹μŠ΅λ‹ˆλ‹€. 더 κ³ μˆ˜μ€€μ˜ 둜직, 인간 μˆ˜μ€€μ˜ 둜직과 μΆ©λΆ„νžˆ λΉ„μŠ·ν•˜κ²Œ 문제λ₯Ό λΆ„μ„ν•˜λ €λ©΄ μƒˆλ‘œμš΄ μžλ£Œν˜•μ΄ ν•„μš”ν•©λ‹ˆλ‹€.

ex) λΉ„μ¦ˆλ‹ˆμŠ€ 둜직 -은행(고객, μž”κ³ , 돈, ν˜„κΈˆ, μ§€λΆˆ) κ°œλ…μ„ λ§ˆμ£Όν•˜κ³ , 은행 λ‘œμ§μ„ κ°œλ°œν•˜κΈ° μœ„ν•΄μ„œλŠ” κ°œλ°œμžμ™€ λΉ„μ¦ˆλ‹ˆμŠ€ λΆ„μ„κ°€λŠ” ν˜‘λ ₯ν•˜λ©° κ·œμΉ™, 둜직, μš©μ–΄μ§‘λ“±μ„ κ³΅μœ ν•΄μ•Όν•©λ‹ˆλ‹€.

β˜‘οΈ ꡬ쑰체의 μ—­ν• 

κ΅¬μ‘°μ²΄λŠ” ν•˜λ‚˜μ˜ ν†΅ν•©λœ νƒ€μž…μ•„λž˜ κ΄€λ ¨λœ 값을 κ°­μŠν™” ν•©λ‹ˆλ‹€.

ex) color_t (red, green,blue)

1
2
3
4
5
struct color_t {
	int red;
	int green;
	int blue;
};

β†’ μƒˆλ‘œμš΄ μžλ£Œν˜• μ•„λž˜μ— μ„œλ‘œ 관련이 μžˆλŠ” ν•„λ“œλ₯Ό 그룹으둜 λ¬ΆλŠ” μΊ‘μŠν™” ν•©λ‹ˆλ‹€. 그리고 λ‚˜μ„œ ν•„μš”ν•œ λ³€μˆ˜λ₯Ό μ •μ˜ν•  λ•Œ 이 μƒˆλ‘œμš΄ μžλ£Œν˜•μ„ μ‚¬μš©ν•©λ‹ˆλ‹€.

β˜‘οΈ λ©”λͺ¨λ¦¬ λ ˆμ΄μ•„μ›ƒ

λ©”λͺ¨λ¦¬ λ ˆμ΄μ•„μ›ƒμ΄ ν•„μš”ν•œ 이유 β†’ 값은 λ©”λͺ¨λ¦¬μ— μ €μž₯되고, cpuλŠ” 이 값을 μΆ©λΆ„νžˆ λΉ λ₯΄κ²Œ 읽고 μ“Έ 수 μžˆμ–΄μ•Ό ν•©λ‹ˆλ‹€.

  • ꡬ쑰체 λ³€μˆ˜μ— ν• λ‹Ήλœ λ°”μ΄νŠΈ 수 좜λ ₯ν•˜κΈ°

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    
      #include <stdio.h>
        
      struct sample_t {
          char first;
          char second;
          char third;
          short fourth;
      };
        
      void print_size(struct sample_t* var) {
          printf("Size: %lu bytes\n", sizeof(*var));
      }
        
      void print_bytes(struct sample_t* var) {
          unsigned char* ptr = (unsigned char*)var;
          for (int i = 0; i < sizeof(*var); i++, ptr++) {
              printf("%d ", (unsigned int)*ptr);
          }
          printf("\n");
      }
        
      int main(int argc, char** argv) {
          struct sample_t var;
          var.first = 'A';
          var.second = 'B';
          var.third = 'C';
          var.fourth = 765;
          print_size(&var);
          print_bytes(&var);
          return 0;
      }
        
      Size: 6 bytes
      65 66 67 0 253 2
    

    sizeof(sample_t)λŠ” 6λ°”μ΄νŠΈλ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.

    • charν˜• 3개 shortν˜• 1개 총 5λ°”μ΄νŠΈ μž…λ‹ˆλ‹€. μ΄λŠ” λ©”λͺ¨λ¦¬ 정렬을 μœ„ν•΄ λ°”μ΄νŠΈ 67뒀에 0이 보이게 ν•©λ‹ˆλ‹€. 0λ°”μ΄νŠΈλŠ” ν˜„μž¬ μ›Œλ“œ(cpuκ°€ λ©”λͺ¨λ¦¬μ— μ ‘κ·Όν•  λ•Œ μ½λŠ” νŠΉμ • λ°”μ΄νŠΈμ˜ 수)λ₯Ό μ™„μ„±ν•˜κΈ° μœ„ν•΄ μΆ”κ°€λ˜λ©°, λ„€ 번째 ν•„λ“œκ°€ λ‹€μŒ μ›Œλ“œμ—μ„œ μ‹œμž‘ν•  수 μžˆλ„λ‘ ν•©λ‹ˆλ‹€.
    • μ΄λ•Œ λ©”λͺ¨λ¦¬ μ •λ ¬μ΄λž€ μ‹œμž‘ν•˜λŠ” λ°”μ΄νŠΈκ°€ μ›Œλ“œμ˜ μ‹œμž‘μ μ— μžˆμ„ λ•Œ, 이 λ³€μˆ˜λŠ” λ©”λͺ¨λ¦¬μ— μ •λ ¬ λ˜μ—ˆλ‹€κ³  ν•©λ‹ˆλ‹€.

      1
      2
      3
      4
      
      ex) charν˜•μΈ first, second, thirdλŠ” 각각 1λ°”μ΄νŠΈμ΄λ©° 이듀은 ꡬ쑰체 λ ˆμ΄μ•„μ›ƒμ˜ 첫번째 μ›Œλ“œμ— νƒ‘μž¬ λ©λ‹ˆλ‹€. 이후 fouth λŠ” 2λ°”μ΄νŠΈ μž…λ‹ˆλ‹€. 만일 λ©”λͺ¨λ¦¬ 정렬이 λ˜μ§€ μ•ŠλŠ”λ‹€λ©΄ 첫번째 λ°”μ΄νŠΈλŠ” 첫번째 μ›Œλ“œμ˜ λ§ˆμ§€λ§‰ λ°”μ΄νŠΈκ°€ 되게 λ©λ‹ˆλ‹€.
            
            
      이λ₯Ό λ°©μ§€ν•˜κΈ° μœ„ν•΄ 첫번째 μ›Œλ“œλŠ” 0λ°”μ΄νŠΈ ν•˜λ‚˜κ°€ νŒ¨ν‚Ή(λ©”λͺ¨λ¦¬ 값을 μ •λ ¬)λ˜μ–΄ μžˆλ‹€κ³  ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
      
    • λ©”λͺ¨λ¦¬ 정렬은 기본적으둜 ν™œμ„±ν™”κ°€ λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€.

β˜‘οΈ 쀑첩 ꡬ쑰체

볡합 μžλ£Œν˜• = μ‚¬μš©μž μ •μ˜ μžλ£Œν˜•μ΄κ³ , λͺ‡ 개의 ꡬ쑰체λ₯Ό μ€‘μ²©ν•œ κ²°κ³Όμž…λ‹ˆλ‹€.

  • λͺ‡κ°€μ§€ 쀑첩 ꡬ쑰체

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    
      #include <stdio.h>
        
      typedef struct {
      	int x;			//4byte
      	int y;			//4byte
      }point_t;			//8byte
        
      typedef struct {
      	point_t center;	//8byte
      	int radius;		//4byte
      }circle_t;			//12byte
        
      typedef struct {
      	point_t start;	//8byte
      	point_t end;	//8byte
      }line_t;			//16byte
    

    3개의 ꡬ쑰체인 point_t와 circle_t, line_tκ°€ μ‘΄μž¬ν•©λ‹ˆλ‹€.

    point_t κ΅¬μ‘°μ²΄λŠ” 였직 μ›μ‹œμžλ£Œν˜•μœΌλ‘œλ§Œ κ΅¬μ„±λœ λ‹¨μˆœν•œ μ‚¬μš©μž μ •μ˜ μžλ£Œν˜•μ΄μ§€λ§Œ

    λ‹€λ₯Έ ꡬ쑰체듀은 point_t μžλ£Œν˜•μ˜ λ³€μˆ˜λ₯Ό ν¬ν•¨ν•œ 볡합 μ‚¬μš©μž μ •μ˜ μžλ£Œν˜•μž…λ‹ˆλ‹€.

β˜‘οΈ ꡬ쑰체 포인터

β†’ μ‚¬μš©μž μ •μ˜ μžλ£Œν˜•μ˜ ν¬μΈν„°λŠ” μ›μ‹œ μžλ£Œν˜•μ˜ 포인터와 λ™μΌν•©λ‹ˆλ‹€.

β†’ ꡬ쑰체 λ³€μˆ˜ 포인터가 ꡬ쑰체 λ³€μˆ˜μ˜ 첫 번째 ν•„λ“œμ˜ μ£Όμ†Œλ₯Ό κ°€λ₯΄ν‚΅λ‹ˆλ‹€.

  • λ©”λͺ¨λ¦¬μ—μ„œ λ™μΌν•œ λ°”μ΄νŠΈ μ£Όμ†Œλ₯Ό κ°€λ¦¬ν‚€λŠ” μ„Έ 가지 μžλ£Œν˜•μœΌλ‘œλΆ€ν„° μ–»λŠ” 3개의 포인터

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    
      #include <stdio.h>
        
      typedef struct {
      	int x;
      	int y;
      }point_t;
        
      typedef struct {
      	point_t center;
      	int raduus;
      }circle_t;
        
      int main(void)
      {
      	circle_t c;
        
      	circle_t* p1 = &c;
      	point_t* p2 = (point_t*)&c;
      	int* p3 = (int*)&c;
        
      	printf("p1 = %p\n", (void*)p1);
      	printf("p2 = %p\n", (void*)p2);
      	printf("p3 = %p\n", (void*)p3);
      	return 0;
      }
        
      p1 = 00000039EEB9F738
      p2 = 00000039EEB9F738
      p3 = 00000039EEB9F738
    

    point_t와 circle_t μžλ£Œν˜•μ˜ ν¬μΈν„°λŠ” ꡬ쑰체의 λ³€μˆ˜μ˜ 첫번째 ν•„λ“œμΈ x의 μ£Όμ†Œλ₯Ό κ°€λ¦¬μΌ°μŠ΅λ‹ˆλ‹€.

    typedefλ₯Ό μ‚¬μš©ν•˜λ©΄ ꡬ쑰체의 μƒˆ 별칭 νƒ€μž…μ„ μ„ μ–Έ ν•  수 μžˆμŠ΅λ‹ˆλ‹€. μ΄λŠ” 좔후에 struct ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•˜μ§€ μ•Šκ³  λ³€μˆ˜λ₯Ό μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

This post is licensed under CC BY 4.0 by the author.