ch11 1차원 배열

암영·2022년 5월 8일
0

c언어

목록 보기
12/21

11-1: 배열의 이해와 배열의 선언 및 초기화 방법

배열이란 무엇인가?

  • 배열(array)
    :자료형이 같은 데이터를 순서대로 나열한뒤 메모리에 연속으로 저장해 만든 자료 그룹.
    다수의 데이터를 저장하고 처리하는 경우에 유용하게 사용할 수 있음.

1차원 배열의 선언에 필요한것 세가지:배열이름,자료형, 길이 정보

int onenumber [4];

  • int :배열을 이루는 요소(변수)의 자료형
  • onenumber: 배열의 이름
  • [4] :배열의 길이

-> int형 변수 4개로 이뤄진 배열을 선언하되, 그 배열의 이름은 onenumber로 해라.

위 문장으로 인해 선언되는 배열의 형태

중요한점:int형 변수 네개가 나란히 선언되었다는점.

+) 배열의 길이 정보는 상수로!
:변수를 이용해 길이 선언이 가능한 컴파일러도 있지만 범용적인 컴파일을 위해서는 배열의 길이정보는 상수로 지정해야한다.

선언된 1차원 배열의 접근

int arr[3]; //길이가 3인 int형 1차원 배열의 접근.

위 배열을 대상으로 값을 저장때는 다음 형태로 접근 한다

arr[idx]=20; -> "배열 arr의 idx+1번쨰 요소에 20을 저장해라!"

ex) arr[0]=10; //배열 arr의 첫번째 요소에 10을 저장해라!
arr[1]=20; //배열 arr의 두번째 요소에 20을 저장해라!

  • []연산자 사이에 배열의 위치 정보를 명시함.(이 위치에 들어가게 되는 숫자:인덱스/인덱스값)
  • 배열 정보를 명시하는 인덱스 값은 1이 아닌 0에서부터 시작한다.

예제)

#include<stdio.h>
int main()
{
	int arr[5];
	int sum = 0, i;

	arr[0] = 10, arr[1] = 20, arr[2] = 30, arr[3] = 40, arr[4] = 50;

	for (i = 0; i < 5; i++)
		sum += arr[i];

	printf("배열요소에 저장된 값의 합: %d \n", sum);
	return 0;


}

예제를 통해 알수 있는것
" 배열의 모든 요소는 반복문을 이용해서 순차적으로 접근하는 것이 가능하다.

배열! 선언과 동시에 초기화 하기

기본 자료형 변수들은 선언과 동시에 초기화가 가능하다. 마찬가지로 배열도 선언과 동시에 원하는 초기화가 가능하다. 초기화의 방법은 총 세가지이다.

  1. int arr[5]={1,2,3,4,5}; //순차적으로 1,2,3,4,5로 초기화함

중괄호 내에 초기화 할 값들을 나영하면, 해당값들이 순서대로 저장된다.

  1. int arr2[]={1,2,3,4,5,6,7}; //컴파일러에 의해 자동적으로 인덱스 값에 7이 삽입됨.

초기화를 목적으로 '초기화 리스트'가 선언되면, 배열의 길이 정보를 생략할수 있다. 이런 경우, 컴파일러가 초기화 리스트 수를 참조하여 길이 정보를 채워주기 때문이다. 즉 위의 문장은 다음 문장과 완전히 동일하다.
int arr2[7]={1,2,3,4,5,6,7};

  1. int arr3[5]={1,2}; // 3,4,5,번째의 배열요소는 0으로 채워짐.

배열의 길이를 다 채울 만큼 초기값이 선언되지 않은 경우 첫번째 요소 부터 순차적으로 값을 채워나가되 채울값이 존재하지 않는 요소들은 0으로 채워진다.

예제)

#include <stdio.h>

int main()
{
	int arr1[5] = { 1,2,3,4,5 };
	int arr2[] = { 1,2,3,4,5,6,7 };
	int arr3[5] = {1,2};
	int ar1len, ar2len, ar3len, i;

	printf("배열 arr1의 크기 :%d \n", sizeof(arr1));
	printf("배열 arr2의 크기 :%d \n", sizeof(arr2));
	printf("배열 arr3의 크기 :%d \n", sizeof(arr3));

	ar1len = sizeof(arr1) / sizeof(int); //배열 arr1의 길이 계산
	ar2len = sizeof(arr2) / sizeof(int); //배열 arr2의 길이 계산
	ar3len = sizeof(arr3) / sizeof(int); //배열 arr3의 길이 계산

	for (i = 0; i < ar1len; i++)
		printf("%d", arr1[i]);
	printf("\n");

	for (i = 0; i < ar2len; i++)
		printf("%d", arr2[i]);
	printf("\n");

	for (i = 0; i < ar3len; i++)
		printf("%d", arr3[i]);
	printf("\n");

	return 0;
}

궁금한점 & 추가

ar1len = sizeof(arr1) / sizeof(int); //배열 arr1의 길이 계산
-> 배열 arr의 길이를 계산하는데 이런 식이 쓰인이유
: 배열의 이름을 대상으로 하는 sizeof연산의 결과로는 '바이트 단위'의 배열크기가 반환된다. 따라서 배열의 크기가 아닌 길이를 계산하고 싶다면 위의 방식으로 계산 해야 한다..!

문제 11-1 : 1차원 배열의 활용

문제

  1. 길이가 5인 int형 배열을 선언해서 프로그램 사용자로부터 총 5개의 정수를 입력받자! 그리고 입력이 끝나면 다음의 내용을 출력해서 예제를 작성해보자.

  • 입력된 정수 중에서 최댓값
  • 입력된 정수 중에서 최솟값
  • 입력된 정수의 총합
    단, 반드시 입력을 완료한 상태에서 '최댓값'과'최솟값' 그리고 '총합'을 계산해야 한다. 참고로 배열을 대상으로 scanf문을 구성할때는 다음과 같이 해야한다.
    scanf("%d",&arr[2]); //3번째 배열 요소에 정수 값 입력받음.
    변수를 대상으로 & 연산자를 붙여주듯이, 배열요소를 대상으로 할때도 & 연산자를 붙여야 한다.
  1. char형 1차원 배열을 선언과 동시에 다음 문장의 내용으로 초기화 하고, 초기화 이후에는 저장된 내용을 출력하는 예제를 작성해보자.
    "Good time"
    참고로 c언어는 배열기반의 문자열 저장 및 출력에 대한 별도의 기준을 제공하고 있다. ->이건 11-2에서 공부.

정답

1.

#include<stdio.h>
int main()
{
	int arr[5];
	int i = 0, sum = 0;

	for (i = 0; i < 5; i++)
	{
		scanf_s("%d", &arr[i]);
		sum += arr[i];
	}


	int max =arr[0];
	int min = arr[0];

	for (i = 0; i < 5; i++)
	{
		if (max < arr[i])
			max = arr[i];
		if (min > arr[i])
			min = arr[i];
	}

	printf("입력된 정수중 최댓값:%d\n", max);
	printf("입력된 정수중 최솟값:%d\n", min);
	printf("입력된 정수의 총합:%d\n",sum);

	return 0;



}

2.

#include<stdio.h>
int main()
{
	char str[] = { 'G','o','o','d',' ','t','i','m','e' };
	int i = 0;
	int artlen = sizeof(str) / sizeof(char);

	for (i = 0; i < artlen; i++)
		printf("%c", str[i]);

	return 0;


}

11-2 배열을 이용한 문자열 변수의 표현

char형 배열의 문자열 저장과 '널(null)'문자

c언어 에서는 큰따옴표를 이용해 문자열 표현

char str[14]="Good morning!";

위의 선언을 통해서 메모리 공간에 char형 배열이 할당되고, 이 배열에는 다음의 형태로 문자열이 저장된다.

  • 문자열의 끝에는 '\0'이라는 특수문자가 자동으로 삽입되어 실제 문자열의 길이가 14가 된다. 따라서 문자열의 저장을 목적으로 char형 배열을 선언할 경우에는 툭수문자 '\0'이 저장될 공간까지 고려해서 배열의 길이를 결정해야 한다.
  • 문자열 끝에 자동으로 삽입되는 문자 '\0'을 가리켜 널(null)문자라고 한다.
    예제)
#include<stdio.h>
int main()
{
	char str[] = "Good morning!";
	printf("배열 str의 크기: %d \n", sizeof(str));
	printf("널문자 문자형출력: %c\n", str[13]);
	printf("널문자 정수형 출력 : %d\n", str[13]);

	str[12] = '?'; //배열 str에 저장된 문자열 데이터는 변경 가능!
	printf("문자열 출력: %s \n", str);

	return 0;
}
  • 예제를 통해 알수 있는점
    널 문자의 아스키코드 값은 0이며 이를 문자로 출력할 경우 아무런 출력이 발생하지 않는다.
    문자열을 입력받는 배열의 이름 앞에는 &연산자를 붙이지 않는다!

+) 공백 문자 vs 널문자
둘다 문자로는 출력되지 않지만, 널문자의 아스키 코드값은 0, 공백 문자의 아스키 코드값은 32로 다르다.

문자열 끝에 널(null)문자가 필요한 이유

메모리 상에서 문자열은 이진데이터로 저장되기 때문에 문자열의 시작과 끝이 표시되어있지 않다면 문자열을 구분하는 것은 불가능하다. 따라서 널문자를 이용해 문자열의 끝을 표시하는 것이다.

널문자가 있으면 문자열이다..!

char arr1[]={'h','i','~'}; //마지막에 널 문자가 없으므로 문자배열
char arr2[]={'h','i','~','\0'}; //마지막에 널 문자가 있으므로 문자열

예제

#include<stdio.h>
int main()
{
	char str[50] = "I like C prgramming";
	printf("string:%s\n", str);

	str[8] = '\0'; //9번째 요소에 널 문자 저장
	printf("string:%s \n", str);

	str[6] = '\0'; //7번째 요소에 널 문자 저장
	printf("string:%s \n", str);

	str[1] = '\0'; //2번째 요소에 널 문자 저장
	printf("string:%s \n", str);

	return 0;
}

+) 널문자의 아스키 코드값은 0
따라서 다음 두 문장은 동일하다.

str[8]='\0';
str[8]=0;

scanf 함수를 이용한 문자열의 입력과 scanf의 문자열 입력 특성

printf함수와 마찬가지로 문자열을 입력 받을때에도 서식문자 %s를 사용한다.

scanf의 함수가 데이터를 구분짓는 기준: 공백 따라서 he is my friend 라는 문장을 입력하면 he/is/my/friend 라는 총 4개의 문자열이 입력된 것으로 인식한다.
즉, scanf함수는 문장을 입력받기 적절하지 않다-> 하지만, 1)입력받고 출력하는 방법이 있으며 2) 공백을 포함하는 하난의 문장을 통째로 입력받을 떄 호출하는 함수가 있다.

공백이 있어도 출력하는 방법

#include <stdio.h>
int main()
{
	char str[50];
	int idx = 0;
	printf("문자열을 입력하세요");
	scanf_s("%[^\n]", str,sizeof(str));//용량을 써야함!!! 공백처리 하기

	
	printf("입력받은 문자열 %s\n \n", str);


	printf("문자단위 출력:");
	while (str[idx] != '\0')
	{
		printf("%c", str[idx]);
		idx++;
	}
	return 0;
}

%[^\n]: \n가 나오기 전까지는 계속 입력하라는 뜻
%s\n :\n가 나오기 전까지 계속 출력하라는 뜻.

문제 11-2 배열기반의 문자열표현

문제 1

프로그램 사용자로부터 하나의 영단어를 입력받아서 입력잗은 영단어의 길이를 계산하여 출력하는 프로그램을 작성해보자. 예를 들어서 array라는 단어가 입력되면 5가 출력되어야한다.

문제2

프로그램 사용자로부터 영단어를 입력잗아서char형 배열에 저장한다. 그 다음 배열에 저장된 영단어를 역순으로 뒤집는다. 물론 이때에 널문자의 위치를 변경해서는 안된다. 뒤집고 나서는 제대로 뒤집혔는지 확인해보자.

문제3

프로그램 사용자로부터 영단어를 입력받는다. 그리고 나서 입력받은 영단어를 구성하는 문자 중에서 아스키 코드의 값이 가장 큰 문자를 찾아서 출력하는 프로그램을 작성해보자. 예를 들어서 입력된 영단어가 "LOVE"라면 아스키코드 값이 가장 큰 문자는 V이므로 V가 출력되어야 한다.

정답

1.

#include<stdio.h>
int main()
{
	char str[100];
	scanf_s("%s", str,sizeof(str));//꼭 sizeof(str)써줘야 한다!
	int i = 0;
	while (str[i] != 0)
		i++;

	printf("단어의 길이는 %d \n",i);
	return 0;
}

틀린답

#include<stdio.h>
int main()
{
	char str[100];
	scanf_s("%s", str);
	int i = 0;
	int arlen = sizeof(str) / sizeof(char);

	printf("단어의 길이는 %d \n",arlen);
	return 0;
}
  • 꼭 sizeof(str)써줘야 한다!
  • 이렇게 하면 출력이 되기는 하는데 이미 문자열 길이를 100으로 지정해놨기 때문에 실제 문자열길이(array)는 나오지 않는다.
#include<stdio.h>
int main()
{
	char str[100];
	scanf_s("%s", str,sizeof(str));
	int i = 0;
	int arlen = sizeof(str) / sizeof(char);

	printf("단어의 길이는 %d \n", arlen);
	return 0;
}

11-1에서는 이렇게 길이를 출력한다고 했는데 문자열은 안되는 건가??

2.

틀린답

#include<stdio.h>
int main()
{
	char str[100];
	printf("문자열을 입력하시오");
	scanf_s("%s", str, sizeof(str));
	int i = 0;
	//문자 길이 구하기
	while (str[i] != 0)
		i++;

	int start = 0;
	char temp;
	for (start = 0; start <i / 2; start++)
	{
	
		temp=str[start];
		str[start] = str[i - 1];
		str[i - 1] = temp;
		i--;
	}
	printf("바뀐 문자열: %s", str);

	return 0;
}

역순 출력이 아니라 위치를 바꿔서 출력이 되기때문에 틀림
ex goodmorning은 gninmordoog로 출력이 된다.
왜 안바뀌지..?

정답

#include<stdio.h>
int main()
{
	char str[100];
	printf("문자열을 입력하시오");
	scanf_s("%s", str, sizeof(str));
	int i = 0;
	//문자 길이 구하기
	while (str[i] != 0)
		i++;

	int start = 0;
	char temp;
	for (start = 0; start <i / 2; start++)
	{
	
		temp=str[start];
		str[start] = str[(i-start) - 1];
		str[i-start - 1] = temp;
		
	}
	printf("바뀐 문자열: %s", str);

	return 0;
}


3.

#include<stdio.h>
int main()
{
	char str[100];
	printf("문자열을 입력하시오");
	scanf_s("%s", str, sizeof(str));
	int i = 0;
	char start = str[0];
	int len=0;
	

	while (str[len] != 0)
	{
		len++;
	}

	for (i = 0; i<len;i++)
		if (start < str[i])
		{
			start = str[i];
			
		}

	printf("아스키코드가 가장 큰 알파벳은 %c ", start);
	return 0;
}
profile
just do! -얼레벌레 굴러가는 공대생

0개의 댓글