Previous Table of Contents Next


3.2.4. Identifiers

A C programmer has fairly wide latitude in choosing names (identifiers) for variables, functions, and other entities. Furthermore, it is possible to use the same name in several contexts at once because each name is known in a particular scope and namespace. (Briefly, scope refers to the part of a program in which an identifier is known, and the existence of multiple namespaces allows names for different entities—for example, variables and user-defined data structures—to be distinguished.) Although most of the examples in the previous section were simple names like i or f1, the actual rules are as follow:

  An identifier must consist of alphabetic characters, digits, and/or underscore characters.
  An identifier must begin with an alphabetic character or underscore.
  Identifiers may be arbitrarily long, but the compiler is not required to consider more than the first 31 characters as significant.
  Case is usually significant.
  For external (i.e., “global”) identifiers, some compilers (or, more precisely, some linkers) may not consider more than the first six characters as significant, and may disregard case.
  An identifier must not match a language keyword.
  Certain patterns of identifiers (including most beginning with underscores) are reserved in certain scopes and namespaces.
  The names of standard library functions, or names reserved for possible future extensions to the standard library, may not be used for user-defined global variables or functions. (Roughly speaking, the “future extensions” names are those beginning with mem, str, is, to, or wcs, followed by a lowercase letter.)
  When the standard headers associated with library functions are included, the macro and type names defined by those headers are, of course reserved. (These names, too, include some future extension patterns, such as most macros beginning with SIG if <signal.h> is included, or most macros beginning with E if <errno.h> is included.)
  Some compilers may allow additional characters (such as $) in identifiers, but these are nonstandard extensions.

3.2.5. Array Declarations

Besides single, simple variables, it is also possible to declare arrays, which are the first example of C’s derived types. An array is indicated in a declaration by a pair of square brackets containing a constant expression that gives the desired number of elements in the array. For example,

int a[10];

declares an array a of 10 ints. All arrays in C are 0-based, so the 10 elements of the array a are numbered from 0 to 9.

In the preceding declaration, the syntax a[10] is the declarator. It contains the identifier to be declared, a, and also additional information about the variable’s type, namely that it is an array of 10 elements. This example shows that the complete type of a variable is determined by a combination of the type name appearing at the beginning of the declaration, and any additional information found in the declarator. Functions and pointers are the other two derived types in C; the declarators for those types are described in sections 3.5.2, 3.6.1, and 3.6.7.

Array dimensions must be compile-time constants; C does not directly support variable-size arrays. (The programmer can, however, easily simulate them using pointers and dynamic memory allocation; see section 3.6.6.) C does not directly support multidimensional arrays, but these too can be readily simulated by declaring arrays of arrays.

Array types are somewhat constrained in their use; in particular, it is not possible to perform operations such as assignment on entire arrays at once. (The special handling of arrays is discussed in section 3.6.5.)


Previous Table of Contents Next