1. Home
  2. Docs
  3. C Programming Guides
  4. Getting Started with C Language
  5. Data Types

Data Types

Interpreting Declarations

The following set of operators with identical precedence and associativity are reused in declarators, namely:

  • unary * “dereference” operator which denotes a pointer;
  • binary [] “array subscription” operator which denotes an array;
  • (1+n)-ary () “function call” operator which denotes a function;
  • () grouping parentheses which override the precedence and associativity of the rest of the listed operators.

Fixed Width Integer Types

The header provides several fixed-width integer type definitions. These types are optional and only provided if the platform has an integer type of the corresponding width, and if the corresponding signed type has a two’s complement representation of negative values. See the remarks section for usage hints of fixed width types.

/* commonly used types include */
uint32_t u32 = 32; /* exactly 32-bits wide */
uint8_t u8 = 255; /* exactly 8-bits wide */
int64_t i64 = -65 /* exactly 64 bit in two's complement representation */

Integer types and constants

Signed integers can be of these types (the int after short, or long is optional):

signed char c = 127; /* required to be 1 byte */
signed short int si = 32767; /* required to be at least 16 bits. */
signed int i = 32767; /* required to be at least 16 bits */
signed long int li = 2147483647; /* required to be at least 32 bits. */

signed long long int li = 2147483647; /* required to be at least 64 bits (Version ≥ C99) */

Each of these signed integer types has an unsigned version.

unsigned int i = 65535;
unsigned short = 2767;
unsigned char = 255;

For all types but char the signed version is assumed if the signed or unsigned part is omitted. The type char constitutes a third character type, different from signed char and unsigned char and the signedness (or not) depends on the platform. Different types of integer constants (called literals in C jargon) can be written in different bases, and different width, based on their prefix or suffix.

/* the following variables are initialized to the same value: */
int d = 42; /* decimal constant (base10) */
int o = 052; /* octal constant (base8) */
int x = 0xaf; /* hexadecimal constants (base16) */
int X = 0XAf; /* (letters 'a' through 'f' (case insensitive) represent 10 through 15) */

Decimal constants are always signed. Hexadecimal constants start with 0x or 0X and octal constants start just with a 0. The latter two are signed or unsigned depending on whether the value fits into the signed type or not.

/* suffixes to describe width and signedness : */
long int i = 0x32; /* no suffix represent int, or long int */
unsigned int ui = 65535u; /* u or U represent unsigned int, or long int */
long int li = 65536l; /* l or L represent long int */

INT_MAX is of type long if possible, or long long otherwise. The header file describes the limits of integers as follows. Their implementation-defined values shall be equal or greater in magnitude (absolute value) to those shown below, with the same sign.

MacroTypeValue
CHAR_BITsmallest object that is not a bit-field (byte)8
SCHAR_MINsigned char-127 / -(27 – 1)
SCHAR_MAXsigned char+127 / 27 – 1
UCHAR_MAXunsigned char255 / 28 – 1
CHAR_MINcharsee below
CHAR_MAXcharsee below
SHRT_MINshort int-32767 / -(215 – 1)
SHRT_MAXshort int+32767 / 215 – 1
USHRT_MAXunsigned short int65535 / 216 – 1
INT_MINint-32767 / -(215 – 1)
INT_MAXint+32767 / 215 – 1
UINT_MAXunsigned int65535 / 216 – 1
LONG_MINlong int-2147483647 / -(231 – 1)
LONG_MAXlong int+2147483647 / 231 – 1
ULONG_MAXunsigned long int4294967295 / 232 – 1
Version >= C99
LLONG_MINlong long int-9223372036854775807 / -(263 – 1)
LLONG_MAXlong long int+9223372036854775807 / 263 – 1
ULLONG_MAXunsigned long long int18446744073709551615 / 264 – 1

Floating Point Constants Data Types

The C language has three mandatory real floating point types, float, double, and long double.

float f = 0.314f; /* suffix f or F denotes type float */
double d = 0.314; /* no suffix denotes double */
long double ld = 0.314l; /* suffix l or L denotes long double */

/* the different parts of a floating point definition are optional */
double x = 1.; /* valid, fractional part is optional */
double y = .1; /* valid, whole-number part is optional */

/* they can also defined in scientific notation */
double sd = 1.2e3; /* decimal fraction 1.2 is scaled by 10^3, that is 1200.0 */

String Literals Data Types

A string literal in C is a sequence of chars, terminated by a literal zero.

char* str = "hello, world"; /* string literal */

/* string literals can be used to initialize arrays */
char a1[] = "abc"; /* a1 is char[4] holding {'a','b','c','\0'} */
char a2[4] = "abc"; /* same as a1 */
char a3[3] = "abc"; /* a1 is char[3] holding {'a','b','c'}, missing the '\0' */

String literals are not modifiable (and in fact may be placed in read-only memory such as .rodata). Attempting to alter their values results in undefined behaviour.

char* s = "foobar";
s[0] = 'F'; /* undefined behaviour */

/* it's good practice to denote string literals as such, by using `const` */
char const* s1 = "foobar";
s1[0] = 'F'; /* compiler error! */

Multiple string literals are concatenated at compile time, which means you can write construct like these.

//Version < C99
/* only two narrow or two wide string literals may be concatenated */
char* s = "Hello, " "World";

//Version ≥ C99
/* since C99, more than two can be concatenated */
/* concatenation is implementation defined */
char* s1 = "Hello" ", " "World";

/* common usages are concatenations of format strings */
char* fmt = "%" PRId16; /* PRId16 macro since C99 */

String literals, same as character constants, support different character sets

/* normal string literal, of type char[] */
char* s1 = "abc";

/* wide character string literal, of type wchar_t[] */
wchar_t* s2 = L"abc";

//Version ≥ C11
/* UTF-8 string literal, of type char[] */
char* s3 = u8"abc";

/* 16-bit wide string literal, of type char16_t[] */
char16_t* s4 = u"abc";

/* 32-bit wide string literal, of type char32_t[] */
char32_t* s5 = U"abc";

Was this article helpful to you? Yes No

How can we help?