Array and Struct: 두 판 사이의 차이

youngwiki
새 문서: 상위 문서: Assembly ==개요== 해당 문서에서는 1차원 배열(array)와, 다차원 배열, 그리고 포인터 배열의 특성에 대해 다룬다. 또한 구조체(struct)를 선언할 때, 구조체가 메모리에 어떻게 배치되는지와 정렬 및 패딩(padding) 규칙이 구조체에 어떤 영향을 미치는지에 대해 다룬다. ==Array== C에서는 기본적으로 아래와 같이 배열을 선언한다: T A[N]; 파일:Array allocation examp...
 
편집 요약 없음
51번째 줄: 51번째 줄:
배열과 포인터는 밀접한 관계가 있지만, 동일하지 않다. char str1[32];과 같이 배열 이름은 포인터처럼 사용될 수 있지만, 진짜 포인터 변수는 아니다. 이는 아래의 예시 코드를 통해서 알아볼 수 있다.
배열과 포인터는 밀접한 관계가 있지만, 동일하지 않다. char str1[32];과 같이 배열 이름은 포인터처럼 사용될 수 있지만, 진짜 포인터 변수는 아니다. 이는 아래의 예시 코드를 통해서 알아볼 수 있다.
<syntaxhighlight lang="c">
<syntaxhighlight lang="c">
char str1[32];
char str1[32];
char str2[64];
char str2[64];
char *p = str1;
char *p = str1;
61번째 줄: 61번째 줄:
</syntaxhighlight>
</syntaxhighlight>
위의 코드에서는 마지막 줄이 컴파일 오류를 야기한다. 이는 배열 이름은 사실상 상수와 같이 동작하므로, 재할당이 불가하기 때문이다. 하지만 그 외에는 사실상 포인터와 같이 동작하므로, 서로 호환되어 사용되는 것을 보여준다.
위의 코드에서는 마지막 줄이 컴파일 오류를 야기한다. 이는 배열 이름은 사실상 상수와 같이 동작하므로, 재할당이 불가하기 때문이다. 하지만 그 외에는 사실상 포인터와 같이 동작하므로, 서로 호환되어 사용되는 것을 보여준다.
===Multi-dimensional (2D) Array===
C에서는 다음과 같이 2차원 배열을 선언한다:
<syntaxhighlight lang="c">
T A[N][M];
</syntaxhighlight>
이는 N행 M열의 2차원 배열을 선언하고, 선언된 배열의 메모리 크기는 <code>N * M * sizeof(T)</code>이다. 이때 이차원 배열의 각 원소들의 저장 순서는 row-major order와 column-major order로 나뉜다.


==각주==
==각주==
[[분류:컴퓨터 시스템]]
[[분류:컴퓨터 시스템]]

2025년 5월 13일 (화) 03:48 판

상위 문서: Assembly

개요

해당 문서에서는 1차원 배열(array)와, 다차원 배열, 그리고 포인터 배열의 특성에 대해 다룬다. 또한 구조체(struct)를 선언할 때, 구조체가 메모리에 어떻게 배치되는지와 정렬 및 패딩(padding) 규칙이 구조체에 어떤 영향을 미치는지에 대해 다룬다.

Array

C에서는 기본적으로 아래와 같이 배열을 선언한다:

T A[N];
Figure 1. Array allocation example
Figure 1. Array allocation example

T는 배열의 원소(element)의 자료형, N는 배열에 최대로 저장될 수 있는 원소의 수에 해당한다. 위 명령어를 통해 총 N * sizeof(T) 바이트의 연속적인 메모리 할당이 이뤄진다. 예를 들어, char *p[3];와 같은 명령어는 포인터 자료형의 크기가 8바이트이므로, 총 24바이트의 공간이 할당된다. 이는 figure 1이 잘 보여준다.

Array Access

기본적으로 배열 이름 A는 배열의 첫 원소의 시작 주소를 지정하는 포인터처럼 작동한다. 예를 들어, 배열 val이 figure 2와 같이 선언되었을 때, 배열 이름 val에 대한 산술 연산은 아래와 같이 작동한다.

Figure 2. Array access example
Figure 2. Array access example
Expression Type Value
val int* x
&val[1] or val + 1 int* x + 1 * 4
val[1] or *(val + 1) int 5
&val[i] or val + i int* x + i * 4

아래는 배열의 원소에 접근하는 C언어 기반의 함수와, 동일한 작업을 수행하는 어셈블리 코드이다.

int get_elem(int* arr, long idx) {
  return arr[idx];
}
get_elem:
  mov (%rdi,%rsi,4), %eax
  ret

위 어셈블리 코드에서 %rdi는 배열의 시작 주소를 의미하며, %rsi는 인덱스를 의미한다. 따라서, arr[idx]%rdi + 4 * %rsi에 위치한 원소이다.

Array vs. Pointer in C

배열과 포인터는 밀접한 관계가 있지만, 동일하지 않다. char str1[32];과 같이 배열 이름은 포인터처럼 사용될 수 있지만, 진짜 포인터 변수는 아니다. 이는 아래의 예시 코드를 통해서 알아볼 수 있다.

char str1[32];
char str2[64];
char *p = str1;
printf("%p vs. %p\n", str1, p); 
printf("sizeof(str1) = %ld\n", sizeof(str1)); // 배열의 크기 = 32 
printf("sizeof(p) = %ld\n", sizeof(p)); //포인터 크기 = 8
p = str2; //char* 포인터에 배열 이름 할당은 괜찮음
str2 = p; //이는 컴파일 오류를 야기

위의 코드에서는 마지막 줄이 컴파일 오류를 야기한다. 이는 배열 이름은 사실상 상수와 같이 동작하므로, 재할당이 불가하기 때문이다. 하지만 그 외에는 사실상 포인터와 같이 동작하므로, 서로 호환되어 사용되는 것을 보여준다.

Multi-dimensional (2D) Array

C에서는 다음과 같이 2차원 배열을 선언한다:

T A[N][M];

이는 N행 M열의 2차원 배열을 선언하고, 선언된 배열의 메모리 크기는 N * M * sizeof(T)이다. 이때 이차원 배열의 각 원소들의 저장 순서는 row-major order와 column-major order로 나뉜다.

각주