본문 바로가기

IT & AI/AI 지식

C 언어 배열, 포인터, 문자열 활용 심화

by 빛나는해커 2024. 11. 19.

안녕하세요! 지난 글에서 C언어 함수, 배열, 포인터에 대해 간단하게 다뤄보았습니다. 혹시나 해당 내용에 대해 기초적인 부분을 모르시는 분들은 바로 이전 글을 보고 오시면 좋을 것 같습니다.

이번에는 배열과 포인터에 대해 좀 더 자세히 정리해보았고 함께 활용할 수 있는 문자와 문자열들에 대해 적어보았습니다.

1. 배열과 포인터

 

배열과 포인터의 관계

  • 배열명은 배열의 첫 번째 요소의 주소를 의미한다.
  • 배열명을 사용해 배열 요소에 접근할 수 있으며, 배열명은 포인터와 유사하게 동작하지만 변경이 불가능하다.
int numbers[5] = {1, 2, 3, 4, 5};
int *p = numbers;  // numbers는 배열의 첫 번째 요소의 주소
printf("첫 번째 요소: %d\n", *p);  // 출력: 1
  • 배열명은 배열의 첫 번째 요소의 주소로 취급되며, 포인터로 동작할 수 있다.
  • 따라서 포인터 연산을 통해 배열의 각 요소에 접근할 수 있다.
for (int i = 0; i < 5; i++) {
    printf("numbers[%d] = %d\n", i, *(numbers + i));  // 배열 요소 출력
}
  • 배열명은 배열의 시작 주소를 나타내며, 포인터처럼 사용될 수 있지만 변경할 수 없는 상수이다.
  • 반면에 포인터 변수는 다른 주소를 저장할 수 있는 변수이다.
int numbers[5] = {1, 2, 3, 4, 5};
int *p = numbers;
p = &numbers[2];  // 포인터는 다른 요소를 가리킬 수 있음
// numbers = &numbers[2];  // 오류: 배열명은 상수이므로 변경할 수 없음
  • 포인터 사이의 뺄셈은 두 주소 간의 거리를 반환하며, 관계 연산을 통해 두 포인터가 가리키는 주소를 비교할 수 있다.
int numbers[5] = {1, 2, 3, 4, 5};
int *p1 = &numbers[1];
int *p2 = &numbers[4];
int distance = p2 - p1;  // 두 포인터 간의 거리 (배열 요소 간의 차이)
printf("거리: %d\n", distance);  // 출력: 3

 

배열을 처리하는 함수

  • 배열을 함수로 전달하여 값을 출력할 수 있다.
  • 함수의 매개변수로 배열을 전달할 때는 배열명이 사용된다.
void print_array(int arr[], int size) {
    for (int i = 0; i < size; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
}

int numbers[5] = {1, 2, 3, 4, 5};
print_array(numbers, 5);  // 출력: 1 2 3 4 5
  • 배열 크기를 매개변수로 전달하여 크기가 다른 배열도 출력할 수 있도록 한다.
int numbers2[3] = {10, 20, 30};
print_array(numbers2, 3);  // 출력: 10 20 30
  • 배열에 값을 입력받아 저장하는 함수도 작성할 수 있다.
void input_array(int arr[], int size) {
    for (int i = 0; i < size; i++) {
        printf("값을 입력하세요: ");
        scanf("%d", &arr[i]);
    }
}

int numbers[5];
input_array(numbers, 5);
  • 함수의 매개변수 자리에 배열을 선언하면 실제로는 배열의 주소가 전달된다.
  • 이는 배열의 첫 번째 요소의 주소를 받는 포인터와 동일한 방식으로 동작한다.
void modify_array(int arr[], int size) {
    arr[0] = 100;  // 첫 번째 요소를 100으로 변경
}

int numbers[5] = {1, 2, 3, 4, 5};
modify_array(numbers, 5);
printf("첫 번째 요소: %d\n", numbers[0]);  // 출력: 100

2. 문자

 

아스키코드 값과 문자 입출력 함수

  • 아스키코드는 문자와 숫자 간의 매핑 규칙을 정의한 것으로, 컴퓨터에서 문자를 숫자로 표현할 때 사용된다.
  • 예를 들어, 'A'의 아스키 값은 65이다.
char c = 'A';
printf("%c의 아스키 값: %d\n", c, c);  // 출력: A의 아스키 값: 65
  • scanf 함수를 사용하여 문자를 입력받을 수 있다.
  • %c 형식 지정자를 사용한다.
char c;
printf("문자를 입력하세요: ");
scanf(" %c", &c);  // 공백을 넣어야 이전 입력의 줄바꿈을 무시함
printf("입력한 문자: %c\n", c);
  • getchar 함수는 한 문자를 입력받고, putchar 함수는 한 문자를 출력한다.
char c;
c = getchar();
putchar(c);  // 입력한 문자 출력

 

버퍼를 사용하는 입력 함수

  • scanf 함수는 입력 버퍼를 사용하여 데이터를 처리한다.
  • 문자 입력 시 이전의 줄 바꿈이 버퍼에 남아 있다면 다음 입력에 영향을 줄 수 있다.
  • scanf 함수는 입력받은 항목의 개수를 반환한다.
  • 이를 활용하여 입력이 제대로 이루어졌는지 확인할 수 있다.
int result = scanf("%d", &num);
if (result == 1) {
    printf("입력이 정상적으로 이루어졌습니다.\n");
}
  • getchar 함수를 반복 사용하여 문자열을 입력받을 수 있다.
char str[100];
int i = 0;
char c;
while ((c = getchar()) != '\n') {
    str[i++] = c;
}
str[i] = '\0';
printf("입력한 문자열: %s\n", str);
  • 입력 버퍼에 남아 있는 불필요한 데이터를 제거하기 위해 fflush(stdin)이나 반복적으로 getchar()를 호출할 수 있다.
while (getchar() != '\n');  // 입력 버퍼 지우기

3. 문자열

 

문자열과 포인터

  • 문자열 상수는 큰따옴표(")로 묶어서 선언하며, 문자열은 자동으로 널 문자(\0)로 끝난다.
char *str = "Hello, World!";
  • char 포인터를 사용하여 문자열을 가리킬 수 있다.
  • 이는 문자열 리터럴의 주소를 가리키는 포인터로 동작한다.
char *str = "Hello";
printf("%s\n", str);  // 출력: Hello
  • scanf 함수는 문자열을 입력받을 때 %s 형식 지정자를 사용하며, 공백이 포함되면 그 이전까지만 입력받는다.
char name[20];
scanf("%s", name);
printf("이름: %s\n", name);
  • gets 함수는 한 줄 전체를 입력받으며, 공백도 포함한다.
  • 하지만 안전하지 않기 때문에 권장되지 않는다.
char str[50];
gets(str);
printf("입력한 문자열: %s\n", str);
  • fgets 함수는 입력의 길이를 제한할 수 있어 더 안전한 방법으로 문자열을 입력받는다.
fgets(str, sizeof(str), stdin);
printf("입력한 문자열: %s\n", str);
  • scanf, gets, fgets 등은 표준 입력 버퍼를 공유하므로, 입력 순서에 따라 버퍼에 남은 줄 바꿈이 다음 입력에 영향을 줄 수 있다.

 

문자열 연산 함수

  • strcpy 함수는 문자열을 다른 문자열에 복사한다.
char dest[20];
strcpy(dest, "Hello");
printf("복사된 문자열: %s\n", dest);
  • strncpy 함수는 지정된 개수만큼 문자를 복사하며, 복사되는 문자의 길이를 제한함으로써 보다 안전하게 문자열을 처리할 수 있다.
char dest[20];
strncpy(dest, "Hello, World!", 5);
dest[5] = '\0';  // 널 문자 추가
printf("복사된 문자열: %s\n", dest);  // 출력: Hello
  • strcat 함수는 두 개의 문자열을 이어 붙이고, strncat 함수는 지정된 개수만큼만 문자열을 이어 붙인다.
char str1[20] = "Hello";
char str2[] = " World";
strcat(str1, str2);
printf("붙인 문자열: %s\n", str1);  // 출력: Hello World

strncat(str1, "!!!", 2);
printf("부분적으로 붙인 문자열: %s\n", str1);  // 출력: Hello World!!
  • strlen 함수는 문자열의 길이를 반환하며, 널 문자는 포함하지 않는다.
char str[] = "Hello";
int length = strlen(str);
printf("문자열의 길이: %d\n", length);  // 출력: 5
  • strcmp 함수는 두 문자열을 비교하여 같으면 0을 반환하고, 다르면 양수 또는 음수를 반환한다.
  • strncmp 함수는 지정된 개수만큼만 비교한다.
char str1[] = "Hello";
char str2[] = "Hello, World!";
int result = strcmp(str1, str2);
printf("비교 결과: %d\n", result);  // 출력: 음수 (str1 < str2)

result = strncmp(str1, str2, 5);
printf("부분 비교 결과: %d\n", result);  // 출력: 0 (처음 5문자는 동일)
  • 기본적인 문자열 함수들을 직접 구현해 보며 문자열의 구조와 연산 원리를 이해할 수 있다.
// 문자열 복사 함수 구현
void my_strcpy(char *dest, const char *src) {
    while (*src) {
        *dest++ = *src++;
    }
    *dest = '\0';
}

char dest[20];
my_strcpy(dest, "Hello");
printf("복사된 문자열: %s\n", dest);  // 출력: Hello

혹시 이해가 어려우시다면, 이전 글을 먼저 참고해보시면 좋을 것 같습니다.

 

C 언어 기본 개념과 프로그램 구조, 변수, 상수, 데이터 입력과 출력

안녕하세요! 문과 출신 데이터 전문가와 함께 파이썬에 이어 이번에는 C언어 기본에 대해 알아보고자 합니다. 특히 정보처리기사와 같은 자격증 시험에서 꼭 알아야 할 내용인데요. 먼저 C언어

actshiny.com

 

C 언어 연산자와 제어문(반복문, 조건문)

안녕하세요! 지난 글에서 C언어의 상수, 변수 및 데이터 입출력에 대해 다뤄보았습니다. 이어서 연산자의 종류 및 예시와 제어문인 반복문, 선택문(조건문)에 대해 정리해보았습니다. 특히 처음

actshiny.com

 

C 언어 함수, 배열, 포인터 사용법과 예제

안녕하세요! 오늘은 C언어의 핵심이자 꼭 알아야 할 내용인 함수, 배열, 포인터를 정리해보았습니다. 무엇보다 배열과 포인터는 C언어에서 몰라서는 안될 핵심과도 같기 때문에 반드시 이해하고

actshiny.com

C 언어 기본 배열, 포인터, 문자열 활용 소개 이미지

반응형