1. 배열의 선언과 사용
동일한 자료형을 저장할 저장 공간이 많이 필요한 경우, 그리고 그 데이터들을 하나의 범주에 묶을 수 있는 경우 사용하는 자료형
자료형 배열명[요소 개수]
int arr[5];
: 정수 자료형의 요소 5개 배열 선언.
- 대괄호 안의 숫자
: 선언할 때는 배열 요소의 개수, 즉 배열의 크기를 정하는 것.
사용할 때는 배열에서의 위치, 인덱스를 나타내는 것. 배열의 특정 위치에 접근할 때는, 크기가 n인 배열에서 0에서부터 n-1으로 접근할 수 있음.
- 배열 초기화
: 변수를 선언할 때처럼, 선언한 직후 할당된 저장 공간에는 쓰레기 값이 저장되어 있음. 초기화가 필요함!!
(1)
int arr[5] = {1, 2, 3, 4, 5};
(2) 배열 요소보다 초기화 개수가 적은 경우, 나머지 공간은 0으로 초기화됨.
int arr[5] = {1, 2, 3};
(3) 자동 초기화
int arr[1000] = {0};
(4) 배열 요소 개수생략
컴파일러는 초기화할 때 사용하는 요소 개수만큼 배열의 크기를 정하고 저장 공간을 할당함.
int arr[] = {1, 2, 3};
* 배열을 처음 선언, 초기화한 이후에는 배열의 요소 하나 하나에 직접 데이터를 할당 / 저장해야 함.
- sizeof 연산자와 배열 처리
: 크기가 큰 배열을 처리할 때, 반복문을 사용해서 처리해야 함. 이때 배열의 크기가 바뀌면 배열 처리에 사용되는 반복문을 전부 수정해야 하는 불편함이 있음...!!
--> sizeof(배열명) / sizeof(배열 요소) 를 사용해서 배열 요소의 개수를 수정하지 않고도 크기가 달라진 배열을 처리할 수 있음.
- 배열명
: 배열명은 배열의 첫 요소가 저장된 메모리의 주소, 즉 포인터로서 활용될 수 있음
즉, arr과 &arr[0]이 같은 역할을 함.
[예제 코드]
(1)
#include <stdio.h>
int main(){
int arr[5];
arr[0] = 10;
arr[1] = 20;
arr[2] = arr[0] + arr[1];
scanf("%d", &arr[3]);
printf("%d\n", arr[2]); //30
printf("%d\n", arr[3]); //입력한 값
printf("%d\n", arr[4]); //쓰레기 값
}
(2)
#include <stdio.h>
int main(){
int score[5];
int i;
int total = 0;
double avg;
for(i = 0; i < 5; i++){
scanf("%d", &score[i]);
}
for(i = 0; i < 5; i++){
total += score[i];
}
avg = total / 5.0;
for(i = 0; i < 5; i++){
printf("%5d", score[i]);
}
printf("\n");
printf("평균 : %.1lf\n", avg);
}
(3) 배열 크기 바뀌더라도 수정 필요없는 코드
#include <stdio.h>
int main(){
int score[5];
int i;
int total = 0;
double avg;
int count = sizeof(score) / sizeof(score[0]);
for(i = 0; i < count; i++){
scanf("%d", &score[i]);
}
for(i = 0; i < count; i++){
total += score[i];
}
avg = total / 5.0;
for(i = 0; i < count; i++){
printf("%5d", score[i]);
}
printf("\n");
printf("평균 : %.1lf\n", avg);
}
(4) 확인 문제 2
#include <stdio.h>
int main(){
int arr[6] = {1, 2, 3};
for(int i = 0; i < sizeof(arr)/sizeof(arr[0]); i++){
printf("%d ", arr[i]);
}
}
(5) 확인 문제 3
#include <stdio.h>
int main(){
int A[3] = {1, 2, 3};
int B[10];
int i;
for(i = 0; i < 10; i++){
B[i] = A[i % 3];
}
for(i = 0; i < 10; i++){
printf("%d ", B[i]);
}
}
2. 문자를 저장하는 배열
- char형 배열
: 문자열(문자 여러 개)를 한 번에 저장할 때, 배열에 저장됨. 주의할 점은 문자열의 전체 길이보다 최소 하나 이상 크게 배열을 선언해야 함!
- NULL('\0') 문자
: 문자열을 배열에 저장할 때 문자 하나씩 배열 처음부터 저장되는데, 문자열이 저장된 후 남은 배열 공간에는 널 문자로 채워짐.
모든 문자는 아스키코드 값으로 저장되는데, 널 문자는 아스키코드 값이 0인 문자로 \0 으로표현됨.
* 문자열의 끝을 표시하는 역할. (저장된 문자열을 출력할 때 널 문자가 나올 때까지만 출력하도록 설정되어 있음..)
- 문자열 대입
: 문자열 처리와 관련된 함수는 <string.h> 헤더 파일에 저장되어 있으므로 코드 앞 쪽에 헤더 파일을 참조해야 함.
문자열 대입에 사용되는 strcpy
strcpy(str1, str2);
위 코드는 str1 배열에 str2 배열의 문자열을 복사하는 기능. 뒤에 위치한 문자열을 앞에 위치한 문자열에 대입하는 것! 저장할(복사할, 대입할) 문자열은 배열에 저장된 형태여도 되지만, 문자열 자체여도 가능
- 문자열 전용 입출력 함수
gets / puts
: 빈칸을 포함해 문자열을 입력받는 gets, 입력 받은 문자열 전체를 출력하는 puts. puts는 \n을 함께 출력함.
* 저장될 배열의 크기보다 입력 받을 문자열의 길이가 더 크면 오류가 발생하기도 함. 입력할 때 항상 배열의 크기를 고려해야 함!!
[예제 코드]
(1)
#include <stdio.h>
int main(){
char str[80] = "applejam";
printf("최초 문자열 : %s\n", str);
printf("문자열 입력: ");
scanf("%s", str);
printf("입력 후 문자열 : %s\n", str);
}
(2)
#include <stdio.h>
#include <string.h>
int main(){
char str1[80] = "cat";
char str2[80];
strcpy(str1, "tiger");
strcpy(str2, str1);
printf("%s, %s\n", str1, str2);
}
(3)
#include <stdio.h>
int main(){
char str[80];
printf("문자열 입력: ");
gets(str);
puts("입력된 문자열: ");
puts(str);
}
(4) 널 문자가 없는 문자열
#include <stdio.h>
int main(){
char str[5];
str[0] = 'O';
str[1] = 'K';
printf("%s\n", str);
}
(5) 확인 문제 3
#include <stdio.h>
#include <string.h>
int main(){
char str1[80], str2[80];
char temp[80];
printf("두 문자열 입력: ");
scanf("%s %s", str1, str2);
printf("바꾸기 전: %s, %s\n", str1, str2);
strcpy(temp, str1);
strcpy(str1, str2);
strcpy(str2, temp);
printf("바꾼 후: %s, %s\n", str1, str2);
}
(6) 도전 실전 예제
#include <stdio.h>
#include <string.h>
int main(){
char str[100];
int cnt = 0;
printf("문장 입력: ");
gets(str);
for(int i = 0; str[i]; i++){
if('A' <= str[i] && 'Z' >= str[i]){
str[i] = str[i] + ('a' - 'A');
cnt++;
}
}
printf("바뀐 문장: ");
puts(str);
printf("바뀐 문자 수 : %d\n", cnt);
}
방학을 즐기고 오니... 모르는 것들 투성이... 상태여서 늦었습니다 ㅜㅡㅜ... 끝까지 파이팅...!!!