CS50_배열_(2)[배열(1,2),문자열과 배열 그리고 활용]

김두미·2022년 6월 21일
0
post-thumbnail

1. 배열(1)

1) 칩에 어떻게 저장되나요?


c언어는 위 사진과 같은 여러 자료형이 있습니다.
각 자료형은 다른 크기의 메모리를 차지합니다.


컴퓨터나 휴대폰에는 RAM이있어 메모리역할을 합니다.
RAM에는 칩이 있는데 칩은 여러 바이트의 묶음을 저장합니다.


예를 들어 'H' 인 char을 저장한다고 하면 RAM내부의 칩에 1byte가 할당되어 H가 저장됩니다. 물론 'H'로 저장된 것은 아니고 ASCII코드로 변경하여 (즉, 숫자로)
해당 숫자를 이진수로 만들어 저장합니다.

추가로 c언어에서는
char은 작은 따움표(')를 사용하고
string의 경우 쌍따옴표(")를 사용합니다.

+ casting
< 하나의 자료형을 다른 종류로 바꾸는 행위 >



2) 배열이요?

c에서 하나 이상의 값들이 있고 그 값들이 서로 연결되어있다면 배열을 사용해서 묶을 수 있습니다. 배열은 값들의 리스트로 모두 같은 자료형의 값들이 같은 이름의 변수로 저장되어있습니다.

int scores[3]; // 컴퓨터에게 정수 3개를 위한 메모리를 달라고함 

scores[0] = 1;
scores[1] = 2;
scores[2] = 3;

위 코드와 같이 배열을 선언하고 각 자리에 값들을 할당할 수 있습니다.



2. 배열(2)

1) 평균을 구해봐요

#include<stdio.h>

int main(void)
{
	int scores[3];
    scores[0] = 72;
    scores[1] = 73;
    scores[2] = 33;
}
printf("Average : %i\n",(scores[0] + scores[1] + scores[2])/3);

이렇게 구할 수 있습니다. 하지만 이 코드는 너무 정적입니다.

#include<stdio.h>
const int N = 3;

int main(void)
{
	int scores[N];
    scores[0] = 72;
    scores[1] = 73;
    scores[2] = 33;
}
printf("Average : %i\n",(scores[0] + scores[1] + scores[2])/N);

이렇게 전역변수를 상수(const)로 지정하여 사용할 수 있습니다.
관행으로 상수의 변수명은 대문자로 적으며 코드 상단에 적습니다.

이를 함수로 만들면?


float average(int length, int array[]) 
{
	int sum = 0;
    for (int i=0; i<length; i++)
    {
    	sum += array[i];
    }
    return (float)sum / (float)length;
}

float average(int length, int array[]) 에서 float은 반환값으로
함수가 사용자에게 돌려주는 값입니다.

return (float)sum / (float)length; 에서는 return을 (float)을 이용하여 float을 형변환을 하였습니다.


혹시 int를 float으로 나누면 ?

보통 더 강력한 자료형이 나온다. 즉, float이 나옵니다.



3. 문자열과 배열

1) string은 어떻게 저장되나요 ?

string은 문자열(char, 1byte)의 배열으로 정해진 크기가 없습니다.

string s = "HI!";

s[0] 은 "H"를 s[1] 은 "I"를 의미합니다.
문자열의 끝을 알리기위해서 \0 (0으로 8bit) 가 마지막에 있습니다.
이를 널문자, null 종단 문자라고 합니다.
덕분에 문자열은 전부 (글자수 + 1) byte만큼의 공간을 차지합니다.

s는 3byte의 char와 1byte의 널 종단문자로 이루어져 있으므로 4byte의 공간을 차지하고 있는 것입니다.


printf의 동작방식도 이를 이용해서 만들어졌습니다.
연속해서 출력을 하다가 \0을 만나면 출력을 멈추는 것이죠.



4. 문자열의 활용

1) <string.h>

#include <string.h>

위 코드를 이용하면 string과 연관된 이미 정의된 함수들을 사용할 수 있습니다.
예를 들어 string의 길이를 반환하는 strlen함수가 있습니다.
strlen 함수의 프로토타입이 string.h에 있기 때문입니다.

#include <cs50.h>
#include <string.h>
#include <stdio.h>

int main(void) {
	string s = get_string("Input : ");
    printf("Output: ");
    int n = strlen(s);
    for (int i=0; i<n; i++ ){
    	printf("%c",s[i]);
    }
    printf("\n");
}

2) <ctype.h>

소문자를 대문자로 만들고 싶다면 ?

아스키코드 표를 참고하여 A = 65, a = 97인것을 알 수있습니다.
이 둘은 32차이가 납니다.
즉 소문자가 들어온다면 32를 빼주면 대문자가 나옵니다.

#include <cs50.h>
#include <string.h>
#include <stdio.h>

int main(void) {
	string s = get_string("Before : ");
    print("After : ");
    for (int i=0; n = strlen(s), i<n ; i++) {
    	if (s[i] >= 'a' && s[i] <= 'z') { // 소문자의 경우 
        	printf("%c",s[i]-32);
        }
        else { // 대문자의 경우 
        	printf("%c",s[i]);
        }
    }
}

이렇게 구현하면 됩니다.
더 쉽게는 라이브러리를 이용하면 됩니다.
cs50에 있는 함수중 ctype.h를 include하면 쓸수있는 함수 중 toupper라는 함수가 있습니다.

#include <cs50.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h> // toupper을 사용하기 위해 
 
int main(void) {
	string s = get_string("Before : ");
    print("After : ");
    for (int i=0; n = strlen(s), i<n ; i++) {
    	printf("%c",toupper(s[i]));
    }
}
profile
개발자를 꿈꾸는 대학생

0개의 댓글