2007. 3. 16. 13:25

정수 변수 -> int, unsigned int, short, unsigned short, long, unsigned long
실수 변수 -> float, double
문자 변수 -> char, unsigned char
문자열 변수 -> char(문자 변수와 표현형은 똑같다.)


sizeof()란 상수, 변수, 자료형의 byte 수를 알고자 할 때 사용하는 예약어이다.
크기를 생각해서 프로그래밍을할 때 사용하는 예약어이다.

sizeof(대상체);

숫자를 표현함에 있어서도 바이트 수를 다르게 할 수 있다.

12 -> 2Byte
12L -> 4Byte
12.4 -> 8Byte
12.4F -> 4Byte

이렇게 똑같은 숫자이지만 크기를 정하여 표현할 수도 있다.

sizeof('A'); 1바이트
sizeof("김"); 3바이트
sizeof("A"); 2바이트
sizeof('한');
sizeof('★');
sizeof('ㅁ');4바이트

sizeof 연산자는 피연산자의 크기를 계산하여 바이트 단위로 결과가 나오게 된다.
'A'는 char 타입으로, 대부분의 시스템에서는 1바이트가 나온다.

 
sizeof("김");은 char a[] = "김";과 같은 의미이다.
sizeof(a);는 3이다.
이때, a는 "김"이라는 문자열에서 널문자까지 포함하는 크기를 가지는 char 타입의 배열이 된다.

즉, 개수가 3개인 배열이 되는 것이다.그래서 sizeof(a)는 배열 a의 크기인 3이 나온다.

"A"는 널문자 포함 2개의 공간을 차지하므로 char 타입 2개의 배열이 생성되어 sizeof("A")는 결과로 2가 나온다.

'한'과 같은 것은 사실 잘못된 표현이다. 컴파일러는 '한'을 'AB'와 같은 의미로 해석한다. 이는 영문자는 한 글자에 1byte인데 비하여, 한글이나 특수 문자는 한글자에 2byte를 차지하기 때문이다.

작은 따옴표는 문자형 상수를 나타내는 기호로써, 작은 따옴표 안에는 하나의 문자만 포함해야 하는데, 두 개의 문자를 포함하는 것이 되어, 컴파일러는 억지로 작은 따옴표 안의 내용을 메모리에 자리잡게 하고 그 주소를 가져온다.

이때 sizeof('한')이라고 한다면 '한'이라는 글자가 저장되어 있는 주소의 크기가 되며, 이는 포인터 타입의 크기와 같다.

현재 대부분의 시스템에서 포인터는 4byte의 크기를 갖고 있다. 컴파일러에게 sizeof('한')은 sizeof('AA')와 같은 의미로 해석되며, 그 결과는 해당 문자들을 메모리에 자리잡게 한 후 자리잡은 위치를 가리키는 포인터의 크기이다.결론적으로, '한'과 같은 문자 상수 표현은 잘못된 것이다.

R/E/F/E/R/E/N/C/E/

---------------------------------------------------------------------------

Data Types (16-bit)

---------------------------------------------------------------------------

Type Length Range

---------------------------------------------------------------------------

unsigned char 8 bits(1)         0 to 255

char 8 bits(1)                     -128 to 127

enum 16 bits(2)                  -32,768 to 32,767

unsigned int 16 bits(2)          0 to 65,535

short int 16 bits(2)               -32,768 to 32,767

int 16 bits(2)                      -32,768 to 32,767

unsigned long 32 bits(4)       0 to

long 32 bits(4)                    -2,147,483,648 to 2,147,483,647

float 32 bits(4)                    3.4 x 10-38 to 3.4 x 10+38

double 64 bits(8)                 1.7 x 10-308 to 1.7 x 10+308

long double 80 bits(10)         3.4 x 10-4932 to 1.1 x 10+4932

near(pointer) 16 bits(2)         not applicable

far (pointer) 32 bits(4)         not applicable

---------------------------------------------------------------------------

Data Types (32-bit)

---------------------------------------------------------------------------

Type Length Range

---------------------------------------------------------------------------

unsigned char 8 bits(1)            0 to 255

char 8 bits(1)                        -128 to 127

short int 16 bits(2)                 -32,768 to 32,767

unsigned int 32 bits(2)             0 to 4,294,967,295

int 32 bits(2)                         -2,147,483,648 to 2,147,483,647

unsigned long 32 bits(2)           0 to 4,294,967,295

enum 16 bits(4)                     -2,147,483,648 to 2,147,483,647

long 32 bits(4)                      -2,147,483,648 to 2,147,483,647

float 32 bits(4)                       3.4 x 10-38 to 3.4 x 10+38

double 64 bits(8)                    1.7 x 10-308 to 1.7 x 10+308

long double 80 bits(10)            3.4 x 10-4932 to 1.1 x 10+4932

near(pointer) 32 bits(2)             not applicable

far (pointer) 32 bits(4)              not applicable

---------------------------------------------------------------------------

'STUDY > C 언어' 카테고리의 다른 글

연산자 2  (0) 2007.03.17
연산자 1  (0) 2007.03.16
명령어 이해 - volatile  (0) 2007.03.09
명령어 이해 - for 문  (0) 2007.03.07
명령어 이해 - #ifdef / #ifndef / #endif  (0) 2007.03.02
Posted by Paul Hwang
2007. 3. 9. 16:33

volatile 은 휘발성 메모리라는 표시로 그 값이 프로그램에서
바꾸지 않아도 바꾸어 질 수 있기 때문에 컴파일러가 옵티마이즈를 하지 않습니다.

보통 하드웨어를 제어하는 곳(디바이스 드라이버)에서 사용하게 되며
프로그램이 그 값을 정의 했더라도 하드웨어에서
자체적으로 다른 값으로 바꿀 수 있는 곳에 사용됩니다.

예를 들어

unsigned int flashRead32 (unsigned int *pFlash, unsigned int offset)
{
    volatile unsigned int dword;
    dword = *(pFlash->base + offset);
    dword = *(pFlash->base + offset);

return (dword);
}

dword를 volatile로 선언 했기때문에 읽으라는 값을 두번 읽지만
그냥 선언 했을 경우에는 한번만 읽은 것 하고 동일한 로직으로 보기 때문에 한번만 수행할 가능성이 높습니다.

특히 딜레이를 주기위하여 for문을 쓰는 경우에 변수정의를 위와 같은 이유로아래와 같이 사용해 주어야 딜레이 값이 확실하게 작용합니다.

volatile unsigned int i;

'STUDY > C 언어' 카테고리의 다른 글

연산자 1  (0) 2007.03.16
데이터형 구조  (0) 2007.03.16
명령어 이해 - for 문  (0) 2007.03.07
명령어 이해 - #ifdef / #ifndef / #endif  (0) 2007.03.02
명령어 이해 - if / while / brake  (0) 2007.03.02
Posted by Paul Hwang
2007. 3. 7. 17:06

for(초기치;종결조건;증가치) ==> 종결 조건이 참이면 for 문을 계속 돌라는 이야기 입니다.
초기치, 종결조건, 증가치 모두 꼭 있을 필요는 없습니다.

즉, for(;;) 도 가능하고, for(i=0;;) 도 가능하고 ... 다 가능합니다.

for(;1;) 또는 for(;2;) ==> 즉 종결조건이 1 또는 2 죠??

C 에서 참 / 거짓을 구분하는 기준은 '0' 을 기준으로 합니다.
따라서 1, 2 는 0 이 아니므로 참입니다.

위의 for 문은 계속 돌라는 얘기가 됩니다.
위의 for(초기치;종결조건;증가치) 는 아래와 같습니다.

초기치;

while(1)
{
    if(!종결조건) // ! 이 중요합니다. 즉 종결조건이 참이 아니면...
    {
        break; // while 문을 끝내라는 명령어죠??
    }

증가치;

}


//예제///////////////////////////////////////////////////////////////

#include <stdio.h>
main( )
{
    int i,s;
    s=0;
    for(i=1; i<=5; i++)
    s=s+i;
    printf("sum=%d\n",s);
}

///////////////////////////////////////////////////////////////////

for(처음 값은 초기값; 두번째값은 조건식; 세번째는 증감연산자)
처음에 초기값은 1번 실행되고
그 다음에 조건식이 참이면 for문 안에 문장을 실행합니다.
문장을 모두 실행후에 증감연산인 i++을 실행합니다

그 다음 다시 조건식이 참이면 포문안에 문장을 실행해서 계속 반복하겟죠.
조건식이 거짓이면 for문이 중지됩니다.

 

'STUDY > C 언어' 카테고리의 다른 글

데이터형 구조  (0) 2007.03.16
명령어 이해 - volatile  (0) 2007.03.09
명령어 이해 - #ifdef / #ifndef / #endif  (0) 2007.03.02
명령어 이해 - if / while / brake  (0) 2007.03.02
명령어 이해 - return  (1) 2007.03.02
Posted by Paul Hwang
2007. 3. 2. 11:57

#define WORD 1

이것은 WORD를 1로 치환한다는 것입니다.
쉬운 예를 들자면 많일 원의 면적을 구하는 프로그램을 짤다고 했을 때
원주율 3.14가 계산에 필요하게 됩니다.

...

int r, s;                // r 은 원의 반지름 길이, s는 원의 넓이
r = 3;
s = 3.14 * r ^ 2;

...

위와 같이 되겠죠. 그런데 이때 원주율 3.14를 좀더 정확하게 3.141592로 바꿔야 한다면 위에는 3.14가 한번밖에 안쓰였지만 3.14를 약 100번정도 사용하였다면 그걸 일일이 다 바꾸는건 엄청난 노가다가 될것입니다.

이럴때

#define PI 3.14

라고 해두면

...

int r, s;                // r 은 원의 반지름 길이, s는 원의 넓이
r = 3;
s =PI * r ^ 2;

...

라는 코드가 만들어 지니까
#define PI 3.141592
라고만 바꾸면 끝이되죠

위의 경우에만 쓰라고 있는건 아니고
#define라는 건
어떤 숫자라든지 긴 정의를 짧게 또는 의미있는 단어로 바꾸어 주는겁니다.

#ifdef WORD
printf("Hello, ");
#endif

여기서 #ifdef WORD 라는 것은 'WORD란 단어가 define가 되어있다면' 이란 뜻입니다.
즉 WORD란 단어가 위에서 #define WORD 1으로 define되어 있으므로 참이 되고
그 다음줄 printf("Hello, ");가 실행되는 거죠

#endif 란 #ifdef 구문이 끝났음을 알리는 겁니다.

#ifndef WORD2 도 비슷합니다.
이것은 #ifdef와는 반대로 'WORD2란 단어가 define되어 있지 않다면'이란 뜻입니다.
즉 WORD2란 단어는 위에서 #define에 의해 define된 적이 없으므로 참이되고
그 다음줄 printf("world/n"); 가 실행이 됩니다.

#ifndef WORD
printf("HaHa\n");

위 에서는 #ifndef WORD에서 WORD는 이미 define되어 있으므로 거짓이 되서
그 다름줄인printf("HaHa\n"); 가 실행되지 않습니다.
즉 출력결과는 Hello world 가 됩니다.

'STUDY > C 언어' 카테고리의 다른 글

명령어 이해 - volatile  (0) 2007.03.09
명령어 이해 - for 문  (0) 2007.03.07
명령어 이해 - if / while / brake  (0) 2007.03.02
명령어 이해 - return  (1) 2007.03.02
전역변수 사용시 주의 할 점  (0) 2007.02.26
Posted by Paul Hwang
2007. 3. 2. 11:52

if는 분기문이고..
while은 loop문입니다..

그럼 분기문과 loop의 차이를 아셔야 하는데...

간단히 설명드리면..
분기문은.. 특정조건을 만족할때 분기문 안에 내용을 실행한다 이고,
loop문은 특정조건을 만족하는 동안 loop문 안에 내용을 반복한다입니다...

말인즉슨...

if(i < 100) {
    i++; // i=i+1;
}
위에 구문은 i가 100 보다 작으면 i에 1을 더하라 고 명령하는것입니다..

while(i < 100) {
    i++; // i=i+1;
}
위에 구문은 i가 100보다 커질때 까지 i를 1씩 더하는 작업을 반복하라 입니다...

전혀 다른 구문이죠...

brake;는 루프문에 만 사용이 가능하며...
가장 가까운 loop를 강제 종료 시킵니다...

int i = 0;

while(i < 100) {
    break;
    i++;             // i=i+1;
}
라고 하면...i=0;으로 끝이 납니다...

int i = 0;

while(i < 100) {
    i++;             // i=i+1;
    break;
}

라고 하면 i는 1로 끝이 나죠...
브레이크의 위치에 따라 loop(반복문의 실행을 순차를 비교해보시면 더 좋을 것입니다.)

자 이제 while을 if로 바꾸면 왜 break;가 에러가 나는냐 라는 질문으로 들어가면...
우선 while은 loop(반복)문이고 if는 분기문 이기 때문에 전혀 다른말이 됩니다.

굳이 따지자면...

if( 나는 대학생){
    공부를 한다.
}

while( 나는 대학생){
    공부를 한다.
}

위와 같이 2개를 예로 들면...
if는 내가 대학생이면 공부를 한다 이고..
while은 내가 대학생인 동안 계속 공부를 한다...
입니다...

비슷해 보이실지 모르겠지만 전혀 다른말입니다.
간단하게 설명하자면 if를 계속 반복하면 while이됩니다...
해서 while을 if로 바꾸면 원하던 결과와 전혀 다른 결과가 나오게 되니 바꾸어선 안될것입니다..

그리고..
break는 loop문에만 사용이 가능한 구문이라 했습니다...
while(반복문)을 if(분기문)으로 교체를하면 당연히 말이 안 되기 때문에 에러를 뱉어 내는것입니다..

Posted by Paul Hwang