C Variable Types and Declarations

You might also like

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 10

C variable types and declarations

From Wikipedia, the free encyclopedia


Jump to: navigation, search

The C programming language has an extensive system for declaring variables of different
types. The rules for the more complex types can be confusing at times, due to the decisions taken
over their design. The principal decision is that the declaration of a variable should be similar,
syntactically, to its use (declaration reflects use). This article presents a collection of variable
declarations, starting at simple types, and proceeding to more complex types. No attempt is made
to present code which actually uses the variables declared.

Contents
[hide]

 1 Basic types
o 1.1 Signedness
o 1.2 Size
o 1.3 Type qualifiers
 2 Pointer types
o 2.1 Pointers to pointers
 3 Arrays
o 3.1 Arrays of arrays
o 3.2 Arrays of pointers
o 3.3 Pointers to arrays
o 3.4 Arrays are pointers
 4 Functions
 5 See also

[edit] Basic types


There are four basic types of variable in C; they are: char, int, double, and float.

Type
Meaning
name
char
The most basic unit addressable by the machine; typically a single octet(one byte).
This is an integral type.
int
The most natural size of integer for the machine; typically a whole 16, 32 or 64-bit(2,
4, or 8 bytes respectively) addressable word.
float A single-precision floating point value.
double A double-precision floating point value.

To declare a variable of any of these basic types, the name of the type is given first, then the
name of the new variable second.

char red;
int i;

Various qualifiers can be placed on these basic types, in order to further describe their type.

[edit] Signedness
unsigned int x;
signed int y;
int z; /* Same as "signed int" */
unsigned char grey;
signed char white;

If signed, the most significant bit designates a positive or negative value leaving the remaining
bits to be used to hold a designated value. Unsigned integers can only take non-negative values
(positive or zero), while signed integers (default) can take both positive and negative values. The
advantage of unsigned integers is to allow a greater range of positive values (e.g., 0 → +65535
depending on the size of the integer), whereas signed integers allow only up to half the same
number as positive integers and the other half as negative integers (e.g., −32768 → +32767).

An unsigned character, depending on the code page, might access an extended range of
characters from 0 → +255, instead of that accessible by a signed char from −128 → +127, or it
might simply be used as a small integer. The standard requires char, signed char, unsigned
char to be different types. Since most standardized string functions take pointers to plain char,
many C compilers correctly complain if one of the other character types is used for strings
passed to these functions.

[edit] Size

The int type can also be given a size qualifier, to specify more precisely the range of values
(and memory size requirements) of the value stored.

short int yellow;


long int orange;
long long int red;

When declaring a short int or long int, it is permissible to omit the int, as this is implied.
The following two declarations are equivalent.

long int brown;


long brown;
Novice C programmers may be confused as to how big these types are. The standard is
specifically vague in this area:

 sizeof(short int) ≤ sizeof(int) ≤ sizeof(long int)


 short int must be at least 16 bits long.
 long int must be at least 32 bits long.
 long long int must be at least 64 bits long.

The standard does not require that any of these sizes be necessarily different. It is perfectly valid,
for example, if all four types are 64 bits long. In order to allow a simple and concise description
of the sizes a compiler will apply to each of the four types (and the size of a pointer type; see
below), a simple naming scheme has been devised; see 64-Bit Programming Models. Two
popular schemes are ILP32, in which int, long int and pointer types are 32 bits long; and
LP64, in which long int and pointers are 64 bits, and int are 32 bits. Most implementations
under these schemes use 16-bit short ints.

A double variable can be marked as being a long double, which the compiler may use to select
a larger floating point representation than a plain double. Again, the standard is unspecific on
the relative sizes of the floating point values, and only requires a float not to be larger than a
double, which should not be larger than a long double.

[edit] Type qualifiers

To help promote safety in programs, values can be marked as being constant with the const type
qualifier. Compilers must diagnose, usually with an error, attempts to modify such variables.
Since const variables cannot be assigned to, they must be initialized at the point of declaration.

The C standard permits arbitrary ordering of type qualifiers, such as const, and type specifiers,
such as int. Both of the following declarations are therefore equivalent:

int const black = 12;


const int black = 12;

While the former more closely reflects the use of const marking when used in pointer types, the
latter form is more natural and almost ubiquitous.

[edit] Pointer types


Variables can be declared as being pointers to values of various types, by means of the * type
declarator. To declare a variable as a pointer, immediately precede its name with an asterisk.

char *square;
long *circle;

K&R gives a good explanation for the slightly odd use of asterisks in this way, as well as a
motivation for why they attach the asterisk onto the name of the variable, when it might seem to
make more sense being attached to the name of the type. This is, that when the program
dereferences the pointer, it has the type of the object to which it points. In this case, *circle is a
value of type long. While this may be a subtle point to raise in this case, it starts to show its
worth when more complex types are used. This is the reason for C's slightly odd way of
declaring more complex types, when the name of the actual variable gets hidden within the type
declaration, as further examples will show. However, the standard also allows you to attach the
asterisk to the name of the type such as long* circle. This form is usually discouraged since it
can confuse the novice when multiple pointers are declared on the same line:

long* first, second; // Discouraged usage

will result in first being a pointer to a long, but second being a long itself, which is likely not
what a beginner expects.

There is a special type of value which cannot be directly used as a variable type, but only as
pointed type in the case of pointer declarations.

void *triangle;

The pointed value here cannot be used directly; attempts to dereference this pointer will result in
a compiler error. The utility here is that this is a generic pointer; useful when the pointed type
does not matter, simply the pointer address is needed. It is usually used to store pointers in utility
types, such as linked lists, or hash tables, where the code using the utility will typecast it to a
pointer of some specific type (moreover, this casting may be implicit, meaning that the cast
operator isn't needed when the new type is obvious, for example in variable assignments).

The pointed type can take all of the usual markings given above; the following are all valid
pointer declarations.

long int *rectangle;


unsigned short int *rhombus;
const char *kite;

Note specifically the use of const in this last case. Here, kite is a (non-const) pointer to a
const char. The value of kite itself is not a constant, only the value of the char to which it
points. The placement of const before the type, as noted above, gives motivation for the way a
constant pointer is declared. As it is constant, it must be initialised when it is declared.

char * const pentagon = &some_char;

Here, pentagon is a constant pointer, which points at a char. The value at which it points is not
a constant; it will not be an error to modify the pointed character; only to modify the pointer
itself. It is also possible to declare both the pointer and the pointed value as being constant. The
following two declarations are equivalent.

char const * const hexagon = &some_char;


const char * const hexagon = &some_char;
[edit] Pointers to pointers

Because, for example, char * is itself a type, pointer variables can be declared which point at
values of such a type. These are pointers to pointers.

char **septagon;

As before, the usual type qualifiers and const marking can be applied.

unsigned long const int * const *octagon;

This declares octagon as a pointer to a constant pointer to a constant unsigned long integer.
Pointer types can be arbitrarily nested below this, but with each level of indirection their use is
increasingly harder to think clearly about. Any code using more than two levels of pointer
probably requires a redesign, in terms of struct pointers, or the use of the typedef keyword.

See also Three Star Programmer at the WikiWikiWeb.

[edit] Arrays
An array is a collection of values, all of the same type, stored contiguously in memory. In C,
arrays are implemented as pointers, with some syntactic sugar to simplify memory allocation.

Some C-like languages, such as Java or C#, separate their array declarations into a type followed
by a list of variable names. In these languages, an array of 10 integer values may be declared this
way:

int[10] cat; /* THIS IS NOT VALID C CODE */

However, as noted above, C's declaration syntax aims to make declarations resemble use.
Because an access into this array would look like cat[i], it is declared in a different syntax in C.

int cat[10]; /* THIS IS VALID C CODE */

[edit] Arrays of arrays

Since they are pointers, arrays can be nested. Because the array notation, using square brackets
([]), is a postfix notation, the size of the inner nested array types is given after the outer type.

double dog[5][12];

This declares that dog is an array containing 5 elements. Each element is an array of 12 double
values.

[edit] Arrays of pointers


Because the element in an array is itself a C type, arrays of pointers can be constructed.

char *mice[10];

This declares mice to be a 10 element array, where each element is a pointer to a char.

[edit] Pointers to arrays

As stated before, a bare array name (ie. without a subscription) is simply a pointer and can be
passed around as such:

double dbls[20];
...
myFunc(dbls);
...

To declare a variable as being a pointer to an array, we must make use of parentheses. This is
because in C brackets ([]) have higher precedence than the asterisk (*). So if we wish to declare a
pointer to an array, we need to supply parentheses to override this:

double (*elephant)[20];

This declares that elephant is a pointer, and the type it points at is an array of 20 double values.

To declare a pointer to an array of pointers, simply combine the notations.

int *(*crocodile)[15];

[edit] Arrays are pointers

The square-bracket array subscription notation, such as my_array[5] can be thought of as "take
element number 5 from my_array", but it is also just as valid to think of this operation as
"dereference the pointer which is equal to 'my_array + 5'". In fact, the following is perfectly
valid code:

int *start_pointer = malloc(5*sizeof(int)); // Allocate memory, giving a


pointer to the start
start_pointer[3] = 42; // Put the integer '42' in the fourth position of
the allocated memory

This shows how a pointer can be used as an array, although the memory allocation must be given
explicitly (and thus the memory must later be freed to prevent a memory leak). In a similar
fashion, dereferencing a pointer using *pointer_name can be done by asking for the "first
element of the array" (ie. treating a pointer as a 1-element array) like this pointer_name[0].
Both are valid, as long as C's precedence rules are followed.

[edit] Functions
A function is an example of a derived type. The type of each parameter to a function is ordinarily
specified, although strictly speaking it is not required for most functions. Specifying the name of
each parameter is optional in a function declaration without a function body. The following
declarations are equivalent:

long int bat(char);


long int bat(char c);

While both forms are syntactically correct, it is usually considered bad form to omit the names of
the parameters when writing function declarations in header files. These names can provide
valuable clues to readers of such files, as to their meaning and operation.

Functions can take and return pointer types using the usual notation for a pointer:

const int *ball(long int l, int i, unsigned char *s);

The special type void is useful for declaring functions which do not take any parameters at all:

char *wicket(void);

This is quite different from the empty set of parentheses used in C to declare a function without
information on its parameter types:

double umpire();

This declaration declares a function called umpire which returns a double, but says nothing
about the parameters the function takes. (In C++, however, this declaration means that umpire
takes no parameters, the same as the declaration that uses void.)

In C, functions cannot directly take other functions as parameters, or return functions as results.
However, they can take or return pointers to them. To declare that a function takes a function
pointer as an argument, use the standard notation as given above:

int crowd(char p1, int (*p2)(void));

Here, we have a function which takes two arguments. Its first argument, p1, is a plain char. Its
second argument, p2 is a pointer to a function. This pointed-to function should be given no
arguments, and will return an int.

As a special case, C implementations treat function parameters declared with a function type as
pointer-to-function types. Thus, the following declaration and the preceding declaration are
equivalent:

int crowd(char p1, int p2(void));

To declare a function returning a function pointer (a so-called functional) again requires


parentheses, to properly apply the function markings:
long int (*boundary(int height, int width))(int x, int y);

As there are two sets of argument lists, this declaration should be read carefully, as it is quite
subtle. Here, we are defining a function called boundary. This function takes two integer
parameters, height and width, and returns a function pointer. The returned pointer points at a
function that itself takes two integer parameters, x and y, and returns a long.

This type of marking can be arbitrarily extended, to make functions that return pointers to
functions that return pointers to functions, and so on, but it quickly gets very unreadable, and
prone to bugs. Use of a typedef improves readability, as shown by the following declarations
that are equivalent to the previous declaration:

typedef long int return_func(int x, int y);


return_func *boundary(int height, int width);

[edit] See also


 C syntax
 uninitialized variable
 Blocks (C language extension)

[hide]
v • d • e
C programming language
LibrariesC standard library · glibc · dietlibc · uClibc · Newlib · EGLIBC
String · Syntax · Preprocessor · Variable types and declarations ·
Features
Functions
Select descendants C++ · C++0x · Objective-C · D · C# · Vala
C and other C and C++ (Compatibility · Operators) · Comparison of Pascal and
languages C · C to Java byte-code compiler
Category
Retrieved from "http://en.wikipedia.org/wiki/C_variable_types_and_declarations"
Categories: C programming language

Personal tools

 New features
 Log in / create account

Namespaces

 Article
 Discussion

Variants
Views

 Read
 Edit
 View history

Actions

Search

Special:Search

Search

Navigation

 Main page
 Contents
 Featured content
 Current events
 Random article

Interaction

 About Wikipedia
 Community portal
 Recent changes
 Contact Wikipedia
 Donate to Wikipedia
 Help

Toolbox

 What links here


 Related changes
 Upload file
 Special pages
 Permanent link
 Cite this page

Print/export

 Create a book
 Download as PDF
 Printable version
Languages

 Tiếng Việt

 This page was last modified on 11 August 2010 at 14:39.


 Text is available under the Creative Commons Attribution-ShareAlike License;
additional terms may apply. See Terms of Use for details.
Wikipedia® is a registered trademark of the Wikimedia Foundation, Inc., a non-profit
organization.
 Contact us

 Privacy policy
 About Wikipedia
 Disclaimers

You might also like