C 언어에서 배열 이해하기
C 언어에서 배열은 동일한 데이터 유형의 여러 값을 저장하는 데 사용됩니다. 배열을 사용하면 코드가 더욱 깔끔하고 효율적으로 변할 수 있습니다. 이번 포스팅에서는 C 언어의 배열에 대해 자세히 알아보고, 예제 코드와 함께 사용 방법을 설명드리겠습니다.
1. 배열 선언 및 초기화
배열을 선언하는 방법은 다음과 같습니다:
int arr[5]; // 크기가 5인 정수형 배열 선언
배열을 선언하면서 초기화하는 방법도 있습니다:
int arr[5] = {1, 2, 3, 4, 5}; // 배열 선언과 동시에 초기화
2. 배열 요소 접근
배열의 요소에 접근하고 값을 할당하는 방법은 다음과 같습니다:
arr[0] = 10; // 첫 번째 요소에 10 할당
int value = arr[2]; // 세 번째 요소의 값을 변수에 저장
3. 배열과 반복문
배열과 반복문을 함께 사용하면 배열의 모든 요소를 순회할 수 있습니다. 예를 들어, 배열의 모든 값을 출력하는 코드는 다음과 같습니다:
#include <stdio.h>
int main() {
int arr[5] = {1, 2, 3, 4, 5};
for (int i = 0; i < 5; i++) {
printf("%d\n", arr[i]);
}
return 0;
}
C언어 배열에서 원소 개수 세는 방법 알아보기
C언어로 프로그래밍을 하다 보면 배열을 자주 사용하게 됩니다. 배열은 같은 자료형의 변수들을 하나로 묶어서 관리할 수 있게 해주는 유용한 도구입니다. 이때, 배열에 몇 개의 원소가 있는지 아는 것은 매우 중요합니다. 배열의 크기를 넘어서는 접근은 프로그램 오류를 발생시킬 수 있기 때문입니다.
C언어에서 배열 원소의 개수를 계산하는 방법은 다음과 같습니다.
1. sizeof 연산자 활용
sizeof 연산자는 변수 또는 자료형의 크기를 바이트 단위로 반환합니다. 이를 이용하여 배열의 전체 크기와 배열 원소 하나의 크기를 구한 후, 두 값을 나누어 배열 원소의 개수를 계산할 수 있습니다.
#include <stdio.h>
int main() {
int arr[] = {1, 2, 3, 4, 5};
int count = sizeof(arr) / sizeof(arr[0]);
printf("배열 arr의 원소 개수: %d\n", count); // 출력: 배열 arr의 원소 개수: 5
return 0;
}
코드 설명
sizeof(arr)
: 배열arr
의 전체 크기 (바이트 단위) 를 반환합니다.int
형 변수가 4바이트라고 가정하면 5개 원소의 배열 크기는 20바이트가 됩니다.sizeof(arr[0])
: 배열arr
의 첫 번째 원소의 크기 (바이트 단위) 를 반환합니다. 즉,int
형 변수 하나의 크기인 4바이트를 반환합니다.count
: 배열arr
의 원소 개수를 저장하는 변수입니다. 20바이트 / 4바이트 = 5개가 됩니다.
어디에쓰냐? C언어에서 파일을 읽어드릴때 유용히 사용하는데 이는 나중에 활용성이 커집니다.
C언어 배열 복사하기: 얕은 복사 vs 깊은 복사
C언어에서 배열을 복사하는 방법은 크게 두 가지로 나눌 수 있습니다. 바로 얕은 복사(Shallow Copy)와 깊은 복사(Deep Copy)입니다. 각 방법의 차이점과 장단점을 이해하고 상황에 맞는 방법을 선택하는 것이 중요합니다.
1. 얕은 복사 (Shallow Copy)
얕은 복사는 단순히 배열의 메모리 주소를 복사하는 방법입니다. 즉, 원본 배열과 복사된 배열이 같은 메모리 공간을 공유하게 됩니다. 따라서, 한 배열의 값을 변경하면 다른 배열의 값도 함께 변경됩니다.
장점:
- 빠른 속도: 메모리 주소만 복사하므로 속도가 빠릅니다.
- 메모리 효율성: 새로운 메모리 공간을 할당하지 않아 메모리를 절약할 수 있습니다.
단점:
- 원본 배열의 변경: 복사된 배열에서 값을 변경하면 원본 배열의 값도 변경됩니다.
- 메모리 해제 문제: 원본 배열을 해제하면 복사된 배열도 접근할 수 없게 됩니다.
얕은 복사 예시:
#include <stdio.h>
int main() {
int arr1[] = {1, 2, 3, 4, 5};
int *arr2 = arr1; // arr2는 arr1의 메모리 주소를 가리킴
arr2[0] = 10; // arr2의 첫 번째 요소를 변경
printf("arr1: ");
for (int i = 0; i < 5; i++) {
printf("%d ", arr1[i]); // 출력: arr1: 10 2 3 4 5
}
printf("\n");
printf("arr2: ");
for (int i = 0; i < 5; i++) {
printf("%d ", arr2[i]); // 출력: arr2: 10 2 3 4 5
}
printf("\n");
return 0;
}
2. 깊은 복사 (Deep Copy)
깊은 복사는 원본 배열의 값을 복사하여 새로운 메모리 공간에 저장하는 방법입니다. 즉, 원본 배열과 복사된 배열은 서로 다른 메모리 공간을 갖게 됩니다. 따라서, 한 배열의 값을 변경해도 다른 배열의 값은 변경되지 않습니다.
장점:
- 원본 배열 유지: 복사된 배열에서 값을 변경해도 원본 배열에 영향을 주지 않습니다.
- 독립적인 메모리 관리: 원본 배열과 복사된 배열은 서로 다른 메모리 공간을 사용하므로 독립적으로 관리할 수 있습니다.
단점:
- 느린 속도: 모든 값을 복사해야 하므로 얕은 복사보다 속도가 느립니다.
- 메모리 사용량 증가: 새로운 메모리 공간을 할당해야 하므로 메모리 사용량이 증가합니다.
깊은 복사 예시:
#include <stdio.h>
int main() {
int arr1[] = {1, 2, 3, 4, 5};
int arr2[5];
// for 반복문을 사용하여 값을 복사
for (int i = 0; i < 5; i++) {
arr2[i] = arr1[i];
}
arr2[0] = 10; // arr2의 첫 번째 요소를 변경
printf("arr1: ");
for (int i = 0; i < 5; i++) {
printf("%d ", arr1[i]); // 출력: arr1: 1 2 3 4 5
}
printf("\n");
printf("arr2: ");
for (int i = 0; i < 5; i++) {
printf("%d ", arr2[i]); // 출력: arr2: 10 2 3 4 5
}
printf("\n");
return 0;
}
깊은 복사 - memcpy 함수 활용:
#include <stdio.h>
#include <string.h> // memcpy 함수를 사용하기 위해 string.h 헤더 파일 포함
int main() {
int arr1[] = {1, 2, 3, 4, 5};
int arr2[5];
memcpy(arr2, arr1, sizeof(arr1)); // arr1을 arr2로 복사
// ... (이후 코드는 위와 동일)
}
얕은 복사 vs 깊은 복사: 어떤 방법을 선택해야 할까요?
- 원본 배열의 값을 보존해야 하는 경우: 깊은 복사
- 속도가 중요하고 원본 배열의 변경이 문제가 되지 않는 경우: 얕은 복사
- 큰 배열을 복사하는 경우: 메모리 사용량을 고려하여 얕은 복사 (필요한 경우에만 깊은 복사)
C언어: 배열을 함수의 인수로 전달하기
C언어에서 함수는 특정 작업을 수행하는 코드 블록입니다. 함수를 사용할 때, 필요한 데이터를 함수에 전달해야 하는 경우가 있는데, 이때 인수(argument)를 사용합니다. 배열도 함수의 인수로 전달하여 함수 내부에서 사용할 수 있습니다.
배열을 함수 인수로 전달하는 방법
C언어에서는 배열을 함수에 전달할 때, 배열의 이름을 사용합니다. 배열의 이름은 배열의 시작 주소를 나타내는 포인터이기 때문에, 함수에 배열의 시작 주소가 전달됩니다.
예시
#include <stdio.h>
// 배열의 모든 원소를 출력하는 함수
void print_array(int arr[], int size) {
for (int i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");
}
int main() {
int numbers[] = {1, 2, 3, 4, 5};
int size = sizeof(numbers) / sizeof(numbers[0]);
print_array(numbers, size); // 배열 numbers를 함수에 전달
return 0;
}
코드 설명
print_array
함수는int
형 배열arr
과 배열의 크기size
를 인수로 받습니다.main
함수에서print_array
함수를 호출할 때, 배열의 이름numbers
와 배열의 크기size
를 전달합니다.print_array
함수 내부에서는 전달받은 배열arr
을 사용하여 배열의 모든 원소를 출력합니다.
주의 사항
- 배열을 함수에 전달할 때는 배열의 크기를 함께 전달해야 합니다. 함수 내부에서는 배열의 크기를 알 수 없기 때문입니다.
- 함수 내부에서 배열의 값을 변경하면 원본 배열의 값도 변경됩니다. 배열은 Call-by-reference 방식으로 전달되기 때문입니다.
장점
- 효율성: 배열 전체를 복사하지 않고 시작 주소만 전달하므로 메모리 사용량을 줄이고 속도를 높일 수 있습니다.
- 유연성: 함수 내부에서 배열의 값을 변경하여 원본 배열에 영향을 줄 수 있습니다.
활용
배열을 함수의 인수로 전달하는 것은 C언어 프로그래밍에서 매우 일반적인 방법입니다. 배열을 정렬하거나, 배열의 합계를 계산하거나, 배열의 값을 검색하는 등 다양한 작업에 활용할 수 있습니다.