- C언어

리문·2022년 4월 25일
0

C언어


식별자(Identifier)

  • 여러 요소를 구분짓는 이름,
  • 식별자의 이름에 문법에 들어가는 키워드는 불가능.
  • 유니코드, 라틴문자, 대,소문자, 숫자(숫자로 시작할 수 없음) 지원.
  • 구체적으로 적어야함 (모든 사람들이 알아볼 수 있도록)

선언(Declaration)

  • 선언을 통해 식별자에 의미와 속성을 지정.

정의(Definition)

  • 식별자에 대한 모든 정보를 제공하는 것.

할당(Assignment)

  • 메모리에 데이터를 저장하는 것.

초기화(Initialization)

  • 선언과 정의를 같이하는것

범위

  • 식별자가 유효한 공간.
  • 블록 범위* : 복합 구문 안 쪽(중괄호 안쪽)에서만 식별자를 볼 수 있음.
  • 파일 범위* : 파일 전체에서 식별자를 볼 수 있는 영역.
  • 함수 범위 : 함수 내 레이블이 갖는 영역
  • 함수 프로토타입 범위 : 함수 선언에서 매개변수 목록에 소개된 식별자의 영역.

이름 공간

  • C프로그램은 식별자에 카테고리를 지정하여 구분 가능.

    • 레이블 이름 공간
    • 태그 이름 공간
    • 멤버 이름 공간
    • 일반 이름 공간

    ex) using namespace std(standard);

연결(Linkage)

  • 서로다른 지점에서, 서로다른 객체, 같은 지점에서 서로 다른 이름 공간을 가질 때,
  • 같은 식별자를 사용 가능.

구문

  • 컴퓨터에게 명령을 내리는 것. 세미 콜론으로 구문을 구분.

    • 복합 구문(Compound Statement) : 블록. 중괄호로 묶인 구문과 선언의 시퀀스
    • 식 구문(Expression Statement) : 계산을 정하는 연산자와 피연산자의 시퀀스. 계산을 하는 것(평가)
      평가는 결과를 만들거나 사이드 이펙트를 생성하거나 변수나 함수를 지정할 수 있다.
      식 없이 쓰인 구문(NULL Statement)
    • 분기문(Selection Statement) : 식의 결과에 따라 몇 개의 구문 중 하나를 선택하게 하는 구문 (if / switch)
    • 반복문(Iteration Statement) : 특정 구문을 반복하는 구문 (for / while / do-while)
    • 점프문(Jump Statement) : 조건에 관계없이 흐름을 바꾸는 구문 (break / continue / goto)
  • 구문에 사용되는 여러 C언어의 요소는 식별자에 의해 구분된다.
    이렇게 작성한 구문은 main 함수에서 시작된다.

  • 선언을 제외하고 모든 구문은 레이블이 될 수 있음.

    주석

  • 사용자에게 정보를 제공하는 문서. 코드의 의미를 설명할 때 사용.
    Why? 왜 이 코드를 작성했는지 설명할 때.

    객체

  • C프로그램에서 메모리, 데이터를 조작하는 영역. 객체는 선언을 통해 생성.

    • 크기(Size) : 데이터를 저장하기 위한 바이트의 개수
    • 정렬 요건(Alignment Requirement) : 데이터를 저장하기 위해 필요한 연속적인 바이트 개수
    • 기억 존속 시간(Storage Duration) : 데이터를 얼마나 오래 가질 수 있는 지.
    • 수명(Lifetime) : 객체가 유효한 시간을 의미. (= 기억 존속 시간)
    • 타입(Type) : 데이터 해석 방법.
    • 값(Value) : 데이터 자체.
    • 식별자(Identifier) : 객체의 이름. 생략될 수도 있다(무명 객체)

타입

  • 객체에 저장된 이진수나 식에서 평가된 이진수의 해석.

    • 정수(Integer) : 정수에는 signed char, short, int, long, long long이 있다.
      위의 타입들은 부호를 가지고 있으며, MSB를 부호비트로 사용해 0이면 양수, 1이면 음수로 취급. 부호를 사용하고 싶지 않다면 unsigned를 사용.
      - MSB(Most Significant Bit) : 이진수에서 가장 큰 비트.

    • 실수(Floating-point) : 실수 표현을 위해 부동 소수점으로 표현하고 IEEE - 754 포맷을 사용.
      float타입을 많이 사용. float, double, long double
      - float : 유효숫자 6자리
      - 유효 숫자 : 어떤 측정값이 있을때 그 측정값의 정확도에 영향을 주는 숫자.
      - IEEE - 754 : 비트를 부호, 지수, 정규화된 가수 부분으로 나눠 표현하는 방식.

    • 문자(Character) : char타입을 사용, 아스키코드로 해석.

      • 아스키코드 : 이진수 값에 각 문자,제어 문자를 대입시켜 놓은 코드
  • 반드시 초기화를 하는 습관을 들이자.(초기화를 하지 않아, 오류가 나는 경우가 많음.)

    변수(Variable)

  • 여러 데이터를 담을 수 있는 객체. 상수나 리터럴, 혹은 식의 결과값을 넣어준다.
    ex) int 타입의 number 객체를 정의하고, 10으로 초기값을 지정.

    • 상수를 사용했다.

      int number = 10;
      - 실행 중간에 값을 바꿀 수도 있다.
      number = 20;

    • 다른 객체의 값을 가져올 수도 있다.

      int number2 = number;

    • 정수 상수는 아래 4가지 표현으로 작성할 수 있다.

      number = 42; // 10진수
      number = 052; // 8진수
      number = 0x2a; // 16진수
      number = 0X2a; // 16진수

    • 정수 상수의 타입은 아래와 같다.

      number2 = 42; // int
      number2 = 42U; // unsigned int
      number2 = 42L; // long
      number2 = 42UL; // unsigned long
      number2 = 42LL; // long long
      number2 = 42ULL; // unsigned long long

    • 부동 소수점 상수는 2가지 표현으로 작성할 수 있다.

      double realNumber = 1.2;
      realNumber = 1.2e3; // 지수 표현법으로 1.2 * 10^3이다.
      - 부동 소수점 상수의 타입은 아래와 같다.
      realNumber = 1.2; // double
      realNumber = 1.2f; // float
      realNumber = 1.2L; // long double
      - 문자 상수는 ''으로 표현한다.
      char ch = 'a';

  • 리터럴 : 문자 그대로의.
    printf( ); scanf( );

    • "%c" : 단일 문자
    • "%s" : 문자열
    • "%d" : 상수
    • "%f" : 부동 소수점
  • 타입에 따라 읽어들일 수 있는 비트의 수가 다르기 때문에, 타입을 잘 알아야함.

  • 입력 형식을 잘 맞춰주지 않으면 쓰레기값으로 출력이 제대로 되지 않을 수 있다.

  • flags

    • leading zero : 정수의 앞의 자리수를 표현. ex) 04 ; 오른쪽정렬, - 붙이면 왼쪽 정렬.
    • . : 소수점 개수를 정할 수 있다. ex) .3 ;
  • ASCII : graphical , Non - graphical

    • 이스케이프 시퀀스(Escape Sequence)
      • \n : 개행문자(Line Feed)
      • \t : 탭(Horizontal Tap)
  • & : 데이터 주소를 알아야 할 때. (address)

  • 오류의 종류
    • 컴파일 오류(Compile Error) : 문법을 잘못 쓴 것.
    • 링크 오류(Link Error) : 연결을 잘못 한 것.
      • 함수를 선언만 하고 정의하지 않음
    • 런타임 오류(Runtime Error) : 잘못된 데이터 주소로 진입.

변환(Conversion)

  • 데이터를 다른 타입으로 해석 하는 것. ex) 정수형 데이터를 가지고 실수를 얻어내야 할 때.

    • 암시적 변환(Implicit) : 피 연산자의 타입이 연산자의 결과 타입과 매치되지 않을 때.
      데이터를 보존할 수 있는 쪽으로 변환이 일어남.

      • 정수끼리는 크기가 큰 쪽으로 변환되며, 크기가 같을 경우 unsigned로 변환된다. -> 정수 승격(Integer Promotion)
      • 실수가 있다면 실수 타입으로 변환. 실수도 크기가 큰 쪽으로 변환.
    • 명시적 변환(Explicit) : 데이터 손실이 일어날 수 있다. (캐스팅 Casting)

  • 상수(Constant) : 데이터가 변하지 않는 객체.

    • const : 데이터를 변경할 수 없는 객체(상수), 상수에 새로운 데이터를 할당하려고 하면 컴파일오류.

분기문

  • 프로그램에게 여러 흐름을 제공하는 구문.
    • if : 식의 결과가 0과 같지 않을 때 참.
    • switch
      • 예외 처리
        • 위 case와 매칭되지 않는 값을 처리 할 때.
        • 절대 들어와서는 안되는 값이 들어올 때.

반복문

  • while : 반복 횟수를 파악할 수 없을 때 유용.

  • do-while : 맨 뒤에 세미콜론이 붙음에 주의. 평가를 나중에 해야할 때 용이.

  • for : 유효한 반복 횟수가 있을 때 유용.
    for (init-clause; cond-expression; iteration-expression)

    - EOF(End Of File) : 파일의 끝.

점프문

  • break

  • continue

    배열 : 같은 타입으로 된 여러 개의 객체를 한 번에 다루고자 할 때 사용.

    const 사용 불가능
    index가 0부터 시작함.

    문자열

  • char 타입의 배열. 문자열의 끝은 널 문자로 판단함.

    • Buffer Overrun : 문자열의 인덱스 수를 넘으면 런타임.(저장공간을 넘어서 저장했기 때문.)
    • scanf("%9s", str); 식으로 저장할 글자의 수를 적어주면 그만큼만 저장하기 때문에 오버런 X. 입력 받을 때, &(주소연산자)를 사용하지 않음.
      -> 포인터 타입 (메모리 주소값으로 해석하는 타입)으로 암시적 변환 가능 (포인터로 퇴행(decay)), fgets(문자열 이름, 문자열길이, stdin);
  • <ctype.h> : 알파벳 체커.

  • <stdlib.h> : string을 다른 타입으로 바꿔줌

  • <string.h> : string 조작

    • strcpy : string을 카피함. strcpy(Destination, src);
      -> src가 null 문자여야함. 배열의 크기가 충분해야함.
    • strlen : string의 길이를 구해줌. (NULL문자 제외.)
    • strcmp : 사전순으로 더 빠른 순. 보통 두 문자열이 같은 지 확인할 때 사용.

    포인터

  • 데이터를 메모리 주소값으로 해석.

    • Type Identifier;
      ex) int num = 10;
      int
      p = # pointer to int
      *p = 20;
  • 메모리에 접근 하는 방법

    • 직접 참조(Direct Reference / Direct Access) : 메모리 주소에 직접 접근하는 것.
      ex> num = 20;
    • 간접 참조(Indirect Reference / Indirect Access) : 메모리 주소를 포인터를 통해서 접근하는 것.
      ex> *p = 20; =>
      • Scope : 프로그램이 식별자를 찾을 수 있는 영역.
      • Block Scope : 중괄호(블록) 안에서만 찾을 수 있음.
        => Local Variable
      • File Scope : 파일 내에서만 찾을 수 있음.
        => Global Variable
  • Pointer Type의 크기 - x86 = 4Byte, x64 = 8Byte.
    쓸 수 있는 연산자 : +, -;

    • 주소 연산(Address Operation) : + 만큼 뒤로, - 만큼 앞으로

      • 주의 : 역참조 연산자와 증감 연산자를 결합할 때 연산
        - pointer -> 데이터의 주소값으로 데이터를 해석.
    • pointer to int -> int의 크기만큼 주소연산.

    • *P++ => 역참조한 후, 주소연산.

    • *++P => 주소연산 후, 역참조.

      • void* : 메모리 주소값 그 자체로 취급. 타입을 모르기 떄문에 어떤 연산도 불가능.
    • 패딩 : 멤버의 정렬요건 중 가장 큰 값으로 맞춤. 패딩을 줄이려면 크기가 작은 것부터 큰 순서대로, 혹은 큰 것부터 작은 순서대로 정렬, 가장 최소한의 패딩바이트를 얻음.

표준 라이브러리

  • <assert.h> : 반정문. 입력이 조건에 맞는 지 확인해줌. 디버그 모드에서만 동작한다. 조건에 맞지 않는 코드가 존재하지 않아야 할 때 사용.

  • <ctype.h> : 캐릭터 타입에 관련된 라이브러리.

  • <float.h> : 부동소수점의 한계를 정리한 라이브러리.

  • <limits.h> : 정수의 한계를 정리한 라이브러리.

  • <math.h> : 다양한 수학적인 계산을 지원하는 라이브러리.

  • <stdarg.h> : 가변인수를 만드는 라이브러리.

  • <stdbool.h> : 불리언 함수. 불리언 타입으로 참과 거짓을 표현할 수 있음.

  • <stddef.h> : 데이터타입의 값을 표준으로 정해주는 라이브러리.

  • <stdint.h> : 정수의 크리를 정하는 타입 지원 라이브러리.

  • <string.h> : 문자열 사용 관련 라이브러리.

  • <time.h> : C의 날짜 시간 관련 라이브러리.

  • <stdlib.h> : 여러가지 도구를 사용하게 하는 표준 라이브러리.

파일

1.파일을 다루기 위한 객체 생성

2.파일을 연다.
1) 텍스트 파일 : 텍스트 에디터로 열 수 있는 파일.
2) 바이너리 파일 : 그 외 모든 타입의 파일.

  1. 파일을 조작한다.

    fputs() / fputc( ) / fprintf() -> 텍스트 파일에 작성할 수 있는 함수.
    fwrite() -> 바이너리 파일에 작성할 수 있는 함수.

    fgets() / fgetc( ) / fscanf() -> 텍스트 파일에 읽어들일 수 있는 함수.
    fread() -> 바이너리 파일에 읽어들일 수 있는 함수.

  2. 파일을 닫는다.

스택 프레임과 호출 규약.

  • Heap : 동적 할당 영역 -> malloc()

  • Stack : 정적 할당 영역 -> 함수, 이미 얼마나 메모리를 사용해야 할 지 알고 있다.

  • 스택 프레임 : 함수와 관련된 데이터. 임시 데이터, 매개 변수, 반환 주소로 구성되어 있음.

  • 호출 규약 (x86 Achitecture)

    cdecl : C의 기본 호출 규약. 오른쪽에서 왼쪽으로 인자를 스택에 넣음. 호출자가 스택 정리를 하기에 가변인자 사용 가능, stdcall보다 실행 파일의 크기가 큼.

    __stdcall : Win32 API함수에서 사용. 오른쪽에서 왼쪽. 피호출된 함수가 스택 정리 하기에 가변인자 사용 불가능.

    __fastcall : 첫 2개의 인자 까지는 순서대로 ECX와 EDX 레지스터에 저장. 나머지 인자는 오른쪽에서 왼쪽으로 스택에 넣음. 피호출된 함수가 스택 정리.

profile
개발자되기 대작전

0개의 댓글