배열
변수를 여러 개 사용해야 할 일이 생기면 하나씩 선언해주는 것이 여간 귀찮은 일이 아니다. 50명의 학생들의 평균 점수를 구하고자 한다면, 변수를 50개 선언해야 하는데 이는 너무 비효율적이다. 이러한 문제를 해결할 수 있는 것이 배열이다.
배열이란 같은 자료형의 변수들의 나열인데, 반복문과 함께 사용하면 변수가 몇 개가 있든 손쉽게 처리할 수 있는 특성을 가지고 있다. 배열을 선언하는 법은 다음과 같다.
자료형 이름[크기];
자료형 이름[크기] = {값, 값, 값, 값, ...};
위는 초기화 없이 선언할 때고, 아래는 선언과 동시에 초기화 해줄 때 사용된다. 만약 정수형 배열 arr를 10개만큼 생성했다고 가정하자. 생성은 int arr[10]과 같이 해야 하는데, 이렇게 하면 10개의 변수가 생성 된 것과 다름없다. 이 때, 각각의 변수는 0~9의 숫자로 구분된다. 맨 첫번째 변수는 arr[0], 두번째 변수는 arr[1], ... , 마지막 변수는 arr[9]가 된다. 이들 각각을 변수를 사용하듯이 사용하면 된다. 이 때 각각의 숫자를 인덱스(Index)라고 한다. 배열의 시작은 1이 아닌 0임을 주의해야 한다.
배열의 구조는 다음과 같다.
정수형 배열을 선언했기에, 각각의 인덱스는 4바이트의 크기를 가지므로, numArr 배열의 전체 크기는 40바이트이다. 또한, 배열을 선언할 때 첫 번째 인덱스의 주소가 00000004라고 한다면, 두 번째 인덱스는 바로 4바이트 뒤인 00000008, 세 번째 인덱스는 00000012와 같이 된다. 이 때, 배열의 이름은 첫 번째 인덱스의 주소가 된다. 만약 numArr를 %x로 출력해준다면, 주소 값이 나올 것이다.
배열은 for문과 함께 세트로 많이 쓰이는데, 이유는 바로 연속된 수로 구성되는 인덱스에 있다. 어떠한 배열이 생성되어도 인덱스는 0부터 1씩 증가하는 형태이기 때문에, 이를 for문을 통해 손쉽게 관리할 수 있다. 예를 들어 numArr[10]에 10개의 값을 각각 입력받는다고 해보자. for문을 이용하지 않은 코드는 다음과 같다.
#include <stdio.h>
int main(){
int numArr[10];
scanf("%d %d %d %d %d %d %d %d %d %d",
&numArr[0], &numArr[1], &numArr[2], &numArr[3], &numArr[4], &numArr[5],
&numArr[6], &numArr[7], &numArr[8], &numArr[9]);
printf("%d %d %d %d %d %d %d %d %d %d \n", numArr[0], numArr[1], numArr[2], numArr[3],
numArr[4], numArr[5], numArr[6], numArr[7], numArr[8], numArr[9]);
return 0;
}
배열의 크기가 10이 아니고 더 큰 상황이라면, 코드는 더 길어진다. 이를 for문을 이용하면 아래와 같다.
#include <stdio.h>
int main(){
int numArr[10];
for(int i=0; i<10; i++){
scanf("%d ", &numArr[i]);
}
for(int i=0; i<10; i++){
printf("%d ", numArr[i]);
}
printf("\n");
return 0;
}
이와 같이 for문을 활용해서 배열을 보다 편리하게 관리할 수 있다.
2차원 배열
1차원 배열은 일직선으로 나열 되어있는 형태이다. 2차원 배열은 가로와 세로가 존재하는, 2차원 평면의 형태를 구현할 수 있다. 기본 구조는 다음과 같다.
2차원 배열을 선언하는 방법은 다음과 같다.
자료형 이름[세로크기][가로크기];
2차원 배열을 선언하고 값을 출력하는 법은 다음과 같다.
#include <stdio.h>
int main()
{
int numArr[3][4] = { // 세로 크기 3, 가로 크기 4인 int형 2차원 배열 선언
{ 11, 22, 33, 44 },
{ 55, 66, 77, 88 },
{ 99, 110, 121, 132 }
};
// ↓ 세로 인덱스
printf("%d\n", numArr[0][0]); // 11 : 세로 인덱스 0, 가로 인덱스 0인 요소 출력
printf("%d\n", numArr[1][2]); // 77 : 세로 인덱스 1, 가로 인덱스 2인 요소 출력
printf("%d\n", numArr[2][0]); // 99 : 세로 인덱스 2, 가로 인덱스 0인 요소 출력
printf("%d\n", numArr[2][3]); // 132: 세로 인덱스 2, 가로 인덱스 2인 요소 출력
// ↑ 가로 인덱스
return 0;
}
2차원 배열도 마찬가지로 변수의 개수가 많을 경우 쉽게 접근하기 위해서 사용하는 것인데, 이차원 배열을 다룰 때에는 이중 for문을 사용해야 한다.
#include <stdio.h>
int main()
{
int numArr[3][4] = { // 세로 크기 3, 가로 크기 4인 int형 2차원 배열 선언
{ 11, 22, 33, 44 },
{ 55, 66, 77, 88 },
{ 99, 110, 121, 132 }
};
int col = sizeof(numArr[0]) / sizeof(int); // 4: 2차원 배열의 가로 크기를 구할 때는
// 가로 한 줄의 크기를 요소의 크기로 나눠줌
int row = sizeof(numArr) / sizeof(numArr[0]); // 3: 2차원 배열의 세로 크기를 구할 때는
// 배열이 차지하는 전체 공간을 가로 한 줄의 크기로 나눠줌
for (int i = 0; i < row; i++) // 2차원 배열의 세로 크기만큼 반복
{
for (int j = 0; j < col; j++) // 2차원 배열의 가로 크기만큼 반복
{
printf("%d ", numArr[i][j]); // 2차원 배열의 인덱스에 반복문의 변수 i, j를 지정
}
printf("\n"); // 가로 요소를 출력한 뒤 다음 줄로 넘어감
}
return 0;
}
위의 for문을 보면, 먼저 i는 0이고 j가 0부터 col-1까지 반복된다. 이 때 접근하는 배열의 인덱스는 arr[0][0] ~ arr[0][3]이 된다. 그 후에 i가 1이 되고 다시 j가 0부터 col-1까지 반복된다. 그러면 arr[1][0] ~ arr[1][3]까지 출력이 된다. 마지막으로 i가 2가 되고 j가 0부터 col-1까지 반복되면 arr[2][0] ~ arr[2][3]까지 출력 되고 프로그램이 종료된다. 이처럼 이차원 배열은 이중 for문과 짝지어서 쓰인다.
2차원 배열과 포인터
1차원 배열은 단일 포인터에 넣을 수 있듯이 2차원 배열은 이중 포인터에 넣을 수 있다.
int numArr[3][4] = { // 세로 크기 3, 가로 크기 4인 int형 2차원 배열 선언
{ 11, 22, 33, 44 },
{ 55, 66, 77, 88 },
{ 99, 110, 121, 132 }
};
int **numPtr = numArr; // 자료형이 다르다는 경고 발생
printf("%d\n", numPtr[0][0]); // 실행 에러
위와 같이 이중 포인터 numPtr을 선언한 후 numArr의 주소를 가리키게 한 후에, numPtr 변수를 배열처럼 이용해서 numArr의 각 인덱스에 접근할 수 있다. 단일 포인터를 활용해서도 선언할 수 있는데, 만약 가로의 크기를 4로 고정해주고 싶다면,
int (*numPtr)[4];
와 같이 선언해주면 된다. 이 경우엔, 가로의 크기가 4인 배열을 가리키는 포인터라는 의미가 된다. 괄호를 써준 이유는, 괄호 없이 *numPtr[4]로 선언하게 되면, 인덱스가 4개인 포인터를 선언하는 것이 되기 때문에, 꼭 괄호로 묶어주어야 한다.
배열과 포인터
배열의 이름은 첫 번째 인덱스의 주소를 나타낸다고 했다. 이를 이용해서 포인터를 선언해서 포인터로 배열을 다룰 수도 있다.
#include <stdio.h>
int main()
{
int numArr[10] = { 11, 22, 33, 44, 55, 66, 77, 88, 99, 110 }; // 크기가 10인 int형 배열
int *numPtr = numArr; // 포인터에 int형 배열을 할당
printf("%d\n", *numPtr); // 11: 배열의 주소가 들어있는 포인터를 역참조하면 배열의
// 첫 번째 요소에 접근
printf("%d\n", *numArr); // 11: 배열 자체를 역참조해도 배열의 첫 번째 요소에 접근
printf("%d\n", numPtr[5]); // 66: 배열의 주소가 들어있는 포인터는 인덱스로 접근할 수 있음
printf("%d\n", sizeof(numArr)); // 40: sizeof로 배열의 크기를 구하면 배열이 메모리에
// 차지하는 공간이 출력됨
printf("%d\n", sizeof(numPtr)); // 4 : sizeof로 배열의 주소가 들어있는 포인터의 크기를
// 구하면 포인터의 크기가 출력됨(64비트라면 8)
return 0;
}
numPtr이라는 포인터를 선언해서 배열의 첫 번째 인덱스의 주소를 가리키게 해준 다음, 역참조를 통해 numPtr을 출력하면, numArr[0]의 값인 11이 출력된다. 해당 포인터를 배열처럼 사용해서 numPtr[5]와 같이 사용해도, numArr[5]와 동일하게 동작하여 66을 출력한다. 이 때 주의할 점은 sizeof(numArr)는 10개의 int형이기 때문에 4byte * 10 = 40byte여서 40이 출력되지만, sizeof(numPtr)을 출력한다면, 이는 인트형 포인터이기 때문에 4가 나오게 된다.
위의 경우처럼 배열을 생성하고 포인터로 가리키는 방법이 아닌, 포인터 자체에 메모리를 할당받은 후에 이를 배열처럼 사용하는 방법도 존재한다. 먼저 위와 같이 10개의 정수를 저장할 공간을 만들고자 한다면, int형 10개 = 40byte이므로 40의 크기만큼 크기를 할당 한 후에, 배열을 사용하는 것과 동일하게 사용하면 된다. 이 때, 사용을 마쳤다면 꼭 free함수를 통해 해제를 해주어야 한다.
#include <stdio.h>
#include <stdlib.h> // malloc, free 함수가 선언된 헤더 파일
int main()
{
int *numPtr = malloc(sizeof(int) * 10); // int 10개 크기만큼 동적 메모리 할당
numPtr[0] = 10; // 배열처럼 인덱스로 접근하여 값 할당
numPtr[9] = 20; // 배열처럼 인덱스로 접근하여 값 할당
printf("%d\n", numPtr[0]); // 배열처럼 인덱스로 접근하여 값 출력
printf("%d\n", numPtr[9]); // 배열처럼 인덱스로 접근하여 값 출력
free(numPtr); // 동적으로 할당한 메모리 해제
return 0;
}
배열과 다르게 포인터로 선언한 배열은 값을 호출하는 방법이 한 가지 더 있다. 바로 역참조를 이용한 방법이다. numPtr[0]의 값을 가져오기 위해 역참조를 이용한 *numPtr 을 이용해도 동일한 값이 출력된다. 만약 numPtr[1]의 값을 가져오고자 한다면 *(numPtr + 1)로 작성해주면 동일한 결과를 얻을 수 있다. 만약 입력 받은 크기만큼의 배열을 선언하고 싶다면, 동적 할당을 sizeof(int) * 10이 아닌 sizeof(int) * input으로 해준다면, 입력 받은 만큼의 방이 생긴다.
2차원 배열의 경우 두번에 나누어서 할당해야 한다. 먼저, sizeof(int)가 아닌 sizeof(int *)의 크기를 세로의 길이만큼 할당해주어야 한다. 그 후에 세로의 길이만큼 for문을 돌면서 각 줄마다 가로의 길이만큼 할당 해주어야 한다. 코드는 아래와 같다.
#include <stdio.h>
#include <stdlib.h> // malloc, free 함수가 선언된 헤더 파일
int main()
{
int **m = malloc(sizeof(int *) * 3); // 이중 포인터에 (int 포인터 크기 * 세로 크기)만큼
// 동적 메모리 할당. 배열의 세로
for (int i = 0; i < 3; i++) // 세로 크기만큼 반복
{
m[i] = malloc(sizeof(int) * 4); // (int 크기 * 가로 크기)만큼 동적 메모리 할당.
// 배열의 가로
}
m[0][0] = 1; // 세로 인덱스 0, 가로 인덱스 0인 요소에 값 할당
m[2][0] = 5; // 세로 인덱스 2, 가로 인덱스 0인 요소에 값 할당
m[2][3] = 2; // 세로 인덱스 2, 가로 인덱스 3인 요소에 값 할당
printf("%d\n", m[0][0]); // 1: 세로 인덱스 0, 가로 인덱스 0인 요소의 값 출력
printf("%d\n", m[2][0]); // 5: 세로 인덱스 2, 가로 인덱스 0인 요소의 값 출력
printf("%d\n", m[2][3]); // 2: 세로 인덱스 2, 가로 인덱스 3인 요소의 값 출력
for (int i = 0; i < 3; i++) // 세로 크기만큼 반복
{
free(m[i]); // 2차원 배열의 가로 공간 메모리 해제
}
free(m); // 2차원 배열의 세로 공간 메모리 해제
return 0;
}
할당해줄 땐 세로->가로 순서로 할당해주었기 때문에, 해제할 땐 반대로 가로->세로의 순으로 해제해주어야 한다.
#36.10 퀴즈
배열의 선언 방법은 자료형 이름[크기]; 이다. 답은 c.
배열의 크기가 11이라면, 0~10까지의 인덱스를 가진다. 마지막 인덱스는 10이므로 답은 d.
배열의 전체 크기를 배열의 자료형으로 나누어주면 인덱스의 개수를 알 수 있다. 답은 e.
numArr[100]의 범위는 0~100이다. 해당 범위를 벗어나는 a, e가 답.
#36.11 연습문제: 점수 평균 구하기
#include <stdio.h>
int main()
{
float scores[10] = { 67.2f, 84.3f, 97.0f, 87.1f, 71.9f, 63.0f, 90.1f, 88.0f, 79.7f, 95.3f };
float sum = 0.0f;
float average;
for (int i = 0; i < sizeof(scores) / sizeof(float); i++)
{
①____________________
}
②_________________________________________________
printf("%f\n", average);
return 0;
}
for문을 순회하면서 scores의 각 요소들을 sum에 더해주어야 한다. 모두 더해준 후에는 average에 sum을 갯수로 나누어준 값을 저장하면 된다. 여기선 10개로 명시되었기에 sum을 10으로 나눠주면 되지만, 갯수를 모르는 경우엔 sizeof(scores) / sizeof(float)와 같은 방법으로 갯수를 구해서 나누어주면 된다.
sum += scores[i];
average = sum / ( sizeof(scores) / sizeof(float) );
#36.12 연습문제: 2진수를 10진수로 변환하기
#include <stdio.h>
int main()
{
int decimal = 0;
int binary[4] = { 1, 1, 0, 1 }; // 1101 순서대로 저장됨
__________________________________________________________
...
__________________________________________________________
printf("%d\n", decimal);
return 0;
}
실행 결과
13
십진수 decimal 변수에 이진수 1101을 비트 단위로 저장해 준 다음, decimal을 출력하면 10진수의 값이 나올 것이다. 방법은 binary 배열의 마지막 인덱스부터 시작해서 처음 수는 0번 왼쪽 시프트한 채로 저장하고, 두 번째는 1번 시프트, 세번 째는 2번 시프트해준 채로 decimal에 저장해주면 된다. 이를 코드로 작성하면 다음과 같다.
int position = 0;
for (int i = sizeof(binary) / sizeof(int) - 1; i >= 0; i--)
{
if (binary[i] == 1)
decimal += 1 << position;
position++;
}
#36.13 심사문제: 가장 작은 수 출력하기
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int numArr[5];
int smallestNumber;
scanf("%d %d %d %d %d", &numArr[0], &numArr[1], &numArr[2], &numArr[3], &numArr[4]);
_____________________________________
_____________________________________
_____________________________________
_____________________________________
_____________________________________
_____________________________________
_____________________________________
_____________________________________
printf("%d\n", smallestNumber);
return 0;
}
입력 예시
20 40 10 50 30
출력 예시
10
numArr를 순회하면서 가장 작은 수를 smallestNumber에 저장해야 한다. 최초에 smallestNumber는 초기화가 이루어지지 않았으므로 쓰레기 값이 들어있기 때문에, smallestNumber에 numArr[0]의 값을 저장해준 후에 numArr[1] ~ numArr[4]의 값들과 비교해주면 된다. 코드는 아래와 같다.
smallestNumber = numArr[0];
for(int i=1; i<sizeof(numArr)/sizeof(int); i++){
smallestNumber = smallestNumber > numArr[i] ? numArr[i] : smallestNumber;
}
#37.7 퀴즈
자료형 이름[세로 크기][가로 크기]에 맞게 선언하면 된다. 답은 c.
sizeof(numArr[0])은 2차원 배열의 가로 전체 크기를 나타낸다.
numArr의 전체 크기를 가로 전체의 크기로 나누면 세로의 크기가 나온다. 답은 d.
numArr[0]은 가로의 전체 크기를 나타낸다. 이를 배열의 자료형의 크기로 나누어주면 가로 인덱스가 몇개인지 알 수 있다. 답은 c.
numArr[2][2]의 인덱스는 numArr[0][0], numArr[0][1], numArr[1][0], numArr[1][1]이다. 이 범위를 벗어나는 것이 답이므로 답은 b, d, e.
#37.8 연습문제: 행렬의 주대각선 성분 구하기
#include <stdio.h>
int main()
{
int matrix[8][8] = {
{ 1, 2, 3, 4, 5, 6, 7, 8 },
{ 9, 10, 11, 12, 13, 14, 15, 16 },
{ 17, 18, 19, 20, 21, 22, 23, 24 },
{ 25, 26, 27, 28, 29, 30, 31, 32 },
{ 33, 34, 35, 36, 37, 38, 39, 40 },
{ 41, 42, 43, 44, 45, 46, 47, 48 },
{ 49, 50, 51, 52, 53, 54, 55, 56 },
{ 57, 58, 59, 60, 61, 62, 63, 64 }
};
____________________________________________________________
...
____________________________________________________________
return 0;
}
실행 결과
1 10 19 28 37 46 55 64
대각선의 원소를 모두 출력해야 한다. 행렬로써 접근하자면, i와 j가 같은 위치에 있는 수를 모두 출력해야 한다. (0, 0)부터 (7, 7)까지 출력해야하기 때문에, for문의 범위는 0부터 sizeof(matrix) / sizeof(matrix[0]) (배열의 세로의 길이) 까지로 작성해주면 된다.
for(int i=0; i<sizeof(matrix) / sizeof(matrix[0]; i++){
printf("%d ", matrix[m][m]);
}
#37.9 심사문제: 전치행렬 구하기
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int matrix[5][5];
scanf("%d %d %d %d %d",
&matrix[0][0], &matrix[0][1], &matrix[0][2], &matrix[0][3], &matrix[0][4]);
scanf("%d %d %d %d %d",
&matrix[1][0], &matrix[1][1], &matrix[1][2], &matrix[1][3], &matrix[1][4]);
scanf("%d %d %d %d %d",
&matrix[2][0], &matrix[2][1], &matrix[2][2], &matrix[2][3], &matrix[2][4]);
scanf("%d %d %d %d %d",
&matrix[3][0], &matrix[3][1], &matrix[3][2], &matrix[3][3], &matrix[3][4]);
scanf("%d %d %d %d %d",
&matrix[4][0], &matrix[4][1], &matrix[4][2], &matrix[4][3], &matrix[4][4]);
______________________________________
______________________________________
______________________________________
______________________________________
______________________________________
______________________________________
______________________________________
______________________________________
return 0;
}
입력 예시
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25
출력 예시
1 6 11 16 21
2 7 12 17 22
3 8 13 18 23
4 9 14 19 24
5 10 15 20 25
전치행렬은 대각선을 기준으로 대칭점에 있는 두 원소가 바뀌어진 행렬을 말한다. 전치행렬을 구하기 위해선 2중 for문을 이용해 출력을 하되, 출력할 때 arr[i][j]가 아닌 arr[j][i]를 출력해주면 된다.
for(int i=0; i<sizeof(matrix[0]) / sizeof(int); i++){
for(int j=0; j<sizeof(matrix) / sizeof(matrix[0]); j++){
printf("%d ", matrix[j][i]);
}
printf("\n");
}
#38.5 퀴즈
float형 포인터에 float의 사이즈 * 10개만큼 할당하면 된다. 답은 d.
2중 포인터를 선언한 후에 세로 길이 만큼 할당한다. 그 후에 for문을 세로 길이만큼 순회하면서 각각의 줄에 가로 길이만큼 할당해주어야 한다. 답은 b.
#38.6 연습문제: 포인터에 할당된 메모리를 3차원 배열처럼 사용하기
#include <stdio.h>
#include <stdlib.h>
int main()
{
long long ***m = malloc(sizeof(long long **) * 2);
①_____________________________________________________
...
______________________________________________________
m[1][2][4] = 100;
printf("%lld\n", m[1][2][4]);
②_____________________________________________________
...
______________________________________________________
free(m);
return 0;
}
포인터로 2차원 배열을 구현하는 법은 세로->가로의 순이였다. 3차원 배열은 높이->세로->가로의 순으로 할당해주면 된다. 먼저 높이 만큼 할당해준다. 그 후, 높이만큼 for문을 순회하면서 각각의 높이마다 세로만큼 할당해준다. 그 후에 세로만큼 for문을 순회하면서 각각의 세로에 가로만큼 할당해주면 된다. 반대로 해제할 땐 가로->세로->높이 순으로 해제하면 된다. 코드로 작성하면 다음과 같다.
for(int i=0; i<2; i++){
m[i] = malloc(sizeof(long long *) * 3);
for(int j=0; j<3; j++){
m[i][j] = malloc(sizeof(long long) * 5);
}
}
for(int i=0; i<2; i++){
for(int j=0; j<3; j++){
free(m[i][j]);
}
}
#38.7 심사문제: 단위행렬 만들기
입력 예시
5
출력 예시
1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0
0 0 0 0 1
입력된 숫자만큼 세로, 가로를 할당한 후에 모든 원소를 0으로 초기화해주고 (0, 0), (1, 1), (2, 2) ... (input-1, input-1)에 모두 1을 저장해주면 된다. 코드는 다음과 같다.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(){
int input;
scanf("%d", &input);
int **matrix = malloc(sizeof(int *) * input);
for(int i=0; i<input; i++){
matrix[i] = malloc(sizeof(int) * input);
for(int j=0; j<input; j++){
matrix[i][j] = 0;
}
}
for(int i=0; i<input; i++){
matrix[i][i] = 1;
}
for(int i=0; i<input; i++){
for(int j=0; j<input; j++){
printf("%d ", matrix[i][j]);
}
printf("\n");
}
for(int i=0; i<input; i++){
free(matrix[i]);
}
free(matrix);
return 0;
}
#38.8 심사문제: 지뢰찾기
해당 위치가 지뢰라면 인접 8방향에 지뢰가 없는 지역에 1씩 더해주어야 하고, 지뢰가 아니라면 그냥 넘어가야 한다. 먼저 2차원 배열을 동적할당을 통해 생성한다. 그 후에 2차원 배열을 한번 순회하기 위해 2중 for문을 사용한다. 이 때, matrix[i][j]가 지뢰면 continue를 통해 넘어가고, 지뢰가 아니라면 근처에 지뢰가 몇개가 있는지 카운팅 한다. 이 때, 확인해야 하는 범위가 (i-1, j-1), (i-1, j), (i-1, j+1), (i, j-1), (i, j+1), (i+1, j-1), (i+1, j), (i+1, j+1) 이기 때문에, 이를 하나하나 확인하는 것도 방법이지만 for문을 두 개 사용해서 작성해 주었다. y를 i-1부터 i+1까지, x를 j-1부터 j+1까지로 지정해주면 위의 8개 방향을 모두 확인할 수 있다. 이 때, y=i, x=j인 경우는 자기 자신이기 때문에 if문을 작성해서 continue를 넣어주면 된다. 이 때, x, y의 범위가 배열의 크기를 벗어날 수 있기 때문에 항상 범위를 확인해주고 범위를 벗어나면 continue를 통해 다음 반복으로 넘어가주면 된다. 인접의 인덱스가 지뢰라면 matrix[i][j]를 1증가시켜준다. 지뢰가 아닌 곳엔 모두 ' . '이 들어가있기 때문에, 나중에 출력해줄 때 지뢰는 그대로 출력해주고 지뢰가 아닌 경우 matrix[i][j]-'.'을 해주면 카운팅 한 숫자만 출력되게 된다. 코드는 아래와 같다.
#include <stdio.h>
#include <stdlib.h>
int main(){
int row, col;
scanf("%d %d", &row, &col);
char **matrix = malloc(sizeof(char *) * col);
for(int i=0; i<col; i++){
matrix[i] = malloc(sizeof(char) * (row+1));
scanf("%s", matrix[i]);
}
for(int i=0; i<col; i++){
for(int j=0; j<row; j++){
if(matrix[i][j] == '*')
continue;
else{
for(int y=i-1; y<=i+1; y++){
for(int x=j-1; x<=j+1; x++){
if(x==j && y==i)
continue;
if(x<0 || x>=row || y<0 || y>=col)
continue;
if(matrix[y][x]=='*')
matrix[i][j]++;
}
}
}
}
}
for(int i=0; i<row; i++){
for(int j=0; j<col; j++){
if(matrix[i][j]=='*')
printf("*");
else
printf("%d", matrix[i][j]-'.');
}
printf("\n");
}
return 0;
}
'Programming > C' 카테고리의 다른 글
[ProjectH4C] 코딩도장 Unit 41~45 Write-Up (0) | 2020.07.24 |
---|---|
[ProjectH4C] 코딩도장 Unit 39~40 Write-Up (0) | 2020.07.23 |
[ProjectH4C] 코딩도장 Unit 34 ~ 35 Write-Up (0) | 2020.07.22 |
[ProjectH4C] 코딩도장 Unit 33 Write-Up (0) | 2020.07.16 |
[ProjectH4C] 코딩도장 Unit 32 Write-Up (0) | 2020.07.16 |