LAB/C

[24.08.06] C언어의 기초2

it-lab-0130 2024. 8. 7. 09:09

 

Chapter 3

 


[ASCII 코드]

영문 키보드로 입력할 수 있는 모든 기호들이 할당되어 있는 가장 기본적인 부호 체계이다. 매우 단순하고 간단하기 때문에 어느 시스템에서도 적용가능하다는 장점이 있다. 8비트 컴퓨터에서는 아스키 코드에 1비트를 더해 더 많은 문자를 표현할 수 있는 여지가 생겼다.

8비트 내에서 2의 8제곱으로 256가지로 경우의수를 나타낼수있다.

#include<stab.h>
int main(void)
{
    // 문자와 문자열은 다르다. 
    // 문자와 문자열은 상수 
    // 문자열은 문자가 끝이라는 문자가 들어감 
    printf("%c\n",65); // 문자 A출력
    printf("%d\n",'A');// Ascii코드 A 10진수 (65)츌룍
    printf("%c\n", 'A'); // %c Character (문자)
    printf("%s\n","A");  // %s String (문자열)
    printf("%c은 %s입니다.", '1', "first\n\n");

    return 0;
}
 

*** 유니코드 : 모든언어를 데이터로 표현하는 코드 / 한글자 당 2바이트 / 한글은 한글자당 3바이트


[C언어 기초]

*** c언어 자료형 변수 선언

// platinum.c  -- your weight in platinum  (플래티넘 가치로 계산한 몸무게)/
#include <stdio.h>
int main(void)
{
    //const float weight : 변하지 않는 상수로 선언 
    float weight;    //  몸무게           / float 안쓰고 double 또는 long을 많이 쓴다.
    float value;     //  플래티넘 가치로 계산한겂    

    // 사용자 안내문
    printf("당신의 몸무게를 플래티넘 가치로 계산하면 얼마나 나갈까요?\n");
    printf("어디 한번 계산해 봅시다.\n");
    printf("몸무게를 파운드 단위로 입력하시오: ");

    // 사용자로부터 입력값을 받는다.   scanf() 입력 받는곳                 
    scanf("%f", &weight);
    /* 
    %d : 입력값이 1.1 이면 1 / %f : 입력값이 1이면 1.0으로 출력 
    scanf() :키보드 입력을 제공한다. %f는 scanf()함수에게 키보드로부터 부동소수점 수를 하나 
    읽으라고 지시한다. &weight는 scanf()함수에게 입력받은 값을 weight라는 이름의 변수에 대입
    하라고 지시한다.
    즉, weight라는 변수가 어디에 위치해 있는지를 나타내기 위해 &기호를 사용한다. 
    */
    // 플래티넘 가격이 온스당 $1700라고 가정한다.         
    // 14.5833은 상형 파운드 단위를 금형 온스 단위로 변환한다.
    value = 1700.0 * weight * 14.5833;
    printf("당신의 몸무게를 플래티넘 가치로 계산하면 $%.2f입니다.\n", value);
    printf("당신의 몸값은 그정도 가치가 나갑니다. 플래티넘 가격이 떨어지면,\n");
    printf("가치를 유지하기 위해 식사량을 늘려야 합니다.\n");

    return 0;
}
// 정수형 : (*)int, long, short 
// 문자형 : char 
// 문자열 : char[], char*
// 소수점 : float , (*)double, longdouble

// signed : 음수값을 포함한 정수 (생략가능 )
// unsigned : 양수
//int형 변수는 해당 컴퓨터의 1워드로 저장된다. 
//  int의 최소범위 4바이트 !!!! 
// 64비트 컴퓨터 와 32비트 컴퓨터 호환성을 위해 (int :4바이트)

// 변수 의 초기화 : 변수에 초기값을 대입하는것 
// int dogs,cats=94 돌아는 가지만 쓰지말자 
// printf()가 값을 출력하는데 사용하는 포맷으로 변환하기 때문에, %d(정수값 출력)를 포맷 지정자라 부른다.
#include <stdio.h>

int main(void)
{
    int a; // int형 a 선언
    int b,c; // 2개의 int형 변수 b,c를 동시에 선언
    double da; // double형 변수 da선언
    char ch; // char형 ch선언

    a = 10;
    b = a;
    c = a + 20;
    da = 3.5;
    ch = 'A';

    printf("변수 a의 값 : %d\n",a);
    printf("변수 b의 값 : %d\n",b);
    printf("변수 c의 값 : %d\n",c);
    printf("변수 da의 값 : %.1lf\n", da);
    printf("변수 ch의 값 : %c\n\n",ch);
     
    return 0;
}

 

 


 

*** Scanf() : 입력받기

scanf() 함수의 f는 formatted의 약자이며, 서식화된 입력을 받는다는 의미입니다.

이 함수는 입력받은 데이터를 어떤 서식으로 변환할지 서식 지정자(format specifier)를 통해 직접 지정할 수 있습니다.

 

int형 입력

%d :int형 타입 정수형 

char형 입력

%c :문자 타입 입력

char[ ]형 입력

%s :문자열 타입 입력 

double형 실수의 입력

scanf() 함수로 float형 실수를 입력받을 때는 서식 지정자로 '%f'를 사용하면 됩니다.

하지만 double형 실수를 입력받을 때는 printf() 함수에서처럼 '%f'를 사용하면 안 됩니다.

scanf() 함수로 double형 실수를 입력받을 때는 반드시 '%lf' 서식 지정자를 사용해야 정확한 값으로 입력받을 수 있습니다.

 

*** Scanf() 에서의 &(앰퍼샌드)의 의미

 

변수 앞에 &를 붙이게 되면 이는 해당 변수의 주소를 가리키게 됩니다.

int a; 라는 변수가 있다면 &a는 a의 주소를 가리킵니다.

scanf에서 두 번째 인자부터는 데이터를 받아들일 변수를 집어넣는데, 이때 &를 붙여서 변수의 주소를 가리키게 합니다.
이는 scanf에서는 전달되는 인자에 사용자가 입력 해준 값을 넣어주어야 하는데, 그 인자가 call by value 라면 복사만 될 뿐 인자로 넣어준 변수에는 들어오지 않기 때문에, call by reference를 이용하기 위해서 &를 붙입니다.

그렇기 때문에 일반 변수들을 보낼 때는 &을 붙여서 주소를 보내도록 하고 (call by reference).

배열의 이름과 같이 &를 붙이지 않아도 주소를 가리키는 것들은 &를 떼고 인자로 넣어주면 됩니다.

예를 들면 아래와 같이 변수와 배열이 존재한다고 했을 때, 
char a;
char arr[10]; 

변수는 scanf("%c", &a)을 넣어야 하고
배열의 이름과 같이 주소를 가리키는 것들은 scanf("%s", arr) 와 같이 &를 붙이지 않아도 됩니다.
만약 배열의 특정 위치는 변수와 같으니 역시 &를 붙여야겠죠 scanf("%c", &arr[2]) 이와 같이 말이죠.

 

**C언어에서 scanf 를 하다 보면 보안 경고가 뜰 때가 있습니다.
이 경고는 무시하셔도 되며 상단에
#define _CRT_SECURE_NO_WARNINGS
을 입력하면 해결이 됩니다.

이 경고는 scanf와 같이 _s가 붙지 않은 함수보다는 scanf_s와 같이 입력받을 데이터의 사이즈를 입력하는 _s류 함수를 사용하라는 경고입니다.
_s가 붙지 않은 함수는 함수에 사용할 데이터 사이즈를 입력하지 않기 때문에 오버플로우와 같은 메모리 관련 위험이 존재하기 때문입니다.

 

*** Scanf() 에 대한 변환 지정자

* 우리는 부동소수점 : %f  / 정수형 : %d / 문자형 : %c / 문자열형 : %s 만 알면된다.

+ double형 실수를 입력받을 때는 반드시 '%lf'  만 알면된다.

 

*** Printf()와 Scanf()에서 변환 지정 문자 차이점

- printf()함수는 float형과 double형 모두에 %f, %e, %E, %g, %G를 사용하지만 주로 "%f" 사용한다.

- Scnaf()함수는 float형에 대해서만 이들을 사용하고, double형에 대해서는 L(소문자 l)변경자를 사용

ex.) double형 실수 => %lf

*** Scanf() 에서 %s 지정자 사용할때

- %s 지정자를 사용하면, 화이트 스페이스가 아닌 어떠한 문자도 받아들일 수 있다.

따라서, scanf()는 화이트스페이스가 아닌 첫문자가 나타날 때까지 건너뛰고, 다시 화이트스페이스를 만날 때까지 계속해서 화이트 스페이스가 아닌 문자들을 읽는다.

- scanf()로 하여금 하나의 단어(화이트스페이스가 들어있지 않는 문자열)을 읽게 만든다.

- 필드 너비를 사용할 경우 , scanf()는 그 필드의 끝에서 멈추거나 첫 화이트스페이스에서 입력을 멈춘다.

- 필드 너비를 사용하여 하나의 %s에 지정자에 대해 scanf()가 하나 이상의 단어를 읽게 만들 수 없다.

 

*** Scanf()에서 %c 지정사 사용할때

- 모든 문자들을 공평하게 입력할 수 있다. 다음 입력 문자가 스페이스나 개행(\n)일지라도, 하나의 스페이스나 개행이 지정된 변수에 대입된다. (공백까지 다 입력됨)

 

*** Scanf()의 리턴값 (기억하자!!!)

* scanf()함수는 성공적으로 읽은 항목의 수를 리턴한다. 읽은 항목이 없을 때 (이와 같은 일은 수치 값이 기대되는 곳에 수치가 아닌 문자열을 타이핑했을때 일어난다.)

- scanf()는 0을 리턴한다. 파일의 끝이라고 알려진 어떤 조건을 만나면 EOF를 리턴한다. 

(EOF : stdio.h에 정의되어있는 하나의 특별한 값이다. 일반적으로 #define 지시자에 의해 EOF를 -1로 정의한다.)

 

 

 


*** printf () : 출력하기

정수형 출력 %d

실수형 출력 %f 

문자 출력 %c

문자열 출력 %s

*** 포맷 문자열 뒤에 오는 각 출력할 항목마다 하나씩 변환 지정자를 일대 일로 대응시켜야 한다!!!!!!!!!!

ex.) printf("볼 카운트가 %d 스트라이크 , %d 볼이었다.\n", strike); -> 두번째 %d에 대응하는 값을 빠뜨렸다.

이 실수에 대한 결과는 의미가 없다.

#include <stdio.h>

int main()
{
    unsigned int un = 3000000000; // 32비트 int형과
    short end = 200;              // 16비트 short형을 사용하는 시스템
    long big = 65537;
    long long verybig = 12345678908642;

    // %hd 는 short형 정수를 10진수로 출력
    // unsigned  long형 정수를 출력하려면 %lu를 사용하라.
    // long long형을 지원하는 시스템에서 그것의 부호있는 데이터형과 부호 없는 데이터형을 출력하려면 %lld와 %llu를 사용하라

    printf ("un = %u and not %d\n", un, un);
    printf("end = %hd and %d\n",end, end);
    printf("big = %ld and not %hd\n", big, big);
    printf("verybig = %lld and not %ld\n", verybig, verybig);

    return 0;
}

 

정수 / 실수형 출력

 

#include<stdio.h>
int main()
{
    int age; // 나이는 정수형
    double height; // 키는 실수형

    printf("나이와 키를 입력하세요: "); // 입력안내 메세지 출력
    scanf("%d%lf",&age,&height); // 나이와 키를 함께 입력
    printf("나이는 %d살, 키는 %.1lfcm입니다.",age,height);

    return 0;

}
 

실수형 출력

*** %.1f  / %.10f  : (마침표+숫자) .1 / .10 입력하고 + lf(LF) 하면 소수점이하 숫자 자리까지 출력 하라는 의미

#include <stdio.h>
int main()
{
    printf("%d\n",10);      // %d 위치에 10 출력
    printf("%lf\n", 3.4);   // %lf 위치에 3.4f를 소수점 이하 6자리까지 출력
    printf("%.1lf\n", 3.45); // 소수점이하 첫째자리까지 출력 (둘째 자리에서 반올림)
    printf("%.10lf\n", 3.4); // 소수점이하 10자리까지 출력

    printf("%d 과 %d의 합은 %d입니다.\m", 10,20,10+20);
    // 순서와 %d의 개수 맞춰 정수 입력 하기 
    printf("%.1lf-%.1lf = %.1lf\n\n",3.4,1.2,3.4-1.2);
    
    return 0;

}
 

문자 / 문자열 출력

#include <stdio.h>

int main()
{
    char ch;

    printf("키보드를 영문모드로 놓고, 문자하나를 입력하시오.\n");
    scanf("%c",&ch);  // 사용자가 문자를 입력한다.
    // Scanf()함수가 타이핑한 문자를 가져온다.

    printf("문자 %c에 대응하는 코드값은 %d이다.\n\n",ch,ch);
    // printf() 함수는 변수ch의 값을 두번 출력한다. 한번은 (%c에의해) 문자로 출력하고, 다른한번은 (%d에 의해) 정수로 출력한다.
    return 0;
}
#include <stdio.h>

int main()
{
    char grade; // 학점을 입력할 변수
    char name[20]; // 이름을 입력할 배열

    printf("학점 입력 : ");   
    scanf("%c", &grade);      // grade 변수에 학점문자입력
    printf("\n이름 입력 : "); 
    scanf("%s",name);        // &name : name의 주소값을 찾음 / name배열에 이름 문자열 입력, &사용하지않는다.
    // 문자열은 변수명(name)이 주소값을 찾는다. 그래서 &를 안적어두됨
    printf("%s의 학점은 %c입니다.\n\n",name,grade);

    return 0;
}
 

*** print() 플래그 

* 변경자와 플래그를 사용하는 예제

#define은 다음 c언어기초3 을 보러가자 ~

/* width.c -- 필드 너비 */

#include <stdio.h>
#define PAGES 959

int main()
{
    printf("*%d*\n",PAGES);
    printf("*%2d*\n", PAGES);
    printf("*%10d*\n", PAGES);
    printf("*%-10d*\n\n", PAGES);

    return 0;
    
}

 

- 서로 다른 4개의 변환 지정을 사용하여 같은 값을 네번 출력한다.

- 각각의 필드가 시작하고 끝나는 위치를 표시하기 위해 ' * (애스터리스크) '를 사용아였다.

- %2d : 너비가 2인 필드를 만들어야한다. 그런데 3자리가 필요한 정수이기 때문에 그 수에 맞게 필드가 자동으로 확장된다.

- %10d : 스페이스 10개에 해당하는 필드너비를 확보하고, 좌우 양편의 별표사이에 7개는 블랭크로, 3개는 숫자로채운다.

- 이때 숫자들은 오른쪽 정렬하여 출력한다.

- %-10d : 스페이스 10개에 해당하는 필드너비를 확보하지만, -플래그 때문에 숫자들은 왼쪽으로 정렬하여 출력한다.

 

*** Printf() 에서 "%"를  사용하고 싶다면 %%를 작성하면 %가 출력된다.

 

 


*** Printf()와 Scanf()에서의 * (애스터리스크) 변경자 

** Printf()에서의 *(애스터리스크) 변경자

- ' * ' : 필드 너비를 지정하는 수 대신에 *를 사용함으써 필드 너비가 얼마인지 알려주는 별도의 전달인자를 사용해야한다.

- %*d : 전달인자 리스트에 *를 위한 값과 d를 위한 값이 함께 들어있어야 한다.

ex.)  printf("%*d",width ,number) -> * 값 : width / d의 값 : number 가 들어간다.

/* 필드 너비가 가변적이다.*/
#include <stdio.h>
int main()
{
    unsigned width, precision;
    int number = 256;
    double weight = 242.5;

    printf ("필드 너비를 입력하시오: \n");
    scanf("%d", &width);
    printf("Number:%*d:\n",width,number);
    printf("필드 너비와 정밀도를 함께 입력하시오: \n");
    scanf("%d %d",&weight,&precision);
    // scanf("%d,%d",&weight, &precision); -> 입력할때 8,3을 입력해야 출력값이 242.500 나온다. 
    printf("Weight = %*.*f\n", width, precision, weight);
    printf("종료!\n");

    return 0;
}

 

** Scanf()에서의 * (애스터 리스크) 변경자

- scnaf()에서 %와 지정자 문자 사이에 *를 넣으면, scanf()가 그에 해당하는 입력을 건너뛴다.

/* Scanf()에서 * 입력을 건너뛴다.*/

#include <stdio.h>

int main()
{
    int n;

    printf("3개의 정수를 입력하시오: \n");
    scanf("%*d %*d %d",&n);
    printf("마지막으로 입력한 정수는 %d이다.\n\n");

    return 0;
}

 

 

** Printf()의 활용 팁

- 고정 필드 너비를 지정하는법 

- 데이터를 일정한 열 형식으로 정렬하여 출력해야 하는경우 유용하다.

#include<stdio.h>

int main()
{
    int val1,val2,val3;
    
    printf("입력1 : \n ");
    scanf ("%d %d %d", &val1,&val2,&val3);
    printf("%d %d %d\n", val1, val2, val3); 

    printf("입력2 : \n ");
    scanf ("%d %d %d", &val1,&val2,&val3);
    printf("%d %d %d\n", val1, val2, val3); 

    printf("입력3 : \n ");
    scanf ("%d %d %d", &val1,&val2,&val3);
    printf("%d %d %d\n", val1, val2, val3); 

    return 0;
}

 

- 하나의 열에 속하는 수들의 크기가 서로 다를 경우에, 들쭉날쭉한 열들로 출력된다.

 

- printf("%9d %9d %9d\n", val1,val2,val3);

 

#include<stdio.h>

int main()
{
    int val1,val2,val3;
    
    printf("입력1 : \n ");
    scanf ("%d %d %d", &val1,&val2,&val3);
    printf("%9d %9d %9d\n", val1,val2,val3);

    printf("입력2 : \n ");
    scanf ("%d %d %d", &val1,&val2,&val3);
    printf("%9d %9d %9d\n", val1,val2,val3);

    printf("입력3 : \n ");
    scanf ("%d %d %d", &val1,&val2,&val3);
    printf("%9d %9d %9d\n", val1,val2,val3);

    return 0;
}

 

- %d 띄고 %d 띄고 %d 지정자 사이에 블랭크를 넣으면, 출력할 수 있는 너비가 필드 너비보다 큰 경우에도 다음 수와 겹치지 않는다. 

 

- 문구 중간에 수를 삽입하여 출력 해야 한다면, printf("그 선수는 %.2f 마일을 3시간 달렸다.\n",distance);

#include<stdio.h>

int main()
{
    float distance;

    scanf("%f",&distance);
    printf("그 선수는 %.2f 마일을 3시간 달렸다.\n",distance);

    return 0;
    
}

 

- %.2f  -> %10.2f로 변경하면 

#include<stdio.h>

int main()
{
    float distance;

    scanf("%f",&distance);
    printf("그 선수는 %10.2f 마일을 3시간 달렸다.\n",distance);

    return 0;

}


 

*** signed / unsigned 선언 변수

*** 정수형 오버플로

signed : int형 숫자 범위 -2147483648 에서 시작한다.

unsigned : int형 숫자범위 0에서 시작한다.

#include <stdio.h>

int main()
{
    // signed : 음수 부터 양수까지 사용하겠다 선언 단, 생략가능  예) signed char : -128 ~ 127까지 범위
    // unsigned char : 0 ~ 255 까지 숫자를 저장할 수 있다.
    // 1byte 256가지
    // 0 ~ 255 까지 256개의 숫자에 1개를 표현
    
    unsigned int a ; // 양수전용으로 쓰고싶을경우  unsigned를 붙인다.

    a = 4294967295; // 큰 양수 저장
    // 가장 왼쪽 비트를 부호비트로 간주하여 -1 출력
    printf("%d\n",a); // %d로 출력 / %d: 10진수로 출력하는 변환문자
    a = -1;
    printf("%u\n\n", a); // %u로 출력 / %u: 부호없는 10진수로 출력하는 변환문자
    // 부호비트를 고려하지 않고 모든 비트를 10진수로 바꿔 4292967295를 출력 
    return 0;
    // unsigned int 는 %d출력값이 int max는 출력 되지 않는다. 
    // %d(singed int의 최소값 과 최대값 출력 / 양수 음수 포함한 출력)와 %u ()출력값은 다르다. 
}

 

*** 정수 오버플로

c 기초 플러스 83 P

// 정수 오버플로 

#include <stdio.h>

int main()
{
    int i = 2147483647;  //  signed int형 최댓값 
    unsigned int j = 4294967295; //  unsigned  int형 최댓값
    // 최대값에 도달하면 처음부터 다시 시작한다.
    // j 는 j+1 (오버플로)=> 0에서 다시 시작 
    // int형 변수i는 i+1(오버플로) => -2147483648에서 시작 i+2 => -2147483648 + 1 => -2147483647 값이 나온다. 

    printf("%d %d %d\n",i, i+1, i+2);
    printf("%u %u %u\n\n", j,j+1,j+2);

    return 0;
}

*** 피연산자 :연산자의 영향을 받는 애들 

컴퓨팅에서 피연산자는 데이터 그 자체를 대표함과 동시에 조작, 연산에 사용할 데이터를 지정하는 컴퓨터 명령의 일부이다.컴퓨터 명령은 덧셈이나 곱하기 X와 같은 명령을 기술하지만, 피연산자는 어느 X가 연산할지, 그리고 X의 값을 모두 지정한다.

*** 복합대입 연산자

* a += 20

* 복합 대입 연산자는 연산과 대입를 한꺼번에 표현할 수 있도록 도와줍니다. 다양한 종류가 있으며 기본적으로 대입 연산자와 산술, 비교, 논리, 비트 연산자가 합쳐진 구조

 

* 증감 연산자 / ++a(변수의 값을 1만큼증가) (a = a+1) or (a += 1) 
/ --a(변수의 값을 1만큼 감소) (a = a-1) or (a -= 1)

증감(증가, 감소) 연산자

증감 연산자는 변수의 값을 1씩 증가 또는 감소시킨 연산자이며, 위치에 따라 연산의 시점이 달라지고 전위(앞쪽)에 사용된 경우는 계산이 수행되기 전에 먼저 실행되지만, 후위(뒤쪽)에 사용된 경우에는 계산을 수행한 후 실행됩니다.

#include <stdio.h>

int main(void)
{
	int a = 10, b = 20;
	int res = 2;

	a += 20;               // a와 20을 더한 결과를 다시 a에 저장 (+=) a = a + 20
	res *= b + 10;         // b에 10을 더한 결과값에 res를 곱하고 다시 res에 저장 (*=)
    // res = (b + 10)
    // res = res * (b + 10)  같은 표현이다.
	printf("a = %d, b = %d\n", a, b);
	printf("res = %d\n", res);

	return 0;
}

 

*** 전위 ++a 표기 / 후위 a++표기

1. 전위 표기법 (prefix)

- 연산자를 먼저 표시하고 연산에 필요한 피연산자를 나중에 표기하는 기법이다.

  (ex. +AB)

 

2. 후위 표기법 (postfix)

- 피연산자를 먼저 표시하고 연산자를 나중에 표시하는 기법이다.

  즉, 컴파일러가 사용하는 방식이다. 

- 세미콜론 끝나고 실행!!!

  (ex. AB+)

 

3. 중위 표기법 (infix)

- 연산자를 두 피연산자 사이에 표기하는 방법으로 가장 일반적으로 사용되는 표현방법이다.

  즉, 이항 연산자 표현이 적합하다.

  (ex. A+B)


*** 문자와 문자열을 다른 타입이다.

문자 char ' ' / 문자열 char[20] " " : (작은따옴표)' ' 는 문자 (큰따옴표) " " 는 문자열

 

*** 문자와 문자열 출력

#include<stab.h>
int main(void)
{
    // 문자와 문자열은 다르다. 
    // 문자와 문자열은 상수 
    // 문자열은 문자가 끝이라는 문자가 들어감 
    printf("%c\n",65); // 문자 A출력
    printf("%d\n",'A');// Ascii코드 A 10진수 (65)츌룍
    printf("%c\n", 'A'); // %c Character (문자)
    printf("%s\n","A");  // %s String (문자열)
    printf("%c은 %s입니다.", '1', "first\n\n");

    return 0;
}
 
 

*** 문자열 입력 받을 때 &연산자를 사용하지않아도 된다.

#include <stdio.h>

int main()
{
    char grade; // 학점을 입력할 변수
    char name[20]; // 이름을 입력할 배열

    printf("학점 입력 : ");   
    scanf("%c", &grade);      // grade 변수에 학점문자입력
    printf("\n이름 입력 : "); 
    scanf("%s",name);        // &name : name의 주소값을 찾음 / name배열에 이름 문자열 입력, &사용하지않는다.
    // 문자열은 변수명(name)이 주소값을 찾는다. 그래서 &를 안적어두됨
    printf("%s의 학점은 %c입니다.\n\n",name,grade);

    return 0;
}
 
*** 문자열 
*** char fruit[6] 과 char fruit[20]의 차이
char fruit[6]  = "apple"; 
- 문자열 "apple"[5] + "Null"[1] 포함 하여 잡는다. 
char fruit[20] = "strawberry"
-  문자열 [20] 범위를 지정 해주었지만 컴퓨터는 "strawberry"[9] +"Null"[1]로 [10]만 인식된다.
즉, 범위를 넓게 지정해도 문자열 끝마치는 "Null"때문에 데이터를 끝까지 읽지 못한다. 
#include <stdio.h>

int main()
{
    char fruit1 = 'A';
    char fruit2 = 'P';
    char fruit3 = 'P';
    char fruit4 = 'L';
    char fruit5 = 'E';

    // 문자열은 [100]을 넣어도 데이터가 있는데까지 읽는다.
    // 뭘 입력할지 모른다면 공간을 넉넉하게 잡아도 문자열은 마지막 표시  NULL까지만 읽는다.
    // 문자열 "Apple" 5개 + NULL 포함 = 6개 잡는다.
    char fruit[6] = "apple"; // 큰따옴표로 문자열을 대입한다.
    // 문자열에는 대입연산자를 사용할 수 없다. / 문자열은 선언된 이후에 대입연산자로 문자열을 입력할 수 없다.

    char fruit[20] = "strawberry";

    printf("딸기 : %s\n", fruit);
    printf("딸기잼 : %s %s\n\n", fruit,"jam");

    return 0;

}

*** float / double

소수는 오차가 발생함 근사값을 측정해 연산함

float : 오차범위가 크고

double : 오차범위가 적다.

 


*** 자료형 변수의 크기

*** Size of() 연산자 

- sizeof()는 함수가 아니다. (연산자이다.) 

- C는 바이트 단위로 크기를 알려주는 sizeof()라는 내장 연산자를 가지고있다. 

- C99 와 C11은 sizeof()에 사용되는 이 데이터형을 위한 %zb지정자를 제공한다.

- 표준을 따르지 않는 컴파일러들은 %u 또는 %lu를 대신하여 쓰인다.\

- 괄호 사용 여부 : 데이터형의 크기를 원하냐 / 어떤 특정 양에 괄호를 사용하는 것은 옵션이다.

즉, 데이터형 대해서는 sizeof(char)나 sizeof(float)처럼 사용해야 하고,

특정 양에 대해서는  sizeof name 또는 sizeof 6.28처럼 사용할 수 있다. 

후자의 경우에, sizeof(6.28)과 같이, 괄호를 사용해도 된다.

#include <stdio.h>

int main(void)
{
    /* C99는 크기를 위해 %zd 포맷 지정자를 제공한다.*/
    printf("int형의 크기: %zd바이트 \n", sizeof(int));
    printf("char형의 크기: %zd바이트 \n", sizeof(char));
    printf("long형의 크기: %zd바이트 \n", sizeof(long));
    printf("long long형의 크기: %zd바이트 \n", sizeof(long long));
    printf("double형의 크기: %zd바이트 \n", sizeof(double));
    printf("long double형의 크기: %zd바이트 \n", sizeof(long double));

    return 0;
}

#include <stdio.h>

int main()
{
    int a = 10;
    double b = 3.4 ;
    printf("int 형 변수의 크기 : %d\n",sizeof(a));
    printf("double 형 변수의 크기 :  %d\n",sizeof(b));
    printf("정수형 상수의 크기 : %d\n",sizeof(10));
    printf("수식의 결과값의 크기 : %ld\n",sizeof(1.5 + 3.4));
    printf("char 자료형의 크기 %d\n",sizeof(a));
    // long d : %ld로 써야됨

    return 0;
}
 

 

 
 
*** 1바이트 8칸!!!!

char 1바이트

short 2바이트

int 4바이트

long 4바이트

long long 8바이트


*** const 상수는 변수에 들어가면 값을 변경할 수 없다. / 고정값

#include<stab.h>
int main(void)
{
    const int num = 10; // const 를 적으면 상수로 변함 
    // num = 10 은 상수 즉, 3.14(원주율) 변하지않는값을 지정한다.

    return 0;

}

*** bool연산자 : true/ false (1/0)

#include <stdio.h>

int main(void)
{
	int a = 10, b = 20, c = 10;        
	int res;                          
	                                   
	res = (a > b);                     
	printf("a > b : %d\n", res);
	res = (a >= b);                    
	printf("a >= b : %d\n", res);
	res = (a < b);                     
	printf("a < b : %d\n", res);
	res = (a <= b);                    
	printf("a <= b : %d\n", res);
	res = (a <= c);                    
	printf("a <= c : %d\n", res);
	res = (a == b);                    
	printf("a == b : %d\n", res);
	res = (a != c);                    
	printf("a != c : %d\n", res);

	return 0;
}
 

*** 논리연산자 기호 && || not : !

#include <stdio.h>

int main()
{
    int a = 30;
    int res;

    res = (a > 10) && (a < 20);
    printf("(a > 10) && (a < 20) : %d\n",res); // True : 1 / False :0
    res = (a < 10) || (a > 20);
    printf("(a < 10) || (a > 20) : %d\n",res);
    res = !(a >= 30);
    printf("! (a >= 30) : %d\n",res);
    
}
 

*** 조건1 || 조건2 =>or은 조건1이 True면 뒤에 조건2는 검사하지 않음 
*** 조건1 && 조건2 => and는 조건1이 true면 뒤에 조건2도 true인지 검사 함