__________

Designing the Future with Circuits

반도체 회로설계 취준기

하만(Harman) 세미콘 반도체 설계 과정/임베디드 시스템을 위한 SW 구조설계

하만(Harman) 세미콘 아카데미 3일차 - SW 구조설계(반복문 / 조건문 / 배열)

semicon_circuitdesigner 2024. 3. 11. 12:44

[2024.03.11.월] 인천인력개발원 하만 세미콘 아카데미


임베디드 시스템을 위한 SW 구조설계



변수와 연산자


  • 대입 연산자: =, +, -, *, /, %
    • 축약형태
       - a = a + b; => a += b;
       - a = a - b; => a -= b;
       - a  = a * b; => a *= b;
       - a  = a / b; => a /= b;
       - a  = a % b; => a %= b; 
  • 증감 연산자
    • ++a : 선 증가, 후 연산
    • a++ : 선 연산, 후 증가
    • --b : 선 감소, 후 연산
    • b-- : 선 연산, 후 감소
    • [example]
      int a = 10;
      printf("%d", ++a); //=> 11출력
      int b = 10;
      printf("%d", b--); //=> 10출력 후 b 값 9로 변경​
  • 관계 연산자(비교 연산자)
    • 두 피연산자의 관계 비교
    • true(1), false(0) 반환
    • <. >, ==(같다), !=(같지 않다), <=, >=
    • 관계 연산자 왼쪽 피연산자가 기준이 됨
    • [example]
      1 < 3 => 결과값 1,
      1 == 3 => 결과값 0
  • 논리 연산자
    • and, or, not 표현
    • true(1), false(0) 반환
       - &&: 피연산자가 모두 true면 true 반환 (AND) [ex) a&&b]
       - ||: 피연산자 하나라도 true면 true 반환 (OR) [ex) a||b]
       - !:  true면 false를, false면 true를 반환 (NOT) [ex) !a]
    • C언어에서는 0이 아니면 true로 간주
  • 비트 단위 연산자: ~(NOT), &(AND), |(OR), ^(XOR), <<, >>
    • [example]
      a: 1010(2)
      b: 0101(2)인 데이터에 대하여
      a&b => 각각의 비트(같은 자릿수)가 연산 대상 => 결과: 0000(2)
      a|b => 결과: 1111(2) = 15(10)
      ~a => 결과: 0101(2) = b
    • <<, >> : shift연산자(비트를 이동시키는 연산자)
       - 새로 생긴 자리는 0, 넘어간 비트는 삭제
    • XOR examples
       - 1^1 = 0
       - 0^1 = 1
       - 1^0 = 1
       - 0^0 = 0
  • 콤마(,) 연산자
    • 둘 이상의 변수 동시 선언 시
    • 둘 이상의 문장을 한 줄에 선언 시
    • 함수의 매개변수 전달 시
  • 연산자의 우선 순위(괄호를 이용하여 명시적으로 구분하기)
    ① *, /
    ② +, -

데이터 표현 방식


  • 진법에 대한 이해
    • 2진수 표현 범위: 0~1
    • 8진수 표현 범위: 0~7
    • 10진수 표현 범위: 0~9
    • 16진수 표현 범위: 0~9+A~F (FF(16)=255(10))
  • 데이트 표현 단위 비트(bit), 바이트(byte)
    • 비트 : 데이터 표현 최소 단위. 0 or 1 저장
    • 바이트 = 8비트
  • 정수 표현 방식
    • MSB(Most Significant Bit): 가장 왼쪽 비트. 부호 표현
    • LSB(Least Significant Bit): 가장 오른쪽 비트
    • MSB 제외 나머지 비트: 데이터의 크기 표현
    • 00000001 => 맨 앞 0은 부호(+/-) 표현
  • shift(<<, >>) 연산자
    • a<<b: a의 비트들을 b칸씩 오른쪽으로 이동한 값 반환
    • 8>>2: 8의 비트를 왼쪽으로 2칸씩 이동한 값 반환

상수와 기본 자료형


  • 자료형: 선언할 변수의 특징을 나타내는 키워드
  • 기본 자료형: 기본 제공 자료형
    • 정수형 종류: 표현 가능 데이터 범위
       - char(1byte): -128 ~ +127
       - short(2byte): -32768~ +32767 
       - int(4byte): -2147483648 ~ +217483647
       - long(4byte): -2147483648 ~ +217483647
    • 실수형 종류: 표현 가능 데이터 범위
       - float(4byte): 3.4*10^(-37) ~ 3.4*10^(+38)
       - double(8byte): 1.7*10^(-307) ~ 1.7*10^(+308)
       - log double(8byte~)
  • 자료형 선택 기준
    • 정수는 int
    • 실수형 데이터(정밀도 기준)
       - 정밀도: 오차 없이 표현 가능한 정도
       - float: 소수 이하 6자리
       - double: 소수 이하 15자리
       - long double: double의 정밀도 이상
  • ASCII 코드
    • 미국 표준협회(ANSI)에서 정의
    • 컴퓨터에서 문자를 표현하기 위한 표준
    • 문자-숫자 연결관계 정의
      ASCII 코드
    • ASCII 코드 범위 : 0~127 char형 변수로 처리 가능
    • 문자는 따옴표(' ')로 표현
  •  리터럴(literal) 상수: 이름이 없는 상수(30, 40과 같은 값)
    • 상수가 메모리 공간에 저장되기 위해 자료형 결정(컴파일러가 자동으로 변수 자료형도 결정)
       - char c = 'A'; => 문자상수(char)
       - int i = 5; => 정수상수(int)
       - double d = 3.15; => 실수상수(double)
  • 접미사에 따른 상수 표현( 접미사 | 자료형 | 예시 )_error 발생 전까지는 굳이 사용 x
    • u or U | unsigned int | 304U
    • l or L | long | 304L
    • ul or UL | unsinged long | 304UL
    • f or F | float | 3.15F
    • l or L | long double | 3.15L
  • 심볼릭 상수
    • const키워드를 통해 변수를 상수화
    • [example]
      #include <stdio.h>
      
      int main(void)
      {
      	const int MAX=100;
      	const double PI=3.1415;
      }​
       이 경우는 선언과 동시에 초기화 필수
  • 자료형 변환
    • 자동 형 변환: 다른 자료형의 변수(int a)를 다른 변수(float b)에 대입할 때 발생
       [example1: 대입 연산 시]
      #include <stdio.h>
      
      int main(void)
      {
      	int n=5.25; //소수부 손실
      	double d=3; //값의 표현이 넓어짐
      	char c=129; //상위 비트 손실
      }​

      [example2: 정수의 승격에 의해]
      #include <stdio.h>
      
      int main(void)
      {
      	char c1=10, c2=20;
          char c3=c1+c2;
          //...
      }​​​
    • 강제 형 변환: 프로그래머가 명시적으로 요청하는 형 변환
       - cast연산자 사용
      #include <stdio.h>
      
      int main(void)
      {
      	float f=(float)3.14;  //3.14를 float형으로 형 변환
      	double e1 = 3 + 3.14;  //정수 3이 double형으로 자동 형 변환
      	double e2 = 3 + (int)3.14;  //3.14가 int형으로 강제 형 변환​
      }​​

반복문


  • 세가지 반복문
    • while 반복문
    • do~while 반복문
    • for 반복문
  • while 반복문
    while( 반복조건 )
    {
    	반복 내용
    }​

     - "반복 조건"이 만족되는 동안 "반복 내용" 반복 실행
    [example]
    while( i<10 ) { 
    	printf("Hello World! \n"); i++; 
    }​​​​​
    : i<10이 만족되는 동안 printf()와 i++을 반복 실행- 무한 루프에 빠지지 않도록 탈출조건 설정!!
    • while문에서 중괄호: 반복 영역이 둘 이상의 문장일 경우 필수
    • 무한루프: 반복 조건으로 true(0이 아닌 정수)일 경우 발생, 탈출조건 x
      while(1){
      	printf("Hellow World!\n");
          i++;
      }​
  • do~while과 while의 차이: do~while은 한 번 실행한 뒤 조건 검사/ while은 실행 전 조건 검사
  • for 반복문: 초기문, 조건문, 증감문을 모두 포함
    for(초기문; 조건문; 증감문)
    {
    	반복내용
    }​
  • for문 vs while문
    [for문 예시]
    int i;
    
    for(i=0; i<10; i++){
    	printf("Hello World!\n");
    }​

    [while문 예시]
    int i;
    i=0;
    
    while(i<10){
    	printf("Hello World!\n");
        	i++;
    }​

조건문


  1. if 조건문
    if (실행 조건)
    {
    	실행 내용
    }​

    • if~else 조건문
      if (실행 조건)
      {
      	조건 만족 시 실행
      }​​
      else
      {
      	조건 불만족 시 실행
      }
    • if, else if, else
      if(조건 A)
      {
      	조건 A 만족 시 실행
      }
      else if(조건 B)
      {
      	조건 A 불만족, B 만족 시 실행
      }
      else if(조건 C)
      {
      	조건 A 불만족, B 불만족, C 만족 시 실행
      }
      else
      {
      	조건 A, B, C 모두 불만족 시 실행
      }
      => 실행 시간이 오래걸려 좋은 방법 X
  2. switch문(분기의 수가 많아지면 가급적 switch 사용)
    switch (n)
    {
    	case 1:
        	n이 1인 경우 실행 영역
            break;
    	case 2:
        	n이 2인 경우 실행 영역
            break;
        case 3:
        	n이 3인 경우 실행 영역
            break;
    	default:
        	해당 case 없을 시 실행
    }​
     
    • switch문에서는 조건식에 비교 연산 불가능
  3. 삼항 연산자(조건 연산자)
    • if~else 문을 간결히 표현하는 데 사용 가능
    • 조건 ? A : B; //조건을 만족하면 A 실행, 불만족하면 B 실행
  • break: 반복문을 빠져나올 때 사용(반복문의 종료 지점 다음 줄의 코드 실행)
  • continue: 다음 번 반복으로 넘어갈 때 사용(반복문의 조건식으로 돌아감)
  • goto label
    • 이동할 위치 표시를 위한 레이블(label:) 선언
    • go to lable; => 레이블 위치로 실행 위치 이동
    • 프로그램의 흐름이 복잡해지므로 사용 지양

조건문 실습


 
실습 주제: if문을 이용하여 숫자키를 누르면 해당 영어단어를 출력하는 프로그램 작성
scanf: 한 값을 입력할 때 마다 엔터키를 눌러야 입력 완료
=> 키 하나만 입력받는 함수: getch(키 값을 출력하지 않고 반환)

  1. if조건문을 이용하여 1 입력 시 One을 출력하는 프로그램
    #include <stdio.h>
    #include <conio.h>
    
    int main(void) {
    
    	printf("숫자키를 입력하면 해당 영단어를 표시합니다.\n");
    	printf(">");
    
    	char c = _getch();
        
        if(c=='1'){
        	printf("One\n");
        }
    }​

    '1' 입력 시 'One' 출력하는 코드 작성
    실행 결과
  2. Select~Case를 이용하여 숫자 입력 시 영단어를 출력하는 프로그램
    #include <stdio.h>
    #include <conio.h>
    
    int main(void) {
    
    	while (1) {
    		printf("숫자키를 입력하면 해당 영단어를 표시합니다.(x는 종료)\n");
    		printf(">");
    
    		char c = _getch();
    
    		printf("%c\n", c);
    
    		if (c == 'x') break;
    
    		switch (c) {
    			case '1':
    				printf("One\n");
    				break;
    			case '2':
    				printf("Two\n");
    				break;
    			case '3':
    				printf("Three\n");
    				break;
    			case '4':
    				printf("Four\n");
    				break;
    			case '5':
    				printf("Five\n");
    				break;
    			case '6':
    				printf("Six\n");
    				break;
    			case '7':
    				printf("Seven\n");
    				break;
    			case '8':
    				printf("Eight\n");
    				break;
    			case '9':
    				printf("Nine\n");
    				break;
    			case '0':
    				printf("Zero\n");
    				break;
    		}
    		printf("\n");
    	}
    }​


    각 숫자 입력값에 맞는 단어 표시 및 x 입력 시 종료
  3. Select~Case를 이용하여 숫자 입력 시 영단어를 출력하는 프로그램+이외 글자 입력 시 에러 표시
    #include <stdio.h>
    #include <conio.h>
    
    int main(void) {
    
    	printf("숫자키를 입력하면 해당 영단어를 표시합니다.(x는 종료)\n");
    	while (1) {
    		printf(">");
    
    		char c = getch();
    
    		printf("%c\n", c);
    
    		if (c == 'x' || c == 'X') break;
    
    		switch (c) {
    			case '1':
    				printf("One\n");
    				break;
    			case '2':
    				printf("Two\n");
    				break;
    			case '3':
    				printf("Three\n");
    				break;
    			case '4':
    				printf("Four\n");
    				break;
    			case '5':
    				printf("Five\n");
    				break;
    			case '6':
    				printf("Six\n");
    				break;
    			case '7':
    				printf("Seven\n");
    				break;
    			case '8':
    				printf("Eight\n");
    				break;
    			case '9':
    				printf("Nine\n");
    				break;
    			case '0':
    				printf("Zero\n");
    				break;
    			default:
    				printf("숫자가 아닙니다.\n");
    				break;
    		}
    
    		printf("\n");
    	}
    }
    종료 조건문에 x | 0x20 == 'x'를 입력하면 입력 값을 소문자로 변환하여 종료 진행
    숫자와 x 이외의 문자 입력 시 오류 표시

    #include <stdio.h>
    #include <conio.h>
    
    int main(void) {
    
    	printf("숫자키를 입력하면 해당 영단어를 표시합니다.(x는 종료)\n");
    	while (1) {
    		printf(">");
    
    		char c = getch();
    
    		printf("%c\n", c);
    
    		if (c == 'x' || c == 'X') break;//c | 0x20 == 'x'로 조건 넣어도 작동. c | 0x20을 통해 입력 값을 소문자로 변환
    
    		switch (c) {
    		case '1':	printf("One\n");	break;
    		case '2':	printf("Two\n");	break;
    		case '3':	printf("Three\n");	break;
    		case '4':	printf("Four\n");	break;
    		case '5':	printf("Five\n");	break;
    		case '6':	printf("Six\n");	break;
    		case '7':	printf("Seven\n");	break;
    		case '8':	printf("Eight\n");	break;
    		case '9':	printf("Nine\n");	break;
    		case '0':	printf("Zero\n");	break;
    		default:	printf("숫자가 아닙니다.\n");	break;
    		}
    		printf("\n");
    	}
    }​
     

[case 코드 정리]


*단축키 참고

  • 전체적으로 들여쓰기를 정렬하려면 Ctrl+K 입력 후 Ctrl+F
  • 일부 전체를 주석처리 : 드래그 후 Ctrl+K -> Ctrl+C
  • 주석처리 해제 : 드래그 후 Ctrl+K -> Ctrl+U

1차원 배열


  • 둘 이상의 변수 동시 선언 효과
  • 많은 데이터의 일괄적 처리에 유용
  • 배열 선언 필요 요소 3가지
    • 배열 길이: 배열 구성 변수의 개수(상수 사용) = 방의 개수
    • 배열 요소 자료형: 배열 구성 변수의 자료형
    • 배열 이름: 배열 접근 시 사용할 이름
    • [example]
      int array [10]; => int: 배열 요소 자료형/ array: 배열 이름/ 10: 배열 길이
  • n차원 배열
    • 1차원 배열: 직렬로 같은 자료형의 배열을 나열
    • 2차원 배열: 1차원 배열이 층을 이루며 올라가는 형태
    • 3차원 배열: 육면체 모양의 형태
  • 1차원 배열의 접근
    • 인덱스(index): 배열 요소의 위치 표현
    • 인덱스는 0부터 시작( array[0], araay[1], array[2], ..., array[8], array[9] ) -> "Zerobase"
  • 배열 선언&접근 예시
    int main(void){
    	int array[10];	//배열 선언
        array[0]=10;	//첫 번째 요소 접근
        array[1]=20;	//두 번째 요소 접근
        array[2]=30;	//세 번째 요소 접근
        ...
        return 0;
    }​
    - array[s] = 10; => s+1번째 요소에 10을 대입

  • 배열 선언과 동시에 초기화
    int main(void)
    {
    	int arr1[5] = {1, 2, 3, 4, 5};
        int arr2[] = {1, 3, 5, 7, 9};
        int arr3[5] = {1, 2};
    }​
     
    • int arr1[5] = {1, 2, 3, 4, 5};
      => int arr1[5]: 길이가 5인(변수가 5개인) 배열 생성/ {1, 2, 3, 4, 5}: 초기화 리스트
      => 배열을 생성하여 초기화 리스트로 각 요소 초기화
      => 배열: [ 1 2 3 4 5 ]
    • int arr2[] = {1, 3, 5, 7, 9};
      => int arr2[]: 배열 길이가 정해지지 않았으나, 초기화 리스트를 통해 변수가 5개임을 명시 -> 길이가 5인 배열 생성
      => 배열: [ 1 3 5 7 9 ]
    • int arr3[5] = {1, 2};
      => 배열 길이가 5개인 배열을 만들고, 앞쪽 배열부터 초기화
      => 배열: [ 1 2 0 0 0 ]
  • 문자열(=문자의 배열) 상수: 문자열이면서 상수의 특징
  • 문자열 변수: 문자열이면서 변수의 특징
    char str1[5] = "Good"; -> 총 5개의 방 포함 배열
    char str2[] = "morning"; -> 총 8개의 방 포함 배열
  • 문자열 특징
    • 널(null)문자('\0', 아스키코드 0)가 문자열 끝에 위치
    • char str[6] = "Hello"; 코드에서, Hello는 5글자이지만 끝에 null을 고려하여 배열의 크기를 6으로 설정
      => 배열을 표시하면 [ H e l l o ( ) ] ( )은 null
    • Null의 역할: 문자열의 끝 표시/ printf 함수에서 출력 범위 결정
  • 문자열 vs. char형 배열
    • char arr[] = "abc";
    • char arr2[] = { 'a', 'b', 'c' }; => printf 사용 시 c 이후 쓰레기값이 표시될 수 있음
    • char arr3[] = { 'a', 'b', 'c', '\0' }; => null을 이용하여 경계 구분

배열을 이용하여 위 실습 코드 수정


  • 각각의 배열 요소는 문자열을 나타냄
  • 입력 숫자 키 값에서 30H(30Hexa, 16진수 30)를 빼면 ASCII코드에 따른 숫자값이 됨
    다음의 코드로 변환 가능
    int m = c - 0x30; //ASCII -> num값​
  • ASCII코드 확인-> 16진수 | 10진수 
    30 | 0
    31 | 1
    32 | 2
       ...
    39 | 9
  • 코드 변경 및 적용
    #include <stdio.h>
    #include <conio.h>
    
    int main(void) {
    
    	char* str[] = { "Zero", "One", "Two", "Three", "Four",
    		"Five", "Six", "Seven", "Eight", "Nine" }; // 문자열 포인터(*) 배열 선언
    
    	printf("숫자키를 입력하면 해당 영단어를 표시합니다.(x는 종료)\n");
    	while (1) {
    		printf(">");
    		char c = getch();
    		printf("%c\n", c);
    		
    		if (c == 'x' || c == 'X') break;//c | 0x20 == 'x'로 조건 넣어도 작동. c | 0x20을 통해 입력 값을 소문자로 변환
    
    		int m = c - 0x30; //ASCII -> num값
    		printf("%c: %s\n", c, str[m]); //입력 값c: str의 m번째 값.
    		printf("\n");
    	}
    }​


    정상 작동 확인