diff --git a/README.md b/README.md index 1c0514bedb4244c0dafff209128247e69389669c..b8dcd1dfa28761189f76901fcf492d6d0ccd7d00 100644 --- a/README.md +++ b/README.md @@ -326,6 +326,48 @@ int main() fprintf(stdout, "sumU %%u %u\n", sumU); } ``` -* 해당 코드 실행시 음수인 -100을 siA에 대한 input값으로 넣어 sumS와 sumU에 관한 결과를 살펴보면 두 값은 %d로 출력했을 때 모두 -200이 나왔고 %u로 출력했을 때 모두 4294967096이 나왔다. -* 분명 unA는 unsigned 값인데 -100인 siA값에 unA를 더하자 값이 줄어 -200이 된 것을 확인 할 수 있다. +> * 해당 코드 실행시 음수인 -100을 siA에 대한 input값으로 넣어 sumS와 sumU에 관한 결과를 살펴보면 두 값은 %d로 출력했을 때 모두 -200이 나왔고 %u로 출력했을 때 모두 4294967096이 나왔다. +> * 분명 unA는 unsigned 값인데 -100인 siA값에 unA를 더하자 값이 줄어 -200이 된 것을 확인 할 수 있다. + +4. static, automatic, const 변수 +> 1. automatic : 기본적으로 비 선언시에는 auto로 선언된다. auto로 설정되면 main함수에서 다른 함수를 호출하여 실행 하였을 때 새로운 scope가 형성되어 함수사용 후 그대로 scope가 지워져서 count의 내부 값이 바뀌어도 main에서의 값은 바뀌지 않는 등의 경우가 생긴다. +> 2. static : static 선언을 하게 되면 새로운 메모리 공간이 형성되어 사라지지 않고 계속 남아있게 된다. 또한 단 하나의 주소값을 가지므로 변수값이 계속 켭켭이 쌓인다. array size가 fixes 되어 있고, (따라서 크기 지정 필수) scope가 종료되어도 계속 살아 있으며 지정을 하지 않으면 초기화가 0 또는 null 로 선언된다. +> 3. const : 말 그대로 상수선언이다. 컴파일 타임이나 링킹타임에 그냥 상수로 들어간다. (array 선언을 해도 마찬가지) 또한 const 값은 변할 수 없다! + +5. 아래는 32bit 프로그램에서 binary의 1의 개수 세는 함수 작성한 것이다. +```C +int count_one(int a) +{ + int i, count = 0; + for(i=31; i>=0; i--) + { + count += a & 1; + a >>=1; + } +} +``` +> * 위의 코드에서 살펴보면 계속 a를 한 자리씩 오른쪽 shift하여 계속 마지막 자리 숫자와 1의 and operation을 한 값을 통해 해당 자리가 1이면 count에 1이 더해지게 만들었다. + +6. shift 연산 +> * signed 값의 음수의 오른쪽 shift연산은 빈자리에 1을 계속 집어넣으므로 1로 시작한다. 따라서 음수를 오른쪽으로 계속 shift하면 절대 0이 될 수 없다. +> * unsigned로 받게 되면 shift 연산이 signed와 달리 한칸이 오른쪽으로 밀릴 때 마다 빈칸에 0이 삽입된다. +> * 따라서 아래의 코드를 살펴보면 unsigned int로 변수를 받아야만 오른쪽 shift시에 빈칸이 0으로 채워지므로 오류가 나지 않는다. (signed로 받을 시 1로 채워져 아래 코드의 경우엔 무한루프에 빠질 수 있다.) +```C +#include <stdio.h> +#define VALUE_ONE 1 +int count_one(unsigned int a) +{ + int static numCalls = 100; + int count = 0; + while (a!=0) + { + count += a & VALUE_ONE; + a >>= VALUE_ONE; + } + fprintf(stderr, "Call : %d\n", numCalls); + numCalls++; + return count; +} +``` +