728x90
반응형
Chapter 8 배열
1. 배열의 선언과 사용
- 같은 형태의 많은 데이터를 반복문으로 처리하기 위해
메모리에 연속적으로 저장해 놓고 쪼개서 사용하는 방법
1) 배열의 선언
- 배열 또한 다른 자료형처럼 선언을 통해서 저장 공간을 확보
- 하나의 이름으로 한꺼번에 확보
- 저장 공간의 개수와 상관없이 하나의 이름을 사용
// 8-1 5명의 나이를 저장할 배열을 선언하고 사용하는 방법 |
#include <stdio.h> int main(void) { int ary[5]; ary[0] = 10; ary[1] = 20; ary[2] = ary[0] + ary[1]; scanf("%d", &ary[3]); printf("%d\n", ary[2]); printf("%d\n", ary[3]); printf("%d\n", ary[4]); return 0; } |
50 30 50 -858993460 |
- 변수를 선언할 때
- 각 변수는 독립적인 저장 공간을 가지며 각각의 이름을 사용
- 배열로 선언할 때
- 저장 공간이 연속으로 할당되며 배열명이 전체 공간의 이름이 됨
- int형 변수는 크기가 4바이트이므로 5개를 연속으로 할당하면 총 20바이트가 할당됨
- 배열의 나누어진 조각을 배열 요소(element)라고 하는데, 각각의 배열 요소는 int형 변수와 똑같이 사용
- 배열 요소는 배열명에 첨자(index)를 붙여 표현하며 index는 0부터 시작
(1) 배열의 사용
- 배열을 선언할 떄와 배열 요소를 사용할 때 대괄호([ ]) 속 숫자의 의미는 다르다.
- 선언할 때는 배열 요소의 전체 개수를 표시하며, 사용할 때는 각 요소가 배열에서 몇 번째에 있는지를 의
[ 배열의 첨자가 사용 범위를 벗어난다면 ]
- 침범한 영역이 어떤 용도로 사용되느냐에 따라 결과가 달라짐
- 컴파일러가 경고 메시지로 알려 주기도 하지만 배열 요소에 포인터 연산을 통해 접근하므로
확실한 에러 메시지를 표시하지 않는다. - 범위를 벗어난 영역에 접근하는 배열 코드는 실행 단계에서 문제를 일으킬 때나 발견할 수 있으므로
버그를 찾아내기 힘들다;;;;
2) 배열 초기화
- 배열도 변수와 마찬가지로 최초 할당에 저장 공간에는 쓰레기 값이 저장되어 있다.
- 배열도 원하는 값을 가지려면 선언과 동시에 초기화해야한다.
- 배열은 중괄호로 묶어서 초기화
[ 초기화 1 ] 기본적인 초기화 방법
- 첫 번째 요소부터 차례로 초기화 됨
[ 초기화 2 ] 초깃값이 배열 요소의 개수보다 적은 경우
- 왼쪽부터 차례로 초기화하고 남은 배열 요소는 모두 0으로 채운다.
[ 초기화 3 ] 자동 초기화 기능
- 배열 요소 개수가 아무리 많아도 모든 요소를 쉽게 0으로 초기화할 수 있습니다.
[ 초기화 4 ] 배열 요소 개수가 생략된 형태
- 이 경우 컴파일러는 초깃값 개수만큼 배열 요소 개수를 정하고 저장 공간을 할당함
- 아래 그림과 같이 메모리에 저장 공간이 할당되고 초기화
[ 초기화 5 ] double형 배열과 char형 배열을 선언하고 초기화
- 각각의 자료형에 맞게 double형 배열은 실수 값으로 초기화
- char형 배열은 문자로 초기화
- 배열의 초기화는 선언 시 최초 한 번만 가능
- 그 이후에는 배열 요소에 일일이 값을 대입해야함
- 초기화 때 처럼 중괄호를 사용한 대입 연산으로 한 번에 값을 바꾸는 것은 불가
3) 배열과 반복문
- 연속된 저장 공간을 할당하고 초기화할 수 있어 같은 유형의 변수가 많이 필요할 때 배열을 사용
// 8-2 배열과 반복문을 사용한 성적 처리 프로그램 |
#include <stdio.h> int main(void) { 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); return 0; } |
80 95 77 84 100 80 95 77 84 100 평균 : 87.2 |
4) sizeof 연산자를 활용 배열 처리
- 많은 양의 데이터를 처리하므로 배열을 다룰 때는 반복문이 필수!
- 배열 요소의 개수가 바뀌면 배열을 처리하는 반복문을 모두 수정해야하는 부담이 있다
- 이 문제의 해결책으로 배열 요소의 개수를 직접 계산에 반복문에 사용하는 방법을 사용할 수 있음
// 8-3 sizeof 연산자를 사용한 배열 |
#include <stdio.h> int main(void) { int score[5]; int i; int total = 0; double avg; int count; 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 / (double)count; for (i = 0; i < count; i++) { printf("%5d", score[i]); } printf("\n"); printf("평균 : %.1lf\n", avg); return 0; } |
80 95 77 84 100 80 95 77 84 100 평균 : 87.2 |
[ 확인 문제 8 - 1 - 1 ]
정수 5개를 저장할 배열 | 실수 10개를 저장할 배열 | 배열 요소 개수가 3개인 int형 배열 | 첨자의 최댓값이 4인 char형 배열 |
int ary[5]; | double ary[10]; | int ary[3]; | char ary[5]; |
[ 확인 문제 8 - 1 - 2 ]
int ary[6]={1,2,3} |
[ 확인 문제 8 - 1 - 3 ]
#include <stdio.h> int main(void) { 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( "%5d", B[ i ] ); } return 0; } |
2. 문자를 저장하는 배열
- 단어는 알파벳의 나열, 그 순서에 따라 단어의 뜻이 달라짐
- 모든 알파벳 문자는 한 바이트로 충분히 표현가능, char형 배열을 사용
1) char형 배열의 선언과 초기화
- char형 배열을 선언할 때 꼭 기억해야 할 점은 저장할 문자열의 길이보다 최소한 하나 이상 크게 배열을 선언해야한다.
- 여분이 공간이 필요한 이유!!
널 문자(\0)를 저장하기 위해!!!
8-4 // 문자열을 저장하는 char형 배열 |
#include <stdio.h> int main(void) { char str[80] = "applejam"; printf("최초 문자열 : %s\n", str); printf("문자열 입력 : "); scanf("%s", str); printf("입력 후 문자열 : %s\n", str); return 0; } |
최초 문자열 : applejam 문자열 입력 : grape 입력 후 문자열 : grape |
(1) 널문자(null character)의 용도
- char형 배열에 저장된 0
- 모든 문자는 아스키 코드 값으로 저장되며 결국 널 문자는 아스키 코드 값이 0인 문자를 말하며
문자 상수로는 \0으로 표현
- 널 문자는 문자열의 끝을 표시하는 용도로 사용됨
- printf 함수가 배열의 크기와 관계없이 초기화된 문자열만을 정확히 출력하는 것도 널 문자가 있기 때문
[ 여기서 잠깐 ] :: char형 배열 선언 시 초기화하지 않은 경우
- char형 배열 선언 시 초기화를 하면 남는 배열 요소가 0으로 채워지므로 자동으로 문자열의 끝에 널 문자가 저장되나,
초기화하지 않은 상태에서 배열 요소에 문자를 직접 대입한다면 반드시 마지막 문자 다음에는 널 문자를 대입
char str[80]; str[0] = 'a'; str[1] = 'p'; str[2] = 'p'; str[3] = 'l'; str[4] = 'e'; str[5] = '\0'; |
(2) char형 배열 선언 시 주의할 점
- 배열의 크기는 최대한 넉넉하게
- 배열 요소의 개수는 최소한 '문자열 길이+1'
2) 문자열 대입
- strcpy 함수
- char형 배열에 새로운 문자열을 저장하는 함수
- 저장할 문자열의 길이를 파악해 딱 그 길이만큼만 char형 배열에 문자열을 복사
- 물론 문자열 끝에 널 문자도 자동으로 붙여줌
8-5 // 문자열을 대입하는 strcpy 함수 |
#include <stdio.h> #include <string.h> int main(void) { char str1[80] = "cat"; char str2[80]; strcpy(str1, "tiger"); strcpy(str2, str1); printf("%s, %s\n", str1, str2); return 0; } |
tiger, tiger |
3) 문자열 전용 입출력 함수: gets, puts
- scanf 함수는 char형 배열에 문자열을 입력할 수 있지만
빈칸 전까지만 입력한다. - 빈칸을 포함해서 문자열을 입력할 수 있는 새로운 방식이 필요함.
8-6 // 빈칸을 포함한 문자열 입력 |
#include <stdio.h> int main(void) { char str[80]; printf("문자열 입력 : "); gets(str); puts("입력된 문자열 : "); puts(str); return 0; } |
문자열 입력 : Love is belief... 입력된 문자열 : Love is belief... |
(1) 빈칸을 포함해 문자열을 입력하는 gets 함수
- gets 함수는 문자열 입력 중간에 빈칸이나 탭 문자를 사용할 수 있다
- Enter를 누르기 전까지 전체를 하나의 문자열로 배열에 저장
- 마지막에 널 문자를 붙여서 문자열의 끝을 표시
(2) gets와 짝을 이뤄 문자열을 출력하는 puts 함수
- puts 함수는 문자열 상수나 char형 배열의 배열명을 주면 문자열을 화면에 출력한다.
- printf 함수의 문자열 출력 기능과 같음
- 문자열을 출력한 후에 자동으로 줄을 바꾸는 차이가 있음
4) 문자열의 끝에 널 문자가 없다면?
- printf 함수를 비롯한 많은 문자열 처리 함수가 널 문자로 문자열의 끝을 확인한다.
- 따라서 char형 배열에 무엇을 저장하든 널 문자가 나올 때까지가 하나의 문자열이다.
8-7 널 문자가 없는 문자열 |
#include <stdio.h> int main(void) { char str[5]; str[0] = '0'; str[1] = 'K'; printf("%s\n", str); return 0; } |
0K儆儆儆儆儆儆儆儆儆儆儆儆儆儆儆儆儆?m묤 |
- 배열이 초기화되지 않았으므로 배열에는 쓰레기 값이 남아있음
- 심지어 할당된 배열에 널 문자가 없으면 이어지는 메모리 영역까지 출력하고
- 널문자가 나올 때까지 출력한다.
728x90
반응형
'혼공 스터디 > 혼자 공부하는 C언어' 카테고리의 다른 글
[혼공C] 6주차 : 포인터 (1) | 2024.02.05 |
---|---|
[ 혼공C ] 4주차 : 함수 (1) | 2024.01.24 |
[ 혼공C ] 3주차 : 선택문, 반복문 (0) | 2024.01.17 |
[ 혼공C ] 2주차 : 변수와 연산자 (1) | 2024.01.13 |
[ 혼공C ] 1주차 공부 : C언어란? (2) | 2024.01.07 |