본문 바로가기
Study/정보처리기사(정처기)

깨알 C언어 특강(Feat.유튜브 흥달쌤) 정리

by 얏옹이 2023. 7. 26.
반응형
  • 컴파일이란?
    • 개발자가 작성한 프로그래밍 언어로 작성돈 코드를 컴퓨터가 이해하고 실행할수 있는 기계어로 변환하는과정
  • C언어 컴파일 과정
    • 개발자가 작성한 소스코드 - 전처리기 - 컴파일러 - 어셈블러 - 링커
      • 전처리기 - 전처리 구문을 처리하는 과정
      • 컴파일러 - 고수준 언어를 저수준 언어로 변환, 기계어와 가장 가까운 형태의 언어로 변환
      • 어셈블러 - 완전히 기계어로 바꾸어주는 역활
      • 링커 - 여러개의 오브젝트 파일을 합치거나 라이브러리를 합치는 역활
  • 인터프린터란?
    • 고급 언어로 작성된 프로그램을 한줄씩 읽어들여서 실행하는 프로그램
    • 번역과 실행이 동시에 이루어지므로, 별도의 실행파일이 존재하지 않는다. 
  • 변수란?
    • 데이터를 저장할수 있는 메모리의 기억 공간
  • 변수 생명 규칙 및 특징
    • 예약어(키워드)는 사용불가
    • 공백을 포함 불가
    • 첫글자는 영문과 언더바( _ )만 사용 가능
    • 언더바 이외의 특수문자 사용 불가
    • 대소문자 구별
  • 변수의 종류와 유효범위
    • 지역변수 : 함수/블록 안에서 선언하는 변수, 함수 / 블록의 종료와함께 소멸
    • 전역변수 : 함스 블록 밖에서 선언하며 전체 함수에 영향을 미친다, 프로그램이 종료시 메모리에서 소멸, 초기값을 주지 않으면 기본 초기값어 대입된다.
    • 정적변수 : static으로 선언하며 선언한 블록 내에서만 사용가능, 함수가 종료되어도 소멸되지않고 값 유지, 프로그램이 종료될때 메모리에서 소멸, 초기화는 한번만 가능
    • 동적변수 : 메모리 동적 할당으로 생성되는 변수, 런타임 시간에 메모리를 할당, 무조건 포인터를 사용해야함
반응형
  • 산술연산자 종류
    • 이항 연산자 : +, -, *, /, %
    • 단항 연산자 : ++, --
    • 대입연산자 : =, +=, -=, *=, /=, %=
  •  연산자 우선순위
    • 1. 괄호 : ()
    • 2. 단항 : ++, --, ~, !
      • 단항 연산자는 연산자가 어디에 위치해있느냐에 따라 주의가 필요하다
      • ++a; 처럼 앞에 붙어있으면 즉시 1 증가 시킨다. 뒤에 a++;로 붙어있으면 다른식을 먼저 수행 후에 1 증가 시킨다.
    • 3. 산술 : *. /, %
    • 4. 산술 : +, -
    • 5. 비트 : << , >>
    • 6. 비교 : <, <=, >, >=
    • 7. 관계 : ==, !=
    • 8. 비트 : &, ^, |
    • 9. 논리 : && , ||
    • 10. 대입 ; =, +=, -=, *=, /=, &=
  • 관계 연산자
    • ==
    • !=
    • >
    • >=
    • <
    • <=
  • 논리 연산자
    • !
    • &&
    • ||
  • 조건문
    • 단순 if문 : if(조건식)이 참(true)일 경우에 코드를 수행
    • if~else문 : 조건식이 참일경우 true 구문의 코드를 수행, false일경우 else 코드를 수행
    • 다중 if 문 : 조건이 여러개인경우 다중 if ( if~ else if ~ else )를 사용 조건1이 참일경우 if문만 수행, 조건2가 참일경우 else if만 수행, 조건1, 2 둘다 참이 아닐경우 else 구문을 수행
  • 출력 형식
    • %d : 부호 있는 10진수 출력
    • %f : 고정 소수점 출력
    • %c : 문자 출력(1글자)
    • %s : 문자열 출력
    • %x : 16진수 출력
    • %o : 8진수 출력
  • 진법 변환
    • 10진수 -> 2진수
      • 19라는 10진수를 2진수로 변환할때는 나눠지지않을때까지 2로 나눈다.
        • 따라서 10진수 19는 2진수 10011
      • 다른방법으로는 32 16 8 4 2 1 순으로 2씩 곱한수를 거꾸로한후 합쳐서 19가 되는수를 찾는다
        • 여기서 16, 그리고 1, 2 이렇게 3수를 더하면 19 그러면 1 과 2 그리고 16에 1씩 붙여주고 나머지에는 0을 붙인다. 그럼 1 0 0 1 1이 된다.
    • 2진수 -> 8진수
      • 8진수는 한자리가 0~7까지만 표현된다.
        • 2진수 1 0 0 1 1 을 8진수로 변환하면 3자리씩 자른다. 왜 3자리나면 잘랐을때 1 2 4 까지만 표현 가능하기때문. 8 이상은 표현이 불가능하기 때문. 그럼 10 / 011 이기때문에 1이 들어간 숫자만 더해준다. 따라서 2 3이 된다. 숫자 23이 아니다.
    • 2진수 -> 16진수
      • 8진수 계산법에서 3자리씩 끊는게 아니고 4자리씩 끊으면 된다. 계산하면 1 3 이 된다.
  • 비트연산자
    • 비트연산자 종류
      • & : 비트 논리곱 ( AND ) 둘다 참이여야 참
      • | : 비트 논리합 ( OR ) 둘중에 하나만 참이여도 참
      • ^ : 비트 배타적 논리합(XOR) 둘이 달라야 참
      • ~ : 비트 NOT
      • >> : 비트값을 우측으로 이동
      • << : 비트값을 좌측으로 이동
  • 매크로
    • 반복적인 일들을 쉽게 하기 위해서 만들어 놓은것
    • #define으로 정의(전처리기)
  • 삼항연산자
    • 조건에 따라서 다른 명령을 수행하는 연산자
    • 구조 = 조건 ? 참 : 거짓
  • 제어문(if, switch문)
    • if문 : 조건에 따라서 다른 명령어들을 수행
    • switch문 : 주어진 값에 맞는 명령어들을 수행 break의 위치에 따라서 전혀 다른 결과값이 나올수도 있으니 주의하자.
  • 반복문(for문, while문, do-while문)
    • for문 - 정해진 횟수만큼 반복
    • while문 - 조건이 만족하는 동안 반복
    • do-while문 - 무조건 한번 수행후 조건이 만족하는 동안 반복
  • 반복문 옵션 Continue, break
    • Continue - 더이상 아래 문장을 실행하지않고 반복문 처음으로 돌아간다
    • break - 반복문을 빠져나감
  • 배열
    • 같은 자료형의 변수를 연속적으로 묶어놓은 저장공간
    • int a[5] = int : 자료형 a: 배열명 [5] : 배열의 공간
  • 이차원 배열
    • 같은 자료형의 변수를 행과 열의 연속적인 공간으로 묶어놓은것
    • int a[2][3] = 2행 3열짜리 a라는 배열명을 가진 배열을 만든다.
  • 포인터
    • 주소값(메모리의 위치)을 가지고 있는 변수
    • 포인터 변수 선언 방법 : int *a; 변수명 앞에 *을 붙여준다.
    • &기호를 사용하면 해당 변수의 주소값을 가리키는 말이다.
    • 선언할때 *a를 사용하여 선언하고 그 이후에 사용하는 *a는 a가 가리키는 주소에 담긴 값을 의미한다.
#include <stdio.h>

void main() {
	int b = 10;
	int *a;
	
	a = &b;
	printf("%d\n", *a);
	printf("%d\n", b);
}

 

이 코드를 보자. 정수형 b라는 변수에 10이라는 값을 대입하고. a라는 이름의 포인터 변수를 선언하였다.

그리고 a에 변수 b의 주소값을 대입하였다.

 

따라서 포인터변수 a와 b는 둘다 10이라는 값을 가리키고 있고. 주소값도 동일하다.

따라서 포인터변수의 값(*a)를 출력해도 10, b라는 변수를 출력해도 10이라고 출력된다.

 

  • scanf
    • scanf란? 사용자의 키보드로 입력받을때 사용하는 함수
      • 형식) scanf("%d", 변수의주소);
      • scanf("%d", &a);
  • 배열과 포인터
#include <stdio.h>

int main(void) {
    int i;
    int a[] = {10,20,30,40,50,60,70,80,90,100};
    int *ptr = a+3;
    for(int i=0; i<5; ++i) {
        printf("%d", *(ptr+i)-3);
    }
}

 

a라는 배열에 저렇게 10부터 100까지의 값을 담아서 초기화를 하고

ptr이라는 포인터 변수에 a+3의 주소값을 담는다, 여기서 주소값을 100이라고 가정하면

포인터 변수에 배열을 접목시키면 100번지가 a[0]이 된다. 따라서 a+3은 103번지고 a[3]인 40을 의미한다.

 

그럼 ptr이라는 103번지를 가리키고 있고 103번지의 값은 즉 40인 셈이다.

 

해당 반복문을 수행해보면 각각의 103, 104, 105, 106, 107(0부터 5까지기때문에 총 5번 반복)의 값에서 각각 3을 뺀 수를 출력하게 된다. 

따라서 결과값은 37 47 57 67 77이 된다.

 

포인터변수에 배열의 주소값이 들어가면 배열과 마찬가지로 [index]도 사용가능하다.

 

#include <stdio.h>

int main(void) {
    int a[] = {1,2,4,8};
    int *p = a;
    p[1] = 3;
    a[1] = 4;
    p[2] = 5;
    printf("%d %d\n",a[1]+p[1], a[2]+p[2]);
    return 0;
}

 

이 문제를 보자. a라는 배열변수에 1,2,4,8이라는 값으로 초기화를 해줬고 *p의 a배열변수의 주소값을 대입했다.

 

그리고 p[1] 이라고 하면 그건 즉 a[1]이랑 같은셈이다. 위의 배열변수에서 a[1]은 2이다. 즉 2라는 칸 안에 3을 대입시켰고

동일하게 a[1]에 4를 대입시켰다. 따라서 배열은 {1,4,4,8} 이 되었다.

그리고 나서 p[2]에 5를 대입했다. 따라서 {1,4,5,8}이 되었다.

 

이제 더해주면 a[1]과 p[1]은 서로 같은 값을 가리키고 있기때문에 4+4인거고 a[2]와 p[2]도 5+5가 된다.

정답은 8 10이 된다.

 

다음문제

 

#include <stdio.h>

int main() {
    int num[4] = {1,2,3,4};
    int *pt = num;
    pt++;
    *pt++ = 5;
    *pt++ = 10;
    pt--;
    *pt++ += 20;
    printf("%d %d %d %d", num[0],num[1],num[2],num[3]);
}

 

pt라는 포인터 변수에 num 배열변수의 주소값을 대입, 그리고 pt를 1 증가

그럼 100번지라는 가정하에 101번지가 되며 배열의 2값을 가리키게 된다. 이제 ++과 --의 향연인데... 이건 글로 적기가 좀 애매하다.. 먼저 값을 대입시키고 pt를 1증가, 또다시 값을 먼저 대입시키고 pt를 1증가.

그리고 pt를 1 감소, 다시 pt의 값에 20을 누적해서 더한후 1증가.... 라고 설명해야하나...

 

결과값은 {1,5,30,4} 이다

 

  • 포인터 배열
    • 배열의 요소가 포인터(메모리 주소)로 이루어진것
    • char *student[3] = {"aaa","bbb","ccc"}; 이런식으로 배열선언시에 포인터 선언을 함께 하면 포인터 배열이다

 

 

 

반응형