산업 제조
산업용 사물 인터넷 | 산업자재 | 장비 유지 보수 및 수리 | 산업 프로그래밍 |
home  MfgRobots >> 산업 제조 >  >> Industrial programming >> C 언어

C 언어 포인터 배열 초기화 완벽 가이드: 팁 & 모범 사례

포인터는 다른 변수의 주소를 저장하는 변수입니다. 포인터 변수 이름은 * 기호로 시작해야 합니다. 일반 변수와 마찬가지로 포인터 배열도 선언할 수 있으며, 배열의 각 첨자는 배열 타입의 주소를 저장합니다.

C에서 포인터 배열 초기화하는 방법?

포인터 변수는 기존 변수의 주소를 할당해 선언 시 초기화할 수 있습니다. 다음 스니펫은 포인터 초기화 방법을 보여줍니다.

int x = 10;
int *y = &x;

기본적으로 포인터 변수를 포함한 모든 변수는 자동 저장 클래스(auto storage class)에 속합니다. 이는 포인터 변수가 예측 불가능한, 가비지, 랜덤 메모리 주소를 저장하게 되어 미정의 동작과 세그멘테이션 폴트 같은 잠재적 위험을 초래할 수 있음을 의미합니다. 따라서 선언 시 특정 값을 저장할 게 없다면 NULL로 초기화해야 합니다.

int *ptr = NULL;

포인터 배열은 각 요소에 주소를 저장합니다. 배열 타입은 대상 변수 타입과 일치해야 합니다.

static 키워드로 포인터 배열 초기화

static 키워드로 포인터 배열을 초기화해 각 첨자에 0(NULL)을 저장할 수 있습니다.

예제

#include <stdio.h>
int main() {
    static int *ptr[5];
    for (int i = 0; i < 5; i++) {
        printf("ptr[%d] = %d\n", i, ptr[i]);
    }
    return 0;
}

출력

ptr[0] = 0
ptr[1] = 0
ptr[2] = 0
ptr[3] = 0
ptr[4] = 0

정수 포인터 배열 초기화

여기서 정수 포인터 배열을 선언하고 세 정수 변수의 주소를 저장합니다.

예제

#include <stdio.h>
int main() {
    int a = 10, b = 20, c = 30;
    int *ptr[3] = {&a, &b, &c};
    for (int i = 0; i < 3; i++) {
        printf("ptr[%d]: address: %p value: %d\n", i, (void*)ptr[i], *ptr[i]);
    }
    return 0;
}

출력

ptr[0]: address: 0x7ffee... value: 10
ptr[1]: address: 0x7ffee... value: 20
ptr[2]: address: 0x7ffee... value: 30

직접 주소로 포인터 배열 초기화

일반 배열 각 요소의 주소를 포인터 배열 대응 요소에 저장할 수 있습니다.

예제

#include <stdio.h>
int main() {
    int arr[] = {10, 20, 30};
    int *ptr[3] = {&arr[0], &arr[1], &arr[2]};
    for (int i = 0; i < 3; i++) {
        printf("ptr[%d]: address: %p value: %d\n", i, (void*)ptr[i], *ptr[i]);
    }
    return 0;
}

출력

ptr[0]: address: 0x7ffee... value: 10
ptr[1]: address: 0x7ffee... value: 20
ptr[2]: address: 0x7ffee... value: 30

기준 주소로 배열 순회

배열의 기준 주소(&arr[0])를 얻으면, 포인터가 데이터 타입 크기만큼 증가함을 알기 때문에 이후 요소들 주소를 얻을 수 있습니다.

따라서 기준 주소(배열 이름이 0번째 요소 주소와 동일)만으로 배열을 순회할 수 있습니다.

예제 1

#include <stdio.h>
int main() {
    int arr[] = {10, 20, 30};
    int *ptr = arr;
    for (int i = 0; i < 3; i++) {
        printf("ptr[%d]: address: %p value: %d\n", i, (void*)(ptr + i), *(ptr + i));
    }
    return 0;
}

출력

ptr[0]: address: 0x7ffee... value: 10
ptr[1]: address: 0x7ffee... value: 20
ptr[2]: address: 0x7ffee... value: 30

예제 2: 포인터 배열로 2차원 배열 순회

이 예제에서는 2차원 배열이 있습니다. 각 행의 0번째 요소 주소가 포인터 배열에 저장됩니다. 순회 시 포인터 배열 각 요소가 저장한 주소(해당 행 0번째 요소 가리킴)에서 시작해 각 행의 값들을 가져옵니다.

#include <stdio.h>
int main() {
    // 2차원 배열
    int arr[2][4] = {
        {1, 2, 3, 4},
        {5, 6, 7, 8}
    };
    int ROWS = 2, COLS = 4;
    int i, j;
    // 포인터
    int (*ptr)[4] = arr;
    // 포인터 ptr로 배열 요소 출력
    for (i = 0; i < ROWS; i++) {
        for (j = 0; j < COLS; j++) {
            printf("%d ", *(ptr[i] + j));
        }
        printf("\n");
    }
    return 0;
}

출력

1 2 3 4
5 6 7 8

예제 3

포인터 배열이 꼭 필요하진 않습니다. 2차원 배열 이름을 기준 포인터로 쓰고 행/열 방향으로 증가시켜 주어진 2차원 배열 요소들을 가져올 수 있습니다.

#include <stdio.h>
int main() {
    // 2차원 배열
    int arr[2][4] = {
        {1, 2, 3, 4},
        {5, 6, 7, 8}
    };
    int ROWS = 2, COLS = 4;
    int i, j;
    // 포인터
    int *ptr = (int *)arr;
    // 포인터 ptr로 배열 요소 출력
    for (i = 0; i < ROWS; i++) {
        for (j = 0; j < COLS; j++) {
            printf("%d ", *(ptr + i * COLS + j));
        }
        printf("\n");
    }
    return 0;
}

출력

1 2 3 4
5 6 7 8

문자 포인터 배열(문자열) 초기화

C 프로그래밍에서 문자열은 char 타입 배열입니다. 배열 이름이 0번째 요소 주소를 나타내므로 문자열은 다음과 같이 선언할 수 있습니다.

char arr[] = "Hello";

포인터 표기법으로 문자열을 char 포인터에 할당하면:

char *arr = "Hello";

여러 문자열을 저장하기 위해 char 포인터 배열을 선언할 수 있습니다.

char *arr[3] = {"string1", "string2", "string3"};

예제

다음 예제는 컴퓨터 언어 이름들을 저장하는 char 포인터 배열입니다.

#include <stdio.h>
int main() {
    char *langs[10] = {
        "PYTHON", "JAVASCRIPT", "PHP", "NODE JS", "HTML",
        "KOTLIN", "C++", "REACT JS", "RUST", "VBSCRIPT"
    };
    for (int i = 0; i < 10; i++)
        printf("%s\n", langs[i]);
    return 0;
}

출력

PYTHON
JAVASCRIPT
PHP
NODE JS
HTML
KOTLIN
C++
REACT JS
RUST
VBSCRIPT

이 프로그램에서 langs는 10개 문자열 배열을 가리키는 포인터입니다. 따라서 langs[0]이 주소 5000을 가리키면 langs + 1은 두 번째 문자열 포인터를 저장하는 주소 5004를 가리킵니다.

따라서 다음 루프 변형으로도 문자열 배열을 출력할 수 있습니다.

for (int i = 0; i < 10; i++) {
    printf("%s\n", *(langs + i));
}

동적 포인터 배열 초기화

malloc() 함수로 포인터 배열을 동적으로 선언하고 초기화할 수 있습니다.

예제

#include <stdio.h>
#include <stdlib.h>

int main() {
    int *arr = (int *)malloc(sizeof(int) * 5);
    for (int i = 0; i < 5; i++) {
        arr[i] = i;
    }
    for (int x = 0; x < 5; x++) {
        printf("%d %d\n", x, arr[x]);
    }
    free(arr);
    return 0;
}

출력

0 0
1 1
2 2
3 3
4 4

사용자 입력을 받아 포인터 배열 요소들에 값을 할당할 수도 있습니다.

for (int i = 0; i < 5; i++) {
    int x;
    scanf("%d", &x);
    arr[i] = x;
}

C 언어

  1. C 데이터 타입 완전 정복: 정수, 실수, void, 파생 타입과 sizeof
  2. C# 생성자 오버로딩 마스터하기: 유연한 클래스 설계
  3. C 언어 재귀 마스터하기: 모범 사례와 종료 조건
  4. C++ 연산자 종합 가이드: 종류, 사용법, 우선순위
  5. C++ 시그널 처리 마스터하기: 안전한 인터럽트 관리와 깔끔한 프로그램 종료
  6. C++ 프로그래밍 기초: C++이란 무엇이며 왜 중요한가
  7. C# 가변 배열(Jagged Array): 선언, 초기화, 접근 완전 가이드
  8. 2024년 C 프로그래밍 면접 질문 TOP 100 & 답변 총정리
  9. C# 변수와 기본 데이터 타입 완벽 가이드
  10. C 프로그래밍 언어: 기초, 역사, 그리고 응용 분야