C Program Syntax
C Program Syntax
C syntax
The syntax of the C programming language, the rules governing writing of software in the language, is designed to
allow for programs that are extremely terse, have a close relationship with the resulting object code, and yet provide
relatively high-level data abstraction. C was the first widely successful high-level language for portable operating-system
development.
Contents
Data structures
Primitive data types
Integer types
Enumerated type
Floating point types
Storage class specifiers
Type qualifiers
Incomplete types
Pointers
Referencing
Dereferencing
Arrays
Array definition
Accessing elements
Variable-length arrays
Dynamic arrays
Multidimensional arrays
Strings
Backslash escapes
String literal concatenation
Character constants
Wide character strings
Variable width strings
Library functions
Structures and unions
Structures
Unions
Declaration
Accessing members
Assignment
Other operations
Bit fields
Initialization
Designated initializers
Compound literals
https://en.wikipedia.org/wiki/C_syntax 1/27
9/21/2019 C syntax - Wikipedia
Operators
Control structures
Compound statements
Selection statements
Iteration statements
Jump statements
Storing the address of a label
Functions
Syntax
Function Pointers
Global structure
Argument passing
Array parameters
Miscellaneous
Reserved keywords
Case sensitivity
Comments
Command-line arguments
Evaluation order
Undefined behavior
See also
References
External links
Data structures
All C integer types have signed and unsigned variants. If signed or unsigned is not specified explicitly, in most
circumstances signed is assumed. However, for historic reasons plain char is a type distinct from both signed char and
unsigned char. It may be a signed type or an unsigned type, depending on the compiler and the character set (C
guarantees that members of the C basic character set have positive values). Also, bit field types specified as plain int may
be signed or unsigned, depending on the compiler.
Integer types
C's integer types come in different fixed sizes, capable of representing various ranges of numbers. The type char occupies
exactly one byte (the smallest addressable storage unit), which is typically 8 bits wide. (Although char can represent any
of C's "basic" characters, a wider type may be required for international character sets.) Most integer types have both
signed and unsigned varieties, designated by the signed and unsigned keywords. Signed integer types may use a two's
complement, ones' complement, or sign-and-magnitude representation. In many cases, there are multiple equivalent ways
to designate the type; for example, signed short int and short are synonymous.
https://en.wikipedia.org/wiki/C_syntax 2/27
9/21/2019 C syntax - Wikipedia
The representation of some types may include unused "padding" bits, which occupy storage but are not included in the
width. The following table provides a complete list of the standard integer types and their minimum allowed widths
(including any sign bit).
long long[1] 64
The char type is distinct from both signed char and unsigned char, but is guaranteed to have the same representation
as one of them. The _Bool and long long types are standardized since 1999, and may not be supported by older C
compilers. Type _Bool is usually accessed via the typedef name bool defined by the standard header stdbool.h.
In general, the widths and representation scheme implemented for any given platform are chosen based on the machine
architecture, with some consideration given to the ease of importing source code developed for other platforms. The width
of the int type varies especially widely among C implementations; it often corresponds to the most "natural" word size for
the specific platform. The standard header limits.h defines macros for the minimum and maximum representable values
of the standard integer types as implemented on any specific platform.
In addition to the standard integer types, there may be other "extended" integer types, which can be used for typedefs in
standard headers. For more precise specification of width, programmers can and should use typedefs from the standard
header stdint.h.
Integer constants may be specified in source code in several ways. Numeric values can be specified as decimal (example:
1022), octal with zero (0) as a prefix (01776), or hexadecimal with 0x (zero x) as a prefix (0x3FE). A character in single
quotes (example: 'R'), called a "character constant," represents the value of that character in the execution character set,
with type int. Except for character constants, the type of an integer constant is determined by the width required to
represent the specified value, but is always at least as wide as int. This can be overridden by appending an explicit length
and/or signedness modifier; for example, 12lu has type unsigned long. There are no negative integer constants, but the
same effect can often be obtained by using a unary negation operator "-".
Enumerated type
https://en.wikipedia.org/wiki/C_syntax 3/27
9/21/2019 C syntax - Wikipedia
The enumerated type in C, specified with the enum keyword, and often just called an "enum" (usually pronounced ee'-num
/ˌi.nʌm/ or ee'-noom /ˌi.nuːm/), is a type designed to represent values across a series of named constants. Each of the
enumerated constants has type int. Each enum type itself is compatible with char or a signed or unsigned integer type,
but each implementation defines its own rules for choosing a type.
Some compilers warn if an object with enumerated type is assigned a value that is not one of its constants. However, such
an object can be assigned any values in the range of their compatible type, and enum constants can be used anywhere an
integer is expected. For this reason, enum values are often used in place of preprocessor #define directives to create
named constants. Such constants are generally safer to use than macros, since they reside within a specific identifier
namespace.
An enumerated type is declared with the enum specifier and an optional name (or tag) for the enum, followed by a list of
one or more constants contained within curly braces and separated by commas, and an optional list of variable names.
Subsequent references to a specific enumerated type use the enum keyword and the name of the enum. By default, the first
constant in an enumeration is assigned the value zero, and each subsequent value is incremented by one over the previous
constant. Specific values may also be assigned to constants in the declaration, and any subsequent constants without
specific values will be given incremented values from that point onward. For example, consider the following declaration:
This declares the enum colors type; the int constants RED (whose value is 0), GREEN (whose value is one greater than RED,
1), BLUE (whose value is the given value, 5), and YELLOW (whose value is one greater than BLUE, 6); and the enum colors
variable paint_color. The constants may be used outside of the context of the enum (where any integer value is allowed),
and values other than the constants may be assigned to paint_color, or any other variable of type enum colors.
Floating-point types
Precision (decimal digits) Exponent range
Type specifiers
Minimum IEEE 754 Minimum IEEE 754
float 6 7.2 (24 bits) ±37 ±38 (8 bits)
double 10 15.9 (53 bits) ±37 ±307 (11 bits)
long double 10 34.0 (113 bits) ±37 ±4931 (15 bits)
Floating-point constants may be written in decimal notation, e.g. 1.23. Decimal scientific notation may be used by adding
e or E followed by a decimal exponent, also known as E notation, e.g. 1.23e2 (which has the value 1.23 × 102 = 123.0).
Either a decimal point or an exponent is required (otherwise, the number is parsed as an integer constant). Hexadecimal
floating-point constants follow similar rules, except that they must be prefixed by 0x and use p or P to specify a binary
exponent, e.g. 0xAp-2 (which has the value 2.5, since Ah × 2−2 = 10 × 2−2 = 10 ÷ 4). Both decimal and hexadecimal
floating-point constants may be suffixed by f or F to indicate a constant of type float, by l (letter l) or L to indicate type
long double, or left unsuffixed for a double constant.
https://en.wikipedia.org/wiki/C_syntax 4/27
9/21/2019 C syntax - Wikipedia
The standard header file float.h defines the minimum and maximum values of the implementation's floating-point types
float, double, and long double. It also defines other limits that are relevant to the processing of floating-point numbers.
Storage classes
Specifiers Lifetime Scope Default initializer
auto Block (stack) Block Uninitialized
Block (stack or CPU
register Block Uninitialized
register)
Block or compilation
static Program Zero
unit
Block or compilation
extern Program Zero
unit
Uninitialized (initialized to 0 if using
(none)1 Dynamic (heap)
calloc())
1 Allocated and deallocated using the malloc() and free() library functions.
Variables declared within a block by default have automatic storage, as do those explicitly declared with the auto[2] or
register storage class specifiers. The auto and register specifiers may only be used within functions and function
argument declarations; as such, the auto specifier is always redundant. Objects declared outside of all blocks and those
explicitly declared with the static storage class specifier have static storage duration. Static variables are initialized to
zero by default by the compiler.
Objects with automatic storage are local to the block in which they were declared and are discarded when the block is
exited. Additionally, objects declared with the register storage class may be given higher priority by the compiler for
access to registers; although they may not actually be stored in registers, objects with this storage class may not be used
with the address-of (&) unary operator. Objects with static storage persist for the program's entire duration. In this way,
the same object can be accessed by a function across multiple calls. Objects with allocated storage duration are created and
destroyed explicitly with malloc, free, and related functions.
The extern storage class specifier indicates that the storage for an object has been defined elsewhere. When used inside a
block, it indicates that the storage has been defined by a declaration outside of that block. When used outside of all blocks,
it indicates that the storage has been defined outside of the compilation unit. The extern storage class specifier is
redundant when used on a function declaration. It indicates that the declared function has been defined outside of the
compilation unit.
Note that storage specifiers apply only to functions and objects; other things such as type and enum declarations are
private to the compilation unit in which they appear. Types, on the other hand, have qualifiers (see below).
Type qualifiers
https://en.wikipedia.org/wiki/C_syntax 5/27
9/21/2019 C syntax - Wikipedia
Types can be qualified to indicate special properties of their data. The type qualifier const indicates that a value does not
change once it has been initialized. Attempting to modify a const qualified value yields undefined behavior, so some C
compilers store them in rodata or (for embedded systems) in read-only memory (ROM). The type qualifier volatile
indicates to an optimizing compiler that it may not remove apparently redundant reads or writes, as the value may change
even if it was not modified by any expression or statement, or multiple writes may be necessary, such as for memory-
mapped I/O.
Incomplete types
An incomplete type is a structure or union type whose members have not yet been specified, an array type whose
dimension has not yet been specified, or the void type (the void type cannot be completed). Such a type may not be
instantiated (its size is not known), nor may its members be accessed (they, too, are unknown); however, the derived
pointer type may be used (but not dereferenced).
They are often used with pointers, either as forward or external declarations. For instance, code could declare an
incomplete type like this:
This declares pt as a pointer to struct thing and the incomplete type struct thing. Pointers to data always have the
same byte-width regardless of what they point to, so this statement is valid by itself (as long as pt is not dereferenced).
The incomplete type can be completed later in the same scope by redeclaring it:
struct thing {
int num;
}; /* thing struct type is now completed */
Incomplete types are used to implement recursive structures; the body of the type declaration may be deferred to later in
the translation unit:
struct Bert {
Wilma *wilma;
};
struct Wilma {
Bert *bert;
};
Incomplete types are also used for data hiding; the incomplete type is defined in a header file, and the body only within the
relevant source file.
Pointers
In declarations the asterisk modifier (*) specifies a pointer type. For example, where the specifier int would refer to the
integer type, the specifier int* refers to the type "pointer to integer". Pointer values associate two pieces of information: a
memory address and a data type. The following line of code declares a pointer-to-integer variable called ptr:
int *ptr;
https://en.wikipedia.org/wiki/C_syntax 6/27
9/21/2019 C syntax - Wikipedia
Referencing
When a non-static pointer is declared, it has an unspecified value associated with it. The address associated with such a
pointer must be changed by assignment prior to using it. In the following example, ptr is set so that it points to the data
associated with the variable a:
int a = 0;
int *ptr = &a;
In order to accomplish this, the "address-of" operator (unary &) is used. It produces the memory location of the data object
that follows.
Dereferencing
The pointed-to data can be accessed through a pointer value. In the following example, the integer variable b is set to the
value of integer variable a, which is 10:
int a=10;
int *p = &a;
int b = *p;
In order to accomplish that task, the unary dereference operator, denoted by an asterisk (*), is used. It returns the data to
which its operand—which must be of pointer type—points. Thus, the expression *p denotes the same value as a.
Dereferencing a null pointer is illegal.
Arrays
Array definition
Arrays are used in C to represent structures of consecutive elements of the same type. The definition of a (fixed-size) array
has the following syntax:
int array[100];
which defines an array named array to hold 100 values of the primitive type int. If declared within a function, the array
dimension may also be a non-constant expression, in which case memory for the specified number of elements will be
allocated. In most contexts in later use, a mention of the variable array is converted to a pointer to the first item in the
array. The sizeof operator is an exception: sizeof array yields the size of the entire array (that is, 100 times the size of
an int, and sizeof(array) / sizeof(int) will return 100). Another exception is the & (address-of) operator, which
yields a pointer to the entire array, for example
Accessing elements
The primary facility for accessing the values of the elements of an array is the array subscript operator. To access the i-
indexed element of array, the syntax would be array[i], which refers to the value stored in that array element.
https://en.wikipedia.org/wiki/C_syntax 7/27
9/21/2019 C syntax - Wikipedia
Array subscript numbering begins at 0 (see Zero-based indexing). The largest allowed array subscript is therefore equal to
the number of elements in the array minus 1. To illustrate this, consider an array a declared as having 10 elements; the
first element would be a[0] and the last element would be a[9].
C provides no facility for automatic bounds checking for array usage. Though logically the last subscript in an array of 10
elements would be 9, subscripts 10, 11, and so forth could accidentally be specified, with undefined results.
Due to arrays and pointers being interchangeable, the addresses of each of the array elements can be expressed in
equivalent pointer arithmetic. The following table illustrates both methods for the existing array:
Since the expression a[i] is semantically equivalent to *(a+i), which in turn is equivalent to *(i+a); the expression can
also be written as i[a], although this form is rarely used.
Variable-length arrays
C99 standardised variable-length arrays (VLAs) within block scope. Such array variables are allocated based on the value
of an integer value at runtime upon entry to a block, and are deallocated at the end of the block.[3] As of C11 this feature is
no longer required to be implemented by the compiler.
int n = ...;
int a[n];
a[3] = 10;
This syntax produces an array whose size is fixed until the end of the block.
Dynamic arrays
Arrays that can be resized dynamically can be produced with the help of the C standard library. The malloc function
provides a simple method for allocating memory. It takes one parameter: the amount of memory to allocate in bytes. Upon
successful allocation, malloc returns a generic (void) pointer value, pointing to the beginning of the allocated space. The
pointer value returned is converted to an appropriate type implicitly by assignment. If the allocation could not be
completed, malloc returns a null pointer. The following segment is therefore similar in function to the above desired
declaration:
The result is a "pointer to int" variable (a) that points to the first of n contiguous int objects; due to array–pointer
equivalence this can be used in place of an actual array name, as shown in the last line. The advantage in using this
dynamic allocation is that the amount of memory that is allocated to it can be limited to what is actually needed at run
time, and this can be changed as needed (using the standard library function realloc).
https://en.wikipedia.org/wiki/C_syntax 8/27
9/21/2019 C syntax - Wikipedia
When the dynamically-allocated memory is no longer needed, it should be released back to the run-time system. This is
done with a call to the free function. It takes a single parameter: a pointer to previously allocated memory. This is the
value that was returned by a previous call to malloc.
As a security measure, some programmers then set the pointer variable to NULL:
free(a);
a = NULL;
This ensures that further attempts to dereference the pointer will crash the program. If this is not done, the variable
becomes a dangling pointer which can lead to a use-after-free bug. However, if the pointer is a local variable, setting it to
NULL does not prevent the program from using other copies of the pointer. Local use-after-free bugs are usually easy for
static analyzers to recognize. Therefore, this approach is less useful for local pointers and it is more often used with
pointers stored in long-living structs. In general though, setting pointers to NULL is good practice as it allows a
programmer is NULL-check pointers prior to dereferencing, thus helping prevent crashes.
Recalling the array example, one could also create a fixed-size array through dynamic allocation:
(*a)[index];
index[*a];
The benefit to using the second example is that the numeric limit of the first example isn't required, which means that the
pointer-to-array could be of any size and the second example can execute without any modifications.
Multidimensional arrays
In addition, C supports arrays of multiple dimensions, which are stored in row-major order. Technically, C
multidimensional arrays are just one-dimensional arrays whose elements are arrays. The syntax for declaring
multidimensional arrays is as follows:
int array2d[ROWS][COLUMNS];
where ROWS and COLUMNS are constants. This defines a two-dimensional array. Reading the subscripts from left to
right, array2d is an array of length ROWS, each element of which is an array of COLUMNS integers.
https://en.wikipedia.org/wiki/C_syntax 9/27
9/21/2019 C syntax - Wikipedia
array2d[4][3]
Again, reading from left to right, this accesses the 5th row, and the 4th element in that row. The expression array2d[4] is
an array, which we are then subscripting with [3] to access the fourth integer.
A multidimensional array should not be confused with an array of references to arrays (also known as an Iliffe vectors or
sometimes an array of arrays). The former is always rectangular (all subarrays must be the same size), and occupies a
contiguous region of memory. The latter is a one-dimensional array of pointers, each of which may point to the first
element of a subarray in a different place in memory, and the sub-arrays do not have to be the same size. The latter can be
created by multiple uses of malloc.
Strings
In C, string literals are surrounded by double quotes ("), e.g. "Hello world!" and are compiled to an array of the
specified char values with an additional null terminating character (0-valued) code to mark the end of the string.
String literals may not contain embedded newlines; this proscription somewhat simplifies parsing of the language. To
include a newline in a string, the backslash escape \n may be used, as below.
There are several standard library functions for operating with string data (not necessarily constant) organized as array of
char using this null-terminated format; see below.
C's string-literal syntax has been very influential, and has made its way into many other languages, such as C++,
Objective-C, Perl, Python, PHP, Java, Javascript, C#, Ruby. Nowadays, almost all new languages adopt or build upon C-
style string syntax. Languages that lack this syntax tend to precede C.
Backslash escapes
If you wish to include a double quote inside the string, that can be done by escaping it with a backslash (\), for example,
"This string contains \"double quotes\".". To insert a literal backslash, one must double it, e.g. "A backslash
looks like this: \\".
https://en.wikipedia.org/wiki/C_syntax 10/27
9/21/2019 C syntax - Wikipedia
Escape Meaning
\\ Literal backslash
\" Double quote
\' Single quote
\n Newline (line feed)
\r Carriage return
\b Backspace
\t Horizontal tab
\f Form feed
\a Alert (bell)
\v Vertical tab
\? Question mark (used to escape trigraphs)
%% Percentage mark, printf format strings only (Note \% is non standard and is not always recognised)
\OOO Character with octal value OOO (where OOO is 1-3 octal digits, '0'-'7')
\xHH Character with hexadecimal value HH (where HH is 1 or more hex digits, '0'-'9','A'-'F','a'-'f')
The use of other backslash escapes is not defined by the C standard, although compiler vendors often provide additional
escape codes as language extensions.
will expand to
Character constants
Individual character constants are single-quoted, e.g. 'A', and have type int (in C++, char). The difference is that "A"
represents a null-terminated array of two characters, 'A' and '\0', whereas 'A' directly represents the character value (65 if
ASCII is used). The same backslash-escapes are supported as for strings, except that (of course) " can validly be used as a
character without being escaped, whereas ' must now be escaped.
https://en.wikipedia.org/wiki/C_syntax 11/27
9/21/2019 C syntax - Wikipedia
A character constant cannot be empty (i.e. '' is invalid syntax), although a string may be (it still has the null terminating
character). Multi-character constants (e.g. 'xy') are valid, although rarely useful — they let one store several characters in
an integer (e.g. 4 ASCII characters can fit in a 32-bit integer, 8 in a 64-bit one). Since the order in which the characters are
packed into an int is not specified, portable use of multi-character constants is difficult.
Wide characters are most commonly either 2 bytes (using a 2-byte encoding such as UTF-16) or 4 bytes (usually UTF-32),
but Standard C does not specify the width for wchar_t, leaving the choice to the implementor. Microsoft Windows
generally uses UTF-16, thus the above string would be 26 bytes long for a Microsoft compiler; the Unix world prefers UTF-
32, thus compilers such as GCC would generate a 52-byte string. A 2-byte wide wchar_t suffers the same limitation as
char, in that certain characters (those outside the BMP) cannot be represented in a single wchar_t; but must be
represented using surrogate pair
The original C standard specified only minimal functions for operating with wide character strings; in 1995 the standard
was modified to include much more extensive support, comparable to that for char strings. The relevant functions are
mostly named after their char equivalents, with the addition of a "w" or the replacement of "str" with "wcs"; they are
specified in <wchar.h>, with <wctype.h> containing wide-character classification and mapping functions.
The now generally recommended method[5] of supporting international characters is through UTF-8, which is stored in
char arrays, and can be written directly in the source code if using a UTF-8 editor, because UTF-8 is a direct ASCII
extension.
Library functions
Strings, both constant and variable, can be manipulated without using the standard library. However, the library contains
many useful functions for working with null-terminated strings.
Structures
https://en.wikipedia.org/wiki/C_syntax 12/27
9/21/2019 C syntax - Wikipedia
Structures and unions in C are defined as data containers consisting of a sequence of named members of various types.
They are similar to records in other programming languages. The members of a structure are stored in consecutive
locations in memory, although the compiler is allowed to insert padding between or after members (but not before the
first member) for efficiency or as padding required for proper alignment by the target architecture. The size of a structure
is equal to the sum of the sizes of its members, plus the size of the padding.
Unions
Unions in C are related to structures and are defined as objects that may hold (at different times) objects of different types
and sizes. They are analogous to variant records in other programming languages. Unlike structures, the components of a
union all refer to the same location in memory. In this way, a union can be used at various times to hold different types of
objects, without the need to create a separate object for each new type. The size of a union is equal to the size of its largest
component type.
Declaration
Structures are declared with the struct keyword and unions are declared with the union keyword. The specifier keyword
is followed by an optional identifier name, which is used to identify the form of the structure or union. The identifier is
followed by the declaration of the structure or union's body: a list of member declarations, contained within curly braces,
with each declaration terminated by a semicolon. Finally, the declaration concludes with an optional list of identifier
names, which are declared as instances of the structure or union.
For example, the following statement declares a structure named s that contains three members; it will also declare an
instance of the structure known as tee:
struct s {
int x;
float y;
char *z;
} tee;
And the following statement will declare a similar union named u and an instance of it named n:
union u {
int x;
float y;
char *z;
} n;
Members of structures and unions cannot have an incomplete or function type. Thus members cannot be an instance of
the structure or union being declared (because it is incomplete at that point) but can be pointers to the type being
declared.
Once a structure or union body has been declared and given a name, it can be considered a new data type using the
specifier struct or union, as appropriate, and the name. For example, the following statement, given the above structure
declaration, declares a new instance of the structure s named r:
struct s r;
https://en.wikipedia.org/wiki/C_syntax 13/27
9/21/2019 C syntax - Wikipedia
It is also common to use the typedef specifier to eliminate the need for the struct or union keyword in later references
to the structure. The first identifier after the body of the structure is taken as the new name for the structure type
(structure instances may not be declared in this context). For example, the following statement will declare a new type
known as s_type that will contain some structure:
Future statements can then use the specifier s_type (instead of the expanded struct ... specifier) to refer to the structure.
Accessing members
Members are accessed using the name of the instance of a structure or union, a period (.), and the name of the member.
For example, given the declaration of tee from above, the member known as y (of type float) can be accessed using the
following syntax:
tee.y
Structures are commonly accessed through pointers. Consider the following example that defines a pointer to tee, known
as ptr_to_tee:
Member y of tee can then be accessed by dereferencing ptr_to_tee and using the result as the left operand:
(*ptr_to_tee).y
Which is identical to the simpler tee.y above as long as ptr_to_tee points to tee. Due to operator precedence ("." being
higher than "*"), the shorter *ptr_to_tee.y is incorrect for this purpose, instead being parsed as *(ptr_to_tee.y) and
thus the parentheses are necessary. Because this operation is common, C provides an abbreviated syntax for accessing a
member directly from a pointer. With this syntax, the name of the instance is replaced with the name of the pointer and
the period is replaced with the character sequence ->. Thus, the following method of accessing y is identical to the
previous two:
ptr_to_tee->y
This can be chained; for example, in a linked list, one may refer to n->next->next for the second following node
(assuming that n->next is not null).
Assignment
Assigning values to individual members of structures and unions is syntactically identical to assigning values to any other
object. The only difference is that the lvalue of the assignment is the name of the member, as accessed by the syntax
mentioned above.
A structure can also be assigned as a unit to another structure of the same type. Structures (and pointers to structures)
may also be used as function parameter and return types.
https://en.wikipedia.org/wiki/C_syntax 14/27
9/21/2019 C syntax - Wikipedia
For example, the following statement assigns the value of 74 (the ASCII code point for the letter 't') to the member named
x in the structure tee, from above:
tee.x = 74;
And the same assignment, using ptr_to_tee in place of tee, would look like:
ptr_to_tee->x = 74;
Other operations
According to the C standard, the only legal operations that can be performed on a structure are copying it, assigning to it
as a unit (or initializing it), taking its address with the address-of (&) unary operator, and accessing its members. Unions
have the same restrictions. One of the operations implicitly forbidden is comparison: structures and unions cannot be
compared using C's standard comparison facilities (==, >, <, etc.).
Bit fields
C also provides a special type of structure member known as a bit field, which is an integer with an explicitly specified
number of bits. A bit field is declared as a structure member of type int, signed int, unsigned int, or _Bool, following
the member name by a colon (:) and the number of bits it should occupy. The total number of bits in a single bit field must
not exceed the total number of bits in its declared type.
As a special exception to the usual C syntax rules, it is implementation-defined whether a bit field declared as type int,
without specifying signed or unsigned, is signed or unsigned. Thus, it is recommended to explicitly specify signed or
unsigned on all structure members for portability.
Unnamed fields consisting of just a colon followed by a number of bits are also allowed; these indicate padding. Specifying
a width of zero for an unnamed field is used to force alignment to a new word.[6]
The members of bit fields do not have addresses, and as such cannot be used with the address-of (&) unary operator. The
sizeof operator may not be applied to bit fields.
The following declaration declares a new structure type known as f and an instance of it known as g. Comments provide a
description of each of the members:
struct f {
unsigned int flag : 1; /* a bit flag: can either be on (1) or off (0) */
signed int num : 4; /* a signed 4-bit field; range -7...7 or -8...7 */
signed int : 3; /* 3 bits of padding to round out to 8 bits */
} g;
Initialization
Default initialization depends on the storage class specifier, described above.
Because of the language's grammar, a scalar initializer may be enclosed in any number of curly brace pairs. Most
compilers issue a warning if there is more than one such pair, though.
https://en.wikipedia.org/wiki/C_syntax 15/27
9/21/2019 C syntax - Wikipedia
int x = 12;
int y = { 23 }; //Legal, no warning
int z = { { 34 } }; //Legal, expect a warning
Structures, unions and arrays can be initialized in their declarations using an initializer list. Unless designators are used,
the components of an initializer correspond with the elements in the order they are defined and stored, thus all preceding
values must be provided before any particular element's value. Any unspecified elements are set to zero (except for
unions). Mentioning too many initialization values yields an error.
The following statement will initialize a new instance of the structure s known as pi:
struct s {
int x;
float y;
char *z;
};
Designated initializers
Designated initializers allow members to be initialized by name, in any order, and without explicitly providing the
preceding values. The following initialization is equivalent to the previous one:
Using a designator in an initializer moves the initialization "cursor". In the example below, if MAX is greater than 10, there
will be some zero-valued elements in the middle of a; if it is less than 10, some of the values provided by the first five
initializers will be overridden by the second five (if MAX is less than 5, there will be a compilation error):
In C89, a union was initialized with a single value applied to its first member. That is, the union u defined above could
only have its int x member initialized:
union u value = { 3 };
Using a designated initializer, the member to be initialized does not have to be the first member:
If an array has unknown size (i.e. the array was an incomplete type), the number of initializers determines the size of the
array and its type becomes complete:
int x[] = { 0, 1, 2 } ;
Compound designators can be used to provide explicit initialization when unadorned initializer lists might be
misunderstood. In the example below, w is declared as an array of structures, each structure consisting of a member a (an
array of 3 int) and a member b (an int). The initializer sets the size of w to 2 and sets the values of the first element of
each a:
https://en.wikipedia.org/wiki/C_syntax 16/27
9/21/2019 C syntax - Wikipedia
Compound literals
It is possible to borrow the initialization methodology to generate compound structure and array literals:
// pointer to array.
float (*foo)[3] = &(float[]){ 0.5f, 1.f, -0.5f };
Compound literals are often combined with designated initializers to make the declaration more readable:[3]
Operators
Control structures
C is a free-form language.
Bracing style varies from programmer to programmer and can be the subject of debate. See Indent style for more details.
Compound statements
In the items in this section, any <statement> can be replaced with a compound statement. Compound statements have
the form:
{
<optional-declaration-list>
<optional-statement-list>
}
and are used as the body of a function or anywhere that a single statement is expected. The declaration-list declares
variables to be used in that scope, and the statement-list are the actions to be performed. Brackets define their own scope,
and variables defined inside those brackets will be automatically deallocated at the closing bracket. Declarations and
statements can be freely intermixed within a compound statement (as in C++).
https://en.wikipedia.org/wiki/C_syntax 17/27
9/21/2019 C syntax - Wikipedia
Selection statements
C has two types of selection statements: the if statement and the switch statement.
if (<expression>)
<statement1>
else
<statement2>
In the if statement, if the <expression> in parentheses is nonzero (true), control passes to <statement1>. If the else
clause is present and the <expression> is zero (false), control will pass to <statement2>. The else <statement2> part
is optional and, if absent, a false <expression> will simply result in skipping over the <statement1>. An else always
matches the nearest previous unmatched if; braces may be used to override this when necessary, or for clarity.
The switch statement causes control to be transferred to one of several statements depending on the value of an
expression, which must have integral type. The substatement controlled by a switch is typically compound. Any statement
within the substatement may be labeled with one or more case labels, which consist of the keyword case followed by a
constant expression and then a colon (:). The syntax is as follows:
switch (<expression>)
{
case <label1> :
<statements 1>
case <label2> :
<statements 2>
break;
default :
<statements 3>
}
No two of the case constants associated with the same switch may have the same value. There may be at most one default
label associated with a switch. If none of the case labels are equal to the expression in the parentheses following switch,
control passes to the default label or, if there is no default label, execution resumes just beyond the entire construct.
Switches may be nested; a case or default label is associated with the innermost switch that contains it. Switch
statements can "fall through", that is, when one case section has completed its execution, statements will continue to be
executed downward until a break; statement is encountered. Fall-through is useful in some circumstances, but is usually
not desired. In the preceding example, if <label2> is reached, the statements <statements 2> are executed and nothing
more inside the braces. However, if <label1> is reached, both <statements 1> and <statements 2> are executed since
there is no break to separate the two case statements.
It is possible, although unusual, to insert the switch labels into the sub-blocks of other control structures. Examples of
this include Duff's device and Simon Tatham's implementation of coroutines in Putty.[7]
Iteration statements
C has three forms of iteration statement:
do
<statement>
while ( <expression> ) ;
while ( <expression> )
https://en.wikipedia.org/wiki/C_syntax 18/27
9/21/2019 C syntax - Wikipedia
<statement>
In the while and do statements, the sub-statement is executed repeatedly so long as the value of the expression remains
non-zero (equivalent to true). With while, the test, including all side effects from <expression>, occurs before each
iteration (execution of <statement>); with do, the test occurs after each iteration. Thus, a do statement always executes
its sub-statement at least once, whereas while may not execute the sub-statement at all.
The statement:
is equivalent to:
e1;
while (e2)
{
s;
cont:
e3;
}
except for the behaviour of a continue; statement (which in the for loop jumps to e3 instead of e2). If e2 is blank, it
would have to be replaced with a 1.
Any of the three expressions in the for loop may be omitted. A missing second expression makes the while test always
non-zero, creating a potentially infinite loop.
Since C99, the first expression may take the form of a declaration, typically including an initializer, such as:
Jump statements
Jump statements transfer control unconditionally. There are four types of jump statements in C: goto, continue, break,
and return.
goto <identifier> ;
The identifier must be a label (followed by a colon) located in the current function. Control transfers to the labeled
statement.
A continue statement may appear only within an iteration statement and causes control to pass to the loop-continuation
portion of the innermost enclosing iteration statement. That is, within each of the statements
https://en.wikipedia.org/wiki/C_syntax 19/27
9/21/2019 C syntax - Wikipedia
while (expression)
{
/* ... */
cont: ;
}
do
{
/* ... */
cont: ;
} while (expression);
a continue not contained within a nested iteration statement is the same as goto cont.
The break statement is used to end a for loop, while loop, do loop, or switch statement. Control passes to the statement
following the terminated statement.
A function returns to its caller by the return statement. When return is followed by an expression, the value is returned
to the caller as the value of the function. Encountering the end of the function is equivalent to a return with no
expression. In that case, if the function is declared as returning a value and the caller tries to use the returned value, the
result is undefined.
Functions
Syntax
A C function definition consists of a return type (void if no value is returned), a unique name, a list of parameters in
parentheses, and various statements:
https://en.wikipedia.org/wiki/C_syntax 20/27
9/21/2019 C syntax - Wikipedia
A function with non-void return type should include at least one return statement. The parameters are given by the
<parameter-list>, a comma-separated list of parameter declarations, each item in the list being a data type followed by
an identifier: <data-type> <variable-identifier>, <data-type> <variable-identifier>, ....
If there are no parameters, the <parameter-list> may be left empty or optionally be specified with the single word void.
It is possible to define a function as taking a variable number of parameters by providing the ... keyword as the last
parameter instead of a data type and variable identifier. A commonly used function that does this is the standard library
function printf, which has the declaration:
Manipulation of these parameters can be done by using the routines in the standard library header <stdarg.h>.
Function Pointers
A pointer to a function can be declared as follows:
<return-type> (*<function-name>)(<parameter-list>);
The following program shows use of a function pointer for selecting between addition and subtraction:
#include <stdio.h>
operation = add;
printf("%d + %d = %d\n", foo, bar, operation(foo, bar));
operation = subtract;
printf("%d - %d = %d\n", foo, bar, operation(foo, bar));
return 0;
}
Global structure
After preprocessing, at the highest level a C program consists of a sequence of declarations at file scope. These may be
partitioned into several separate source files, which may be compiled separately; the resulting object modules are then
linked along with implementation-provided run-time support modules to produce an executable image.
The declarations introduce functions, variables and types. C functions are akin to the subroutines of Fortran or the
procedures of Pascal.
https://en.wikipedia.org/wiki/C_syntax 21/27
9/21/2019 C syntax - Wikipedia
A definition is a special type of declaration. A variable definition sets aside storage and possibly initializes it, a function
definition provides its body.
An implementation of C providing all of the standard library functions is called a hosted implementation. Programs
written for hosted implementations are required to define a special function called main, which is the first function called
when a program begins executing.
Hosted implementations start program execution by invoking the main function, which must be defined following one of
these prototypes:
The first two definitions are equivalent (and both are compatible with C++). It is probably up to individual preference
which one is used (the current C standard contains two examples of main() and two of main(void), but the draft C++
standard uses main()). The return value of main (which should be int) serves as termination status returned to the host
environment.
The C standard defines return values 0 and EXIT_SUCCESS as indicating success and EXIT_FAILURE as indicating failure.
(EXIT_SUCCESS and EXIT_FAILURE are defined in <stdlib.h>). Other return values have implementation-defined
meanings; for example, under Linux a program killed by a signal yields a return code of the numerical value of the signal
plus 128.
A minimal correct C program consists of an empty main routine, taking no arguments and doing nothing:
int main(void){}
Because no return statement is present, main returns 0 on exit.[3] (This is a special-case feature introduced in C99 that
applies only to main.)
The main function will usually call other functions to help it perform its job.
Some implementations are not hosted, usually because they are not intended to be used with an operating system. Such
implementations are called free-standing in the C standard. A free-standing implementation is free to specify how it
handles program startup; in particular it need not require a program to define a main function.
Functions may be written by the programmer or provided by existing libraries. Interfaces for the latter are usually
declared by including header files—with the #include preprocessing directive—and the library objects are linked into the
final executable image. Certain library functions, such as printf, are defined by the C standard; these are referred to as
the standard library functions.
A function may return a value to caller (usually another C function, or the hosting environment for the function main). The
printf function mentioned above returns how many characters were printed, but this value is often ignored.
Argument passing
In C, arguments are passed to functions by value while other languages may pass variables by reference. This means that
the receiving function gets copies of the values and has no direct way of altering the original variables. For a function to
alter a variable passed from another function, the caller must pass its address (a pointer to it), which can then be
https://en.wikipedia.org/wiki/C_syntax 22/27
9/21/2019 C syntax - Wikipedia
int main(void)
{
int x = 0;
incInt(&x); // pass a reference to the var 'x'
return 0;
}
int x;
scanf("%d", &x);
In order to pass an editable pointer to a function (such as for the purpose of returning an allocated array to the calling
code) you have to pass a pointer to that pointer: its address.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int * a; /* create a pointer to one or more ints, this will be the array */
/* 'a' is now an array of length 42 and can be manipulated and freed here */
free(a);
return 0;
}
The parameter int **a_p is a pointer to a pointer to an int, which is the address of the pointer p defined in the main
function in this case.
Array parameters
Function parameters of array type may at first glance appear to be an exception to C's pass-by-value rule. The following
program will print 2, not 1:
#include <stdio.h>
int main(void)
{
int a[1] = {1};
https://en.wikipedia.org/wiki/C_syntax 23/27
9/21/2019 C syntax - Wikipedia
setArray(a, 0, 2);
printf ("a[0]=%d\n", a[0]);
return 0;
}
However, there is a different reason for this behavior. In fact, a function parameter declared with an array type is treated
like one declared to be a pointer. That is, the preceding declaration of setArray is equivalent to the following:
At the same time, C rules for the use of arrays in expressions cause the value of a in the call to setArray to be converted to
a pointer to the first element of array a. Thus, in fact this is still an example of pass-by-value, with the caveat that it is the
address of the first element of the array being passed by value, not the contents of the array.
Miscellaneous
Reserved keywords
The following words are reserved, and may not be used as identifiers:
Implementations may reserve other keywords, such as asm, although implementations typically provide non-standard
keywords that begin with one or two underscores.
Case sensitivity
C identifiers are case sensitive (e.g., foo, FOO, and Foo are the names of different objects). Some linkers may map external
identifiers to a single case, although this is uncommon in most modern linkers.
Comments
Text starting with the token /* is treated as a comment and ignored. The comment ends at the next */; it can occur within
expressions, and can span multiple lines. Accidental omission of the comment terminator is problematic in that the next
comment's properly constructed comment terminator will be used to terminate the initial comment, and all code in
between the comments will be considered as a comment. C-style comments do not nest; that is, accidentally placing a
comment within a comment has unintended results:
https://en.wikipedia.org/wiki/C_syntax 24/27
9/21/2019 C syntax - Wikipedia
1 /*
This line will be ignored.
2 3 /*
4 A compiler warning may be produced here. These lines will also be ignored.
5 The comment opening token above did not start a new comment,
6 and the comment closing token below will close the comment begun on line 1.
7 */
8 This line and the line below it will not be ignored. Both will likely produce compile errors.
9 */
C++ style line comments start with // and extend to the end of the line. This style of comment originated in BCPL and
became valid C syntax in C99; it is not available in the original K&R C nor in ANSI C:
/* these lines
will be ignored
by the compiler */
Command-line arguments
The parameters given on a command line are passed to a C program with two predefined variables - the count of the
command-line arguments in argc and the individual arguments as character strings in the pointer array argv. So the
command:
myFilt p1 p2 p3
m y F i l t \0 p 1 \0 p 2 \0 p 3 \0
argv[0] argv[1] argv[2] argv[3]
While individual strings are arrays of contiguous characters, there is no guarantee that the strings are stored as a
contiguous group.
The name of the program, argv[0], may be useful when printing diagnostic messages or for making one binary serve
multiple purposes. The individual values of the parameters may be accessed with argv[1], argv[2], and argv[3], as
shown in the following program:
#include <stdio.h>
Evaluation order
In any reasonably complex expression, there arises a choice as to the order in which to evaluate the parts of the
expression: (1+1)+(3+3) may be evaluated in the order (1+1)+(3+3), (2)+(3+3), (2)+(6), (8), or in the order (1+1)+
(3+3), (1+1)+(6), (2)+(6), (8). Formally, a conforming C compiler may evaluate expressions in any order between
https://en.wikipedia.org/wiki/C_syntax 25/27
9/21/2019 C syntax - Wikipedia
sequence points (this allows the compiler to do some optimization). Sequence points are defined by:
The arguments to a function call may be evaluated in any order, as long as they are all evaluated by the time the function is
entered. The following expression, for example, has undefined behavior:
Undefined behavior
An aspect of the C standard (not unique to C) is that the behavior of certain code is said to be "undefined". In practice, this
means that the program produced from this code can do anything, from working as the programmer intended, to crashing
every time it is run.
For example, the following code produces undefined behavior, because the variable b is modified more than once with no
intervening sequence point:
#include <stdio.h>
int main(void)
{
int b = 1;
int a = b++ + b++;
printf("%d\n", a);
}
Because there is no sequence point between the modifications of b in "b++ + b++", it is possible to perform the evaluation
steps in more than one order, resulting in an ambiguous statement. This can be fixed by rewriting the code to insert a
sequence point in order to enforce an unambiguous behavior, for example:
a = b++;
a += b++;
See also
Blocks (C language extension)
C programming language
C variable types and declarations
Operators in C and C++
https://en.wikipedia.org/wiki/C_syntax 26/27
9/21/2019 C syntax - Wikipedia
C standard library
List of C-family programming languages (C-influenced languages)
References
1. The long long modifier was introduced in the C99 standard.
2. The meaning of auto is a type specifier rather than a storage class specifier in C++0x
3. Klemens, Ben (2012). 21st Century C. O'Reilly Media. ISBN 1449327141.
4. Balagurusamy, E. Programming in ANSI C. Tata McGraw Hill. p. 366.
5. see UTF-8 first section for references
6. Kernighan & Richie
7. Tatham, Simon (2000). "Coroutines in C" (http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html). Retrieved
2017-04-30.
General
Kernighan, Brian W.; Ritchie, Dennis M. (1988). The C Programming Language (2nd ed.). Upper Saddle River, New
Jersey: Prentice Hall PTR. ISBN 0-13-110370-9.
American National Standard for Information Systems - Programming Language - C - ANSI X3.159-1989
External links
The syntax of C in Backus-Naur form (http://www.cs.man.ac.uk/~pjj/bnf/c_syntax.bnf)
Programming in C (http://www.cs.cf.ac.uk/Dave/C/CE.html)
The comp.lang.c Frequently Asked Questions Page (http://c-faq.com/)
Text is available under the Creative Commons Attribution-ShareAlike License; additional terms may apply. By using this
site, you agree to the Terms of Use and Privacy Policy. Wikipedia® is a registered trademark of the Wikimedia
Foundation, Inc., a non-profit organization.
https://en.wikipedia.org/wiki/C_syntax 27/27