C 내장 정수
목차
void
char
short
int
long
long long
_Bool
enum
enum
vs #define
enum
, flags and bitwise 무효의
void
data type is used in these situations:
-
A function that does not return any value:
void doSomething( int iNum );
-
A function that does not accept any parameter:
int doSomething( void );
-
A pointer to void, generic pointer that has no type and represent an address of an object, that can be casted to any type.
void *pMyPointer;
Don't you dare to
sizeof(void)
, but you cansizeof(*void)
. Some compilers allowsizeof(void)
but this is not in the ISO standard.
숯
In some contexts char
is used to handle numerics, because is large enough to hold the number, and uses less memory than an int
.
짧은
-
short
,short int
,signed short
andsigned short int
are the same thing. -
unsigned short
andunsigned short int
are the same thing.
정수
-
int
,signed
andsigned int
are the same thing. -
unsigned
andunsigned int
are the same thing.
긴
-
long
,signed long
,long int
, andsigned long int
are the same thing. -
unsigned long
andunsigned long int
are the same thing.
긴 긴 [C99]
-
long long
,signed long long
,long long int
, andsigned long long int
are the same thing. -
unsigned long long
andunsigned long long int
are the same thing.
_불 [C99]
Name | Characteristic | Dependence in stdbool.h
|
Value |
---|---|---|---|
_Bool |
Native type | Don't need header | |
bool |
Macro | Yes | Translate to _Bool
|
true |
Macro | Yes | Translate to 1
|
false |
Macro | Yes | Translate to 0
|
-
_Bool
orbool
? Both are fine, butbool
looks better than the keyword_Bool
. - Accepted values for
bool
and_Bool
are:false
ortrue
. Assign0
or1
instead offalse
ortrue
is valid, but is harder to read and understand. -
_Bool
is NOTunsigned int
, but is part of the group unsigned integer types. It is large enough to hold the values0
or1
. -
A macro to tell if the macros
bool
,true
andfalse
are available is__bool_true_false_are_defined
, that translate to1
.
#if 1 != __bool_true_false_are_defined #include <stdbool.h> #endif int main(void) { bool x = true; if(false == x) return 1; else return 0; }
-
Assigning an scalar type to
_Bool
orbool
, if the scalar value is equal to0
or compares to0
it will be0
, otherwise the result is1
.
#include <stdio.h> int main(void) { _Bool x = 9; // 9 is converted to 1 printf("%d", x); // Output 1 return 0; }
_Bool
has size of 1 byte, but not all bits are used. The programmer may try to use the other bits, but is not recommended, because the only guaranteed that is given is that only one bit is use to store the data, not like the typechar
that have 8 bits available.DO NOT, but yes, you are able to redefine
bool
,true
andfalse
but is not a good idea. This ability is considered obsolescent and will be removed in future.
열거
Components of an enum
:
enum
identifier {
enumerators }
Tag ;
enum
identifier {
enumerators ,
}
Tag ;
[C99]
typedef
enum
identifier {
enumerators }
Alias ;
typedef
enum
identifier {
enumerators ,
}
Alias ;
[C99]
-
Identifier: optional, with no identifier
enum { BLUE };
or with identifierenum color { BLUE };
-
Enumerators: not optional, one or many integers constant. Shall be any value that is representable by
int
. Theint
value can be left to the compiler to decide, or may be defined by the programmerBLUE=11
. The default behavior if no value is defined, the first will have value0
and the subsequent enumerator will be the previus value + 1. Yes, you can have enumerators with duplicated values.
// BLUE is 0, GREEN is 1, Grey is 2 enum { BLUE, GREEN, GREY }; // BLUE is 0, GREEN is 15, Grey is 16, RED is 3, BLACK is 4, WHITE is 19 enum { BLUE, GREEN = 15, GREY, RED = 3, BLACK, WHITE = RED+GREY }; // BLUE is 0, GREEN is 12, Grey is 12 enum { BLUE, GREEN = 12, GREY = 12 };
-
[C99] The last enumerator can be left with comma at the end
,
. Because makes easy to handle the enumerator using copy/paste or a script. This eliminates the need for conditional logic to handle the last enumerator.
enum { BLUE, GREEN }; // Valid before and after C99 enum { BLUE, GREEN, }; // Only valid after C99
-
Tag: optional. None, one or many tags separated by comma
,
. But if you have atypedef
the tag part is not a tag anymore, it is alias for that type.
enum { BLUE, GREEN } LED1, LED2; // Tags enum { WHITE, RED } LED3; // Tag enum color { GREY, ORANGE }; // No tag LED1 = GREEN; LED2 = BLUE; LED3 = RED; enum color LED4 = GREY;
-
Alias of a type
enum
is done by using the keywordtypedef
, in simple words means that a new name for thisboring_name
is aawesome_name
. Usingtypedef
in the same line if you have tags, the tags are not tags anymore, instead they are alias an behave different than a tag.
// Giving a name to a enum with no identifier typedef enum { BLUE } color; color LED = BLUE; typedef enum color { BLUE } c; c LED = BLUE; // or `enum color LED = BLUE;` // since you have typedef there is no reason to use this way // The enum exist before the typedef enum color { BLUE } LED2; typedef enum color c; c LED1 = BLUE; LED2 = BLUE; // LED2 still a tag
Assigning a value to a variable of enum
type may cause a warning during compilation. Why?
-
enum
is not a type safe, and the programmer can assign any number that is not one of the _enumerators, it will compile, but this kind of error, wrong value range, is hard to debug. -
Use an explicit cast to suppress the warning. This is one of the few cases that an explicit cast is recommended.
enum color { BLUE=0, GREEN, RED, } LED1 ; LED1 = (enum color)BLUE; //Explicit cast to suppress compiler warning.
하지마
따르지 말아야 할 예:
// Don't use comma on last enumerator if
// you are strict compilling to C98/C90
enum { BLUE, };
// No enum keyword used
color { BLUE };
// No enumerator declared
enum color {};
enum {};
// Use a tag as a type for a new variable.
enum { BLUE } LED;
LED myLed = BLUE;
// No forward-declarations, only struct and union can use this style.
enum color;
color { BLUE };
typedef enum color;
color { BLUE };
// Enumerators with the same name in the same scope.
enum color1 { BLUE };
enum color2 { BLUE };
// Valid, but danger, avoid even if you know BLUE value is 0, use BLUE and not 0
enum color { BLUE=0, GREEN, RED, } LED1 ;
LED1 = 0;
열거형 대 정의
It's a programming style preference, in my opinion the enum
code is cleaner, easier to understand and debug than the macro #define
for cases that represent a group of related data.
enum { BLUE=0, RED, GREEN, };
#define BLUE 0
#define RED 1
#define GREEN 2
Also goes well in switch()
:
// Declaration
enum color { BLUE, GREEN, RED, } led_1;
// Definition
led_1 = (enum color)BLUE; // Explicit cast to suppress compiler warnings.
switch(led_1) {
case BLUE:
//do something
break;
case GREEN:
//do something
break;
case RED:
//do something
break;
}
But in case you need to save every single byte, #define
and char
instead of enum
will be better.
#include <stdio.h>
#define VALUE1 1;
enum a { VALUE2 = 2 };
int main(void) {
char b = VALUE1;
printf("Char: %d\nEnum: %d\n", sizeof(b), sizeof(enum a));
return 0;
}
The output may be Char: 1
and Enum: 4
. For small numbers, to save space, in embedded a common use is char
that use less bytes then an int
. Make sure to check the compiler and find a balance of speed of optimized types vs saving bytes.
열거형, 플래그 및 비트 단위
Using enum
to group flags is powerful way to produce faster and smaller binary, at the expensive to be painful to debug. Example bellow uses enumerators defined with the power of two, in that way using the bitwise operator |
give a unique number for every combination you do. And it is easy read what combination is in use.
#include <stdio.h>
enum { USB = 1, WIFI = 2, SERIAL = 4 };
int main(void) {
int iFlags = USB | WIFI;
switch( iFlags ) {
case USB: // 1
printf("\nUSB");
break;
case WIFI: // 2
printf("\nWIFI");
break;
case SERIAL: // 4
printf("\nSERIAL");
break;
case USB | WIFI: // 3
printf("\nUSB and WIFI");
break;
case USB | SERIAL: // 5
printf("\nUSB and SERIAL");
break;
case USB | WIFI | SERIAL: // 7
printf("\nUSB and WIFI and SERIAL");
break;
case WIFI | SERIAL: // 6
printf("\nWIFI and SERIAL");
break;
}
return 0;
}
Finding if a flag is set in the flags.
#include <stdio.h>
enum { USB = 1, WIFI = 2, SERIAL = 4 };
int main(void){
int iFlags = USB | WIFI | SERIAL;
if( iFlags & USB ) {
printf("USB flag is set"); // This is the output
} else {
printf("USB flag is NOT set");
}
return 0;
}
References
Reference
이 문제에 관하여(C 내장 정수), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/bkddev/c-built-in-integers-3nfg텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)