본문 바로가기

프로그래밍/C language

2. Types, Operators, and Expressions

1) Variable Names

 

-첫 번째에는 반드시 letter이 와야 한다. 왜냐하면, library routine에서 _로 시작하는 경우가 많기 때문이다.
-local variable의 _의 사용을 통해 readability를 향상할 수 있다.
-local variable은 짧은 이름을 사용한다. 특히, loop control에 사용되는 경우
-대소문자를 구별한다.
-function, external variable은 31자 내로 제한된다. 이 이상을 넘어갈 경우, assenbler, loader가 처리할 수 없다.
-목적에 알맞는 이름을 할당하도록 한다.

2.2 Data Types and Sizes

-char, short (int), int, long (int), float, double
-char은 보통 8bit이며, -128~127을 나타냄

(ad. 음수를 양수로 변환하여 사용할 때, -128이 128로 변환되지 않아 오류 발생 가능성이 존재함)
-각각의 data type의 max, min값은 <limit.h>에 정의된, symbolic constant를 출력함으로써 확인 가능
-각각의 data type의 bit 수는 hardware에 종속적임(?)
-signed, unsigned라는 qualifier를 이용하여 범위를 한정시킬 수 있다. 생략하면 signed임

2.3 Constants

- suffix로 L, l, ul, UL, f, F을 써서, 상수의 type을 명시 가능
- float는 deximal point나 '1e-2'와 같은 표현을 통해 묵시적으로 type지정
- 8진수 표기는, 0을 접두사로, 16진수 표기는 0x를 접두사로 표기
ex) 012 = 8+2= 10, 0x12 = 16+2 = 18

charcter constant : character형태로 표현되지만 int값(char)으로 mapping 되는 상수, single quotes로 표현
ex) '0'은 실제로 48의 int값임, '0'이 실제로 어떤 값으로 mapping 되는지 명시하기 위해
octa/hexa표현 가능, 접미사 0, x를 이용함. '0'=='\060'=='x30'
'\n'과 같은 escape sequence도 포함


string constant : string형태로 표현되지만, array로 mapping 되는 상수
ex) "1234고"는 실제로 array에 '1', '2', '3', '4', '고', '\0'순서로 저장되어있음
항상 string의 마지막을 표현하기 위해, '\0' == 0의 값이 추가로 들어가 있음
strlen함수는, '\0'을 제외한 문자열의 길이를 출력하는 함수임


constant expression : 항상 어떠한 상수값으로 표현되는 constant, 컴파일 단계에서 평가됨
ex) #define MAXLINE 1000에서 MAXLINE


enumeration constant : int값을 가지는 상수들의 리스트, 값을 명시하지 않을 경우 0, 1, 2,... 순으로 특정됨
 (컴파일 단계에서 체크되지 않지만, #define에 비해 종종 나은 경우가 있음)


ex) enum boolean {NO, YES};
=> NO는 0 YEW는 1이라는 int값을 나타냄
enum escapes {BELL = '\a', BACKSPACE = '\b'};
enum months {JAN = 1, FEB, MAR, APR};
=> JAN은 1, FEB는 2, MAR은 3, APR은 4

2.4 Declaration

 

- 프로그램이 실행되기 이전에 실행되는 initializer는, constant expression임(ex)#define구문)
- 실행 시 initialize 되는 variable의 declaration은 다음과 같은 형태로 이루어짐


ex1) int lower, upper, step;
 char c, line [1000];

=> 같은 type 열거 가능


ex2) int lower;
 int upper;
 int step;
 char c;
 char line[1000]
=> ex1)이 ex2) 보다 더 적은 공간을 차지함. 


ex3) char esc = '\\'
 int i = 0;
=> type과 값 할당을 동시에 가능


- const라는 qualifier를 이용하여 변하지 않기를 원하는 variable을 명시할 수 있음, 함수의 parameter에 명시 가능


ex) const char msg[] = "warning";
const double e = 2.718;
int strlen(const char[]) => 추후 parameter값이 변하지 않을 것을 명시

2.5 Arithmetic Operations

+, -, *, /, % 
- 기본적으로, 왼쪽에서 오른쪽으로 연산
- % 는 float에서는 적용 안됨
- %, /는 음수 계산에 대해서는 machine-dependent

2.6 Relational and Logical Operations

연산 우선순위 : Arithmetic Operator > relational, equality > && > ||
- relational operatior : >, >=, =<, <
- equality operator : ==,!=
- logical operator : &&, ||
왼쪽에서부터 오른쪽으로 비교되며, 중간에 결과가 나오면 stop 함
- unary operator :! , 0이 아닌 것을 0으로, 0을 1로

2.7 Type Conversions

- 일반적으로, two operand연산에서 automatic conversion은 narrower->wider type으로 이루어짐
(정보의 손실이 없도록)
- automatic conversion은 unsigned가 들어갈 경우, machine dependent 하게 동작하여 문제가 생길 수 있음


- 내부적인 conversion 규칙은 다음과 같음


If either operand is long double, convert the other to long double
Otherwise, it either operand is double, convert the other to double
Otherwise, it either operand is float, convert the other to float
Otherwise, convert char short to int
Then, if either operand is long, convert the other to long


- 함수에 parameter 전달 시, 단항 연산자인 cast를 이용하여 명시적 타입 변환 이용하여 값을 전달할 수 있음
ex) sqrt((double)n); => math.h에서 정의한 함수는 입력 인자로 double타입을 받음
- 함수의 prototype 선언에 명시적으로 표현함으로써 타입이 변환되도록 할 수 있음.
ex) double sqrt(double);

2.8 Increment and Decrement Operators

- variable앞에 붙어서 값을 1 증가/감소시키는 연산
- prefix의 --, ++는 값을 사용하기 이전에 증가, postfix의 --,++는 값을 사용한 이후에 증가

2.9 Bitwiser Operators

- &, |, ^ (XOR), <<, >>, ~ (one's complement)
- ex) ~077의 표현이 0177700의 표현보다 낫다. bit length에 독립적이므로
- 오른쪽 shift의 경우, unsigned가 아닌 경우 0이 아닌 다른 값(sign bit)으로 채워지는 경우가 있음
(machine-dependent)

2.10 Assignment Operators and Expressions

- (expr1) (op) = (expr2)의 형태로 쓰이며, (expr1) = (expr1) (op) (expr2)와 동일함
- op로 쓸 수 있는 것들은, +, -, *, /, %, >>, <<, &, ^, | 
- Assignment operator를 사용함으로써, 표현이 이해하기 쉬워지고 코드의 길이가 간결해짐

2.11 Conditional Expressions

- 조건식의 형태를 띤 expression
- (expr1)?(expr2):(expr3) 의 형태를 가짐, expr2와 expr3가 type이 다를 경우 conversion 규칙에 따라 변환됨
ex) z = (n>0)?a:b;
- expr1을 만족하면 expr2의 value를 가지고, 그렇지 않으면 expr3의 value를 가짐
- if-else구문보다 가독성이 좋음

2.12 Precedence and Order of Evaluation

- operator는 다음과 같은 연산 우선순위를 갖는다.

() [] -> . (괄호, 구조체 멤버 접근) 
! ~ ++ -- + - * & (type) sizeof (단항 연산자) (associativity : R->L)
* / %
+ - (산술 연산자)
<< >> (시프트 연산자)
>= =< > < (비교 연산자)
== != (동등 연산자)

^
| (비트 연산자)
&&
|| (논리 연산자)
?: (조건 연산자) (R->L)
= += -= *= 등 (할당 연산자) (R->L)


- operator는 우선순위를 갖지만, operand에서는 우선순위를 명시하고 있지 않음(&&, ||, ?:, , 제외)
따라서, Evaluation의 순서가 문제가 될 수 있음
ex) x = f()+g() 에서, f가 먼저 실행될지 g가 먼저 실행될지는 machine-dependant 함
- 이러한 문제점은 increment/decrement operator가 있는 function argument에서도 발생함
ex) printf("%d %d", ++n, power(2,n))
=>이러한 경우, ++는 side effect를 발생시킬 수 있음
- increment/decrement operator가 expression update에 쓰일 때도 문제가 됨
ex) a[i] = i++
- 따라서, Evaluation 순서에 independent 하게 코드를 짜되, 그 방식을 이해하는 것이 중요

'프로그래밍 > C language' 카테고리의 다른 글

6. Structures  (0) 2021.08.14
5. Pointer and Arrays  (0) 2021.08.11
4. Function and Program Structure  (0) 2021.03.29
3. Control Flow  (0) 2021.03.29
About C language bulletin board  (0) 2021.03.29