소개
포인터 연산은 C 에서 값을 더하거나 빼서 메모리 주소를 조작할 수 있는 강력한 기능입니다. 포인터 연산의 가장 일반적인 응용 프로그램 중 하나는 배열 순회입니다. 포인터를 사용하면 배열을 정방향 및 역방향으로 효율적으로 이동할 수 있습니다.
이 랩에서는 배열을 생성하고 초기화하는 방법, 배열 요소에 접근하기 위한 포인터를 설정하는 방법, 그리고 포인터 연산을 사용하여 배열을 순회하는 방법을 배우게 됩니다. 이 기술은 C 프로그래밍의 기본이며, 많은 고급 데이터 조작 연산의 기초를 형성합니다.
기본 C 프로그램 생성
VSCode 편집기에서 새로운 C 파일을 생성하는 것으로 시작해 보겠습니다. 이 파일에는 포인터를 사용한 배열 순회를 위한 메인 프로그램이 포함됩니다.
WebIDE 에서 왼쪽의 탐색기 패널을 찾아
~/project디렉토리로 이동합니다.project폴더를 마우스 오른쪽 버튼으로 클릭하고 "New File"을 선택합니다. 파일 이름을main.c로 지정합니다.다음 기본 C 프로그램 구조를 파일에 복사합니다.
#include <stdio.h>
int main() {
printf("Array Traversal using Pointers\n");
return 0;
}
Ctrl+S 를 누르거나 메뉴에서 File > Save 를 사용하여 파일을 저장합니다.
모든 것이 올바르게 설정되었는지 확인하기 위해 이 프로그램을 컴파일하고 실행해 보겠습니다. 메뉴에서 Terminal > New Terminal 을 선택하여 WebIDE 에서 터미널을 열고 다음을 실행합니다.
cd ~/project
gcc main.c -o main
./main
다음 출력이 표시되어야 합니다.
Array Traversal using Pointers
이는 C 개발 환경이 제대로 작동하고 있음을 확인합니다. 다음 단계에서는 이 프로그램을 수정하여 배열과 포인터로 작업할 것입니다.
배열 및 포인터 선언 및 초기화
이 단계에서는 포인터를 사용한 배열 순회의 기본 구성 요소인 배열과 포인터를 선언하는 방법을 배우겠습니다.
배열과 포인터 이해
C 에서 배열은 동일한 유형의 요소 모음으로, 연속된 메모리 위치에 저장됩니다. 예를 들어, 5 개의 요소를 가진 정수 배열은 메모리에 5 개의 정수를 연속적으로 저장할 공간을 예약합니다.
포인터는 다른 변수의 메모리 주소를 저장하는 변수입니다. 포인터를 사용하여 특정 메모리 주소에 저장된 값에 간접적으로 접근할 수 있습니다.
main.c 파일을 수정하여 배열과 포인터를 포함해 보겠습니다.
#include <stdio.h>
int main() {
printf("Array Traversal using Pointers\n\n");
// Declare and initialize an array of 5 integers
int arr[5] = {10, 20, 30, 40, 50};
// Declare a pointer of integer type
int *ptr;
// Print the array elements using array notation
printf("Array elements using array notation:\n");
for(int i = 0; i < 5; i++) {
printf("arr[%d] = %d\n", i, arr[i]);
}
return 0;
}
이 코드에서:
- 5 개의 요소가 있는 정수 배열
arr을 선언하고 10, 20, 30, 40, 50 의 값으로 초기화했습니다. - 배열 요소들을 가리키는 데 사용할 정수 포인터
ptr을 선언했습니다. - 전통적인 배열 표기법을 사용하여 배열 요소를 출력했습니다.
프로그램을 컴파일하고 실행하여 배열 요소를 확인합니다.
gcc main.c -o main
./main
다음 출력이 표시되어야 합니다.
Array Traversal using Pointers
Array elements using array notation:
arr[0] = 10
arr[1] = 20
arr[2] = 30
arr[3] = 40
arr[4] = 50
다음 단계에서는 포인터를 배열에 연결하고 포인터를 사용하여 배열 요소에 접근할 것입니다.
포인터와 배열 연결 및 순방향 순회
이 단계에서는 포인터와 배열 간의 연결을 설정한 다음, 포인터를 사용하여 배열을 순방향으로 순회합니다.
포인터를 배열에 연결하기
C 에서 인덱스가 없는 배열 이름은 배열의 첫 번째 요소의 주소를 나타냅니다. 즉, 이 주소를 포인터 변수에 직접 할당할 수 있습니다.
main.c 파일을 수정하여 포인터를 배열과 연결하고 순회해 보겠습니다.
#include <stdio.h>
int main() {
printf("Array Traversal using Pointers\n\n");
// Declare and initialize an array of 5 integers
int arr[5] = {10, 20, 30, 40, 50};
// Declare a pointer of integer type
int *ptr;
// Assign the address of the first element of the array to the pointer
ptr = arr; // This is equivalent to ptr = &arr[0]
// Print the array elements using array notation
printf("Array elements using array notation:\n");
for(int i = 0; i < 5; i++) {
printf("arr[%d] = %d\n", i, arr[i]);
}
// Print the array elements using pointer notation
printf("\nArray elements using pointer notation (forward traversal):\n");
for(int i = 0; i < 5; i++) {
printf("*(ptr + %d) = %d\n", i, *(ptr + i));
}
return 0;
}
이 업데이트된 코드에서:
- 배열
arr의 첫 번째 요소의 주소를 포인터ptr에 할당했습니다. - 포인터 산술 연산을 사용하여 배열을 순회하는 새로운 루프를 추가했습니다.
- 표현식
*(ptr + i)는 메모리 위치ptr + i의 값에 접근합니다.i가 0 일 때, 이것은 배열의 첫 번째 요소이고,i가 1 일 때는 두 번째 요소이며, 그 외에도 마찬가지입니다.
프로그램을 컴파일하고 실행하여 결과를 확인합니다.
gcc main.c -o main
./main
다음 출력이 표시되어야 합니다.
Array Traversal using Pointers
Array elements using array notation:
arr[0] = 10
arr[1] = 20
arr[2] = 30
arr[3] = 40
arr[4] = 50
Array elements using pointer notation (forward traversal):
*(ptr + 0) = 10
*(ptr + 1) = 20
*(ptr + 2) = 30
*(ptr + 3) = 40
*(ptr + 4) = 50
두 방법 모두 동일한 출력을 생성하는 것을 확인하십시오. 이는 포인터 산술 연산이 전통적인 배열 인덱싱과 마찬가지로 배열 요소에 접근하는 데 사용될 수 있음을 보여줍니다.
배열 순회를 위한 포인터 증가 구현
이전 단계에서는 *(ptr + i) 표현식을 사용하여 배열 요소에 접근했습니다. 이 방법도 완벽하게 작동하지만, C 는 포인터를 사용하여 배열을 순회하는 더 간결한 방법을 제공합니다: 증가 연산자 (++).
포인터를 증가시키면, 포인터가 가리키는 데이터 유형의 크기에 따라 다음 메모리 위치로 이동합니다. 정수 포인터의 경우, 이를 증가시키면 메모리의 다음 정수로 이동합니다.
main.c 파일을 수정하여 배열 순회에 포인터 증가를 사용해 보겠습니다.
#include <stdio.h>
int main() {
printf("Array Traversal using Pointers\n\n");
// Declare and initialize an array of 5 integers
int arr[5] = {10, 20, 30, 40, 50};
// Declare and initialize a pointer to the first element of the array
int *ptr = arr; // Same as ptr = &arr[0]
// Print the array elements using pointer incrementation
printf("Array elements using pointer incrementation:\n");
for(int i = 0; i < 5; i++) {
printf("*ptr = %d\n", *ptr);
ptr++; // Move the pointer to the next element
}
// Reset the pointer to the beginning of the array
ptr = arr;
// Print all elements in a single line using pointer incrementation
printf("\nAll elements in a single line: ");
for(int i = 0; i < 5; i++) {
printf("%d ", *ptr++); // Print and then increment
}
printf("\n");
return 0;
}
이 업데이트된 코드에서:
- 포인터
ptr을 선언할 때 직접 초기화합니다. - 첫 번째 루프 내에서, 현재 요소에 접근하기 위해
*ptr을 사용하고, 다음 요소로 이동하기 위해ptr++을 사용합니다. - 첫 번째 루프가 끝난 후,
ptr을 다시 배열의 시작 부분을 가리키도록 재설정합니다. - 두 번째 루프에서는 후위 증가 연산자
*ptr++을 사용하는데, 이는 먼저ptr의 현재 값을 사용한 다음 증가시킵니다.
프로그램을 컴파일하고 실행하여 결과를 확인합니다.
gcc main.c -o main
./main
다음 출력이 표시되어야 합니다.
Array Traversal using Pointers
Array elements using pointer incrementation:
*ptr = 10
*ptr = 20
*ptr = 30
*ptr = 40
*ptr = 50
All elements in a single line: 10 20 30 40 50
이는 포인터 증가를 사용하여 배열을 순회하는 방법을 보여줍니다. 핵심은 ptr++이 다음 요소로 이동할 때 데이터 유형의 크기를 자동으로 고려한다는 것입니다.
포인터 감소를 사용한 역방향 순회 구현
이전 단계에서는 배열을 순방향으로 순회했습니다. 이제 포인터 감소를 사용하여 배열을 역방향으로 순회하는 방법을 알아보겠습니다.
역방향 순회를 위해서는 다음이 필요합니다.
- 포인터를 배열의 마지막 요소를 가리키도록 초기화합니다.
- 포인터를 감소시켜 배열을 역방향으로 이동합니다.
main.c 파일을 수정하여 역방향 순회를 구현해 보겠습니다.
#include <stdio.h>
int main() {
printf("Array Traversal using Pointers\n\n");
// Declare and initialize an array of 5 integers
int arr[5] = {10, 20, 30, 40, 50};
// Forward traversal using pointer increment
int *ptr = arr;
printf("Forward traversal using pointer increment:\n");
for(int i = 0; i < 5; i++) {
printf("%d ", *ptr);
ptr++;
}
printf("\n\n");
// Backward traversal using pointer decrement
// Point to the last element of the array
ptr = &arr[4]; // or ptr = arr + 4
printf("Backward traversal using pointer decrement:\n");
for(int i = 0; i < 5; i++) {
printf("%d ", *ptr);
ptr--; // Move the pointer to the previous element
}
printf("\n\n");
// Alternative approach: Start from the last element and decrement in the loop condition
printf("Alternative backward traversal approach:\n");
for(ptr = &arr[4]; ptr >= arr; ptr--) {
printf("%d ", *ptr);
}
printf("\n");
return 0;
}
이 업데이트된 코드에서:
- 먼저 포인터 증가를 사용하여 순방향 순회를 수행합니다.
- 역방향 순회를 위해
ptr = &arr[4]를 사용하여 포인터를 배열의 마지막 요소로 설정합니다. - 루프 내에서 현재 요소를 출력한 다음
ptr--를 사용하여 포인터를 감소시킵니다. - 또한 감소가 for 루프의 업데이트 문에 포함된 대체 방법을 보여줍니다.
프로그램을 컴파일하고 실행하여 결과를 확인합니다.
gcc main.c -o main
./main
다음 출력이 표시되어야 합니다.
Array Traversal using Pointers
Forward traversal using pointer increment:
10 20 30 40 50
Backward traversal using pointer decrement:
50 40 30 20 10
Alternative backward traversal approach:
50 40 30 20 10
이는 포인터 산술 연산을 사용하여 배열을 순방향 및 역방향으로 순회하는 방법을 보여줍니다. 포인터를 증가 및 감소시키는 기능은 배열을 어떤 방향으로든 쉽게 이동할 수 있게 해줍니다.
요약
이 랩에서는 C 프로그래밍에서 포인터를 사용하여 배열을 순회하는 방법을 배웠습니다. 다음은 우리가 다룬 주요 개념입니다.
배열 및 포인터 기본 사항:
- C 의 배열은 연속적인 메모리 위치에 요소를 저장합니다.
- 포인터는 메모리 주소를 저장하며 해당 위치에 접근하는 데 사용할 수 있습니다.
포인터 - 배열 관계:
- 배열 이름 (인덱스 없이) 은 첫 번째 요소의 주소를 나타냅니다.
- 이 주소를 포인터에 할당하여 배열과의 연결을 설정할 수 있습니다.
순방향 순회 기술:
- 포인터 산술 연산 사용:
*(ptr + i) - 포인터 증가 사용:
*ptr다음에ptr++ - 역참조와 증가 결합:
*ptr++
- 포인터 산술 연산 사용:
역방향 순회 기술:
- 포인터를 마지막 요소로 초기화:
ptr = &arr[size-1] - 포인터 감소 사용:
ptr--를 사용하여 뒤로 이동 - 루프 조건은 포인터가 배열의 시작 부분에 도달했을 때 확인할 수 있습니다.
- 포인터를 마지막 요소로 초기화:
포인터 산술 연산은 C 의 강력한 기능으로, 효율적인 메모리 조작을 가능하게 하며 배열 및 기타 데이터 구조를 사용할 때 유연성을 제공합니다. 이 기술은 동적 메모리 할당, 연결 리스트 및 기타 복잡한 데이터 구조와 같은 더 고급 프로그래밍 개념의 기초를 형성합니다.



