문자열과 시작 위치, 끝 위치가 입력된다. 입력 받은 문자열에서 시작 위치 ~ 끝 위치까지 출력하는 것이 목적이다. 단 배열 대신 동적 메모리 할당 방법(malloc, free)를 사용해서 풀어야한다. 배열이 안되니 배열 포인터를 만들어서 풀면 될 것 같다.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a, b; // 시작 위치 끝 위치를 입력 받을 변수
char *p = malloc(sizeof(char) * 100);
// malloc으로 char의 크기 * 100만큼 메모리를 할당한 후 그 주소를 포인터 p에 저장
scanf("%s", p);
scanf("%d %d", &a, &b);
// 문자열을 p의 주소에 저장, 시작 위치, 끝 위치 입력
for (int i = a - 1; i < b; i++) // 시작 위치 ~ 끝 위치까지 반복
{
printf("%c", *(p+sizeof(char)*i));
// [를 사용할 수 없으므로 인덱스로 접근하는 대신 해당 요소의 메모리 주소를 역참조
}
free(p); // p 메모리 해제
}
먼저 시작 위치, 끝 위치를 입력 받을 변수 선언, 그리고 [를 사용할 수 없기 때문에 malloc 함수로 char의 크기 * 100 만큼 메모리 공간을 확보하고 그 주소를 char형 포인터 p에 저장했다. 그리고 scanf로 문자열과 시작 위치, 끝 위치를 각각의 변수에 입력 받았다.
시작 위치 ~ 끝 위치 범위로 for문을 하나 작성하고 해당 번째의 문자를 출력하려 했지만, 처음에는 [를 사용할 수 없다는 것을 간과하고 위 코드의 printf("%c", *(p+sizeof(char)*i)); 부분을 printf("%c", p[i]);로 작성하고 제출했다.
위 오류 문구를 보고 인덱스로는 접근할 수 없다는 것을 깨닫고 배열의 메모리 주소를 역참조해 문제를 풀었다.
*(p+sizeof(char)*i)는 p 메모리 주소(배열의 첫 번째 요소의 주소) + char의 크기 * i(인덱스)를 연산한 주소를 *로 역참조해서 해당 주소의 문자를 출력했다. 이렇게 해준 이유는 배열이 데이터를 저장하는 방식이 배열의 크기 * 자료형의 크기 만큼 메모리를 확보한 후 이 메모리를 자료형 만큼 나눠서 데이터를 각각 저장해준다.
위는 배열의 메모리 공간 모습을 복습하기 위해 예시로 int a[10] 배열을 만들었을 때의 메모리의 모습을 그림판으로 그려본 것이다. 저 네모 칸들은 모두 동일한 크기라고 가정한다... 그냥 정사각형 하나 만들어서 복사할걸..
int형은 4byte이므로 4 * 10(배열의 크기)로 총 40바이트의 메모리 공간을 확보한다. 저 칸 하나 하나가 0~9 인덱스의 값들이 저장되는 공간이다.
따라서 메모리 주소로 두 번째 요소(인덱스 1)을 찾는다 가정하면 <배열의 첫 번째 요소의 주소>(항상 배열은 첫 번째 요소의 주소를 가리킨다.) + <자료형*1>을 연산해 해당 요소의 메모리 주소를 구할 수 있다.
위 문제에 적용해보면 for문의 i는 사용자가 입력한 시작 위치의 인덱스 ~ 끝 위치의 인덱스까지의 값을 가지므로 *(p+sizeof(char)*i) 이렇게 작성하면 i의 값에 해당하는 인덱스의 값이 구해지는 것이다.
마지막으로 free를 사용해 배열 포인터 p를 다쓴 후 메모리 해제를 해줬다.
'Old (2021.01 ~ 2021.12) > Algorithm' 카테고리의 다른 글
CodeUp 1502 : 2차원 배열 채우기 2 (0) | 2021.03.07 |
---|---|
CodeUp 1098 : 설탕과자 뽑기 (0) | 2021.03.07 |
CodeUp 1581 : swap 함수 만들기 (0) | 2021.03.07 |
CodeUp WriteUp With C Language (0) | 2021.02.27 |
CodeUp 1076 ~ 1099 With Python (0) | 2021.02.04 |