C언어 정리1

728x90

C언어 정리1

 

학교 공부하면서 미흡했던 부분을 정리했다. 나중에 시간을 들여 다시 다듬어서 작성할 예정임.

 

 

헤더파일 : 외부소스 파일에 정의된 변수나 함수에 대한 레퍼런스
#include <stdlib.h>  -> 헤더파일 부분에는 ; 붙이면 안됨
<stdlib.h>
rand()
rand() % 10 : 0~9랜덤
rand() % 10 + 1 : 1~10랜덤
system("cls"); 콘솔창 지우기
system("timeout 1 > NULL"); 1초 대기
system("timeout -1 > NULL"); 엔터 칠 때마다 다음 명령 수행

<time.h>
srand((unsigned)time(NULL));
rand()함수는 결과의 순서가 정해져 있으므로 srand와 함께 써야함.
rand()사용전에 한번만 사용하기.

<math.h>
sqrt(7) -> 루트 7


if문, 반복문 쓸때 웬만하면 그냥 {} 쓰기. 자꾸 빼먹어서 틀리는 경우 많음.
멀쩡한데 뭐가 틀린거지? 싶으면 {}가 없는 경우가 많음!
while문 안에서 if, continue 쓸때, continue전에 반드시 증감문을 쓰기. 무한루프에 빠질 수 있음.


do {
...
} while ( 조건문 );  <- 세미콜론 반드시 붙이기.
조건문 어기면 그 밑에 코드로 진행됨.



반복문은 조건문을 어길때까지 변수의 증감이 일어남.
for (k = 1, m = 3; k < 5; k++, m++) 에서 for문이 끝난 후 k = 5, m = 7이 된다.

for, while문은 처음부터 조건에서 벗어나면 아얘 실행자체를 안함.


컴퓨터는 main()함수의 중괄호 안의 내용만 실행.
main호출은 운영체제가 함.
다른 함수들은 main()으로부터 직간접적으로 호출됨.
따라서 작업의 시작과 끝을 알리는 것은 중괄호.
return 0는 정상적으로 종료하는 것을 의미함.


라이브러리 (함수) : 미리 만들어 놓은 함수.
이러한 관련있는 함수들을 모아둔 파일을 헤더파일이라고 함.

들여쓰기는 컴파일러 번역에는 문제 없으나 사람이 읽기 힘들기 때문에 함.

주석 : 개발자의 메모. 소스코드 설명. 컴파일러는 주석을 skip

변수 : 데이터를 일시적으로 저장할 목적으로 사용하는 메모리 공간
초기화안하면 쓰레기값
=기호는 오른쪽 값을 왼쪽 변수에 넣음을 의미

int, float 4 바이트
short 2바이트
char 1바이트 영문자, *, \n만 가능.
double 8바이트
long 4바이트
long long 8바이트
printf("%d \n", sizeof(int)); 이런 방법으로 크기를 파악할 수 있음.

double형은 printf로 출력할때는 %f, %lf 둘다 가능하나 scanf로 입력받을때는 %lf만 써야함.

변수 여러개 선언시 주의사항
자료형이 다른 변수 선언은 한줄에 할 수 없음.
int x = 10, double y = 3.14; 불가능

int x, y = 20; x에는 쓰레기값, y에는 20이 대입

int x = 10; y = 20;  y의 자료형이 선언되지 않은 것으로 인식됨.

가능한 경우
int x, y;
int x = 10, y = 20;
int x = 10; int y = 20;


변수 이름 조건
영문자, 숫자, _를 사용. 첫글자는 영문자 또는 _만 가능
대,소문자 구별 가능.
예약어(키워드)와 같은 이름 허용안됨.
의미있는 이름으로 지을 것.


scanf앞에 printf를 사용하는것이 필수!

scanf("%d, %d", &a ,&b); 이런식으로 주면 입력할때도 a, b 이렇게 입력해야함.

배열자체가 주소값을 가지므로
char s[10];
scanf("%s", s); 로 &없이 값을 입력받음.

오른쪽 정렬, 공간확보.
%5d와 같은 방법은 printf로 출력할때만 사용되므로 scanf에서 이렇게 받지 않도록 유의


입력된 문자열을 배열에 저장할 때는 scanf 함수를 사용하며 배열 앞에는 &를 붙이지 않습니다.
char s1[10];        // 크기가 10인 char형 배열을 선언
scanf("%s", s1);    // 표준 입력을 받아서 배열 형태의 문자열에 저장


문자는 아스키코드 정수값으로 저장됨.
a라는 char 변수에 A를 입력받고 %c로 출력 => A 출력
%d로 출력 => 65

\n, \t는 제어문자(이스케이프문자)라고 함.
화면에 보이지 않지만 출력을 조절하기 위해 사용되는 문자.
\n은 아스키코드 문자로 한개의 문자로 취급됨.
\t : 탭
\b : 백스페이스, 한칸왼쪽이동
\r : 줄의 맨앞으로 이동

\"   " 출력
\'    ' 출력
\\   \출력
%%  %출력


상수형 변수는 반드시 선언과 동시에 초기화해야만 한다. 대문자로만 한다.
const double PI = 3.14;
절대로 변하지 않는 값


매크로상수 : 단순 반복 작은 작업
#define DIA 9    => 대문자 사용, 세미콜론 쓰지 않음
메모리를 차지하지는 않고, 컴파일전에 전처리 작업을 함.
컴파일 전에 DIA라는 문자를 모두 9로 바꿈.
printf("라벨 길이 = %.2lf\n", PI * DIA);  => DIA를 9로 바꾼 후 컴파일


리터럴 - 글자 그대로의 데이터, 소스에 적힌 값
double PI = 3.14;  -> 3.14는 실수리터럴
int i = 9;  -> 9는 정수 리터럴


공백 포함 문자열 입력 
char name[11];
scanf("%[^\n]s", name);
gets(name);


char a[0] 이런식으로 문자 하나를 읽거나 수정이 가능.


출력방식           10진수, 8진수, 16진수
printf("%d %d %d \n", 45, 045, 0x45);

scanf("%d %d", &a, &b);
여기에 10.0 10.0을 입력하면
a에 정수부분 10까지만 받고 나머지 부분은 완전히 지워져
b부분에 이상한 값을 받게 됨.
실수로 변수를 선언해서 실수값 받아놓고 정수형으로 출력하면
정수부만 출력된다는 사실.

C언어의 형변환은 자료형부분에 괄호가 쳐져야 한다.
sum = (int)a + (int)b;
위와같은 방법으로도 정수부만 출력하도록 할 수 있음.


공간확보 출력
%4d %2d ...

소수점 출력 제어
%.3f (소수점 셋째자리까지)

공간확보하면서 소수점 출력제어
%3.3f

%g -> 소수점 부분 짧게 출력
소수점 부분 완전히 날릴려면 (int)형변환해서 %d로 출력

long 변수형 %ld
long long 변수형 %lld

왠지 나올 것 같은 문제 유형

#include <stdio.h>
int main(){
    long long num;
    printf("원하는 한 달 용돈 액수 : ");
    scanf("%lld", &num);
    printf("==> 3개월치 용돈 %lld 원이 한꺼번에 입금되었습니다 ^^", 3*num);
    return 0;
}


가장 작은 숫자 포함 long long
가장 큰 숫자 포함 (unsigned)long long


나눗셈 출력결과가 소수로 나오도록 하려면 분자 또는 분모
에서 최소한 하나는 소수로 작성해야 함.
ff = cc * (9.00 / 5.00) + 32;

국영수 값을 정수입력받고 평균을 00.00으로 나타내려면
평균을 구하는 공식 합계/과목수에서 둘 중하나는 00.00형태로 값을 주어야한다.
#include <stdio.h>
int main(){
    int k, e, m, sum;
    printf("국어 점수 입력 : ");
    scanf("%d", &k);
    printf("영어 점수 입력 : ");
    scanf("%d", &e);
    printf("수학 점수 입력 : ");
    scanf("%d", &m);
    sum = k+e+m;
    printf("합계 %d, 평균 %.2f입니다.", sum, sum/3.00);
    return 0;
}

만약 변수 자체를 실수로 만들려면 x.0방식말고 형변환 연산자를 사용하도록 한다.
printf("%f \n", (double)3/2); 이렇게도 가능

7/9*9 같은 경우 7/9가 0이므로 0으로 계산이 됨.
정수끼리 나누는 경우 나오는 값또한 정수로 나오기 때문.

연산자 우선순위
괄1산비논대
괄1산비논대
괄1산비논대
괄1산비논대
괄1산비논대

괄호
1항연산자 -> 피연산자 개수 1개. 단항 연산자. ++a 등
산술 연산자 -> 사칙연산등 -(부호: 음수를 양수, 양수를 음수로) * / % + - 순서
비교 연산자 -> >= != == 등 C언어에서는 True False없으므로 거짓 0 참 1
논리 연산자 -> !(참은 거짓, 거짓은 참으로) && || 순서. 논리연산 결과도 0, 1로 출력됨.
대입 연산자 -> 오른쪽에서 왼쪽

변수값이 변하는 연산은 대입연산자, 증감연산자 뿐임.

복합 대입 연산자 x+=y x%=y ...
만약 x*= y + 1 형태로 쓰는경우 x=x*(y+1)로 쓰는 것을 권장.

2항연산자의 결합방향은 왼쪽에서 오른쪽. 그러나 대입 연산자는 오른쪽에서 왼쪽.

res = num1++ && num2++;
여기서 num1++가 0이라면 num2++부분은 그냥 무시되어버림
0 && ...이므로 무조건 거짓으로 판정되어 뒤에 부분 연산이 씹힘.
int num1=0, num2=0, res;
res = num1++ && num2++;
printf("res, num1, num2출력"..);
res =0, num1 =1, num2 = 0이됨.



switch (변수) {
case 1: case 3: case 5:
...
break;
defalut:
...
break;
}
case 중첩이 가능하며, break가 없으면 다른 케이스(또는 defalut)의 코드까지 실행됨.



ufo 번갈아서 문제
#include <stdio.h>
#include <stdlib.h>
int main(){
    int k, sp;

    for (k = 0; k < 50; k++) {
        system("cls");
        if (k%2 == 0) printf("\n");  // 이거 없으면 그냥 한줄에서 수행
        for (sp = 0; sp < k; sp++) printf(" ");
        printf("<#=#>\n");
        system("timeout 1 > NULL");
        //system("timeout -1 > NULL")은 사람이 엔터를 칠때마다 다음 명령이 수행됨
    }
    // 예상문제, k가 3일때 공백은 몇 개? : 3개
    return 0;
}

float는 %f로 받고, double은 %lf 로 받는 것을 기억하기.
일반적으로 리터럴 실수 기본형은 double이므로
문제에서 별 조건이 없다면 double형으로 받는 것이 좋음.


자연어(고급언어) : 인간이 쓰는 언어
기계어(저급언어) : 기계가 이해하는 언어
컴파일 : 프로그래밍 언어를 기계어로 번역하는 과정
컴파일러 : 인간과 컴퓨터 사이의 통역가
데니스 리치 : C언어 창시자

프로그래밍 하는 이유
컴퓨터는 기계어만 이해할 수 있으나 인간은 기계어를 이해하기가 어렵기 때문에
중간에서 통역을 해주는 과정이 필요하기 때문.

고급언어 : 자연어에 가까운 언어, 고수준, CPU독립적
어셈블리언어 : CPU의존적
기계어 : CPU의존적
C언어는 저수준~고수준 프로그래밍 모두 가능.

통합 개발 환경 (IDE) : 에디터, 컴파일러, 디버거 기능이 결합됨.
vscode, 이클립스, 코드블록 등..
에디터 -> 소스(.c) -> 컴파일러 -> 오브젝트파일(obj) -> 링커 -> 실행파일(exe)
obj파일  = 컴파일된 결과파일
링크 : obj파일을 라이브러리와 연결해 exe (실행)프로그램을 생성
링커 : 링크를 수행하는 프로그램.

컴파일 : 사람이 이해하는 언어를 컴퓨터가 이해할 수 있는 언어로 바꿔주는 과정

오류 3가지
컴파일 오류 : 문법오류
런타임 오류(실행시간 오류) : 잘못된 메모리 주소에 접근. 0으로 나누기
논리 오류 : 문법 안틀렸고 결과도 나오지만 원하던 결과가 아닌 경우.
ex) 4/3 = 1.333333으로 출력안되고 1로 출력됨.


디버깅 : 소스에 존재하는 오류를 잡는것.


3항연산자 (조건) ? 참 : 거짓;
(num % 2 == 0) ? printf("짝수") : printf("홀수");
max = (num1 > num2) ? num1 : num2;
(num2 < 0) ? -num2 : num2;

C언어의 조건문 3가지는 ? if문 switch문 삼항연산자


별찍기 문제들
*
**
***
****
*****
#include <stdio.h>
int main(){
    for (int i = 1; i <= 5; i++){
        for (int j = 1; j <= i; j++){
            printf("*");
        }
        printf("\n");
    }
    return 0;
}
#include <stdio.h>
int main(){
    int i = 1, j = 1;
    while (i<=5){
        while (j<=i){
            printf("*");
            j++;
        }
        printf("\n");
        i++;
        j=1;
    }
    return 0;
}


*****
*****
*****
*****
*****
#include <stdio.h>
int main(){
    for (int i = 1; i <= 5; i++){
        for (int j = 1; j <= 5; j++){
            printf("*");
        }
        printf("\n");
    }
    return 0;
}

#include <stdio.h>
int main(){
    int i = 1, j = 1;
    while (i<=5){
        while (j<=5){
            printf("*");
            j++;
        }
        printf("\n");
        i++;
        j=1;
    }
    return 0;
}

728x90