home *** CD-ROM | disk | FTP | other *** search
- .ta .5i 1i 1.5i 2i 2.5i 3i
- .ul
- 8. Declarations
- .et
- Declarations are used within function definitions to specify the interpretation
- which C gives to each identifier; they do not necessarily
- reserve storage associated with the identifier.
- Declarations have the form
- .dp 2
- declaration:
- decl-specifiers declarator-list\*(op \fG;
- .ed
- The declarators in the declarator-list
- contain the identifiers being declared.
- The decl-specifiers
- consist of at most one type-specifier and at most
- one storage class specifier.
- .dp 5
- decl-specifiers:
- type-specifier
- sc-specifier
- type-specifier sc-specifier
- sc-specifier type-specifier
- .ed
- 8.1 Storage class specifiers
- .et
- The sc-specifiers are:
- .dp 4
- sc-specifier:
- .ft G
- auto
- static
- extern
- register
- .ed
- The
- .bd "auto, static,"
- and
- .bd register
- declarations also serve as definitions
- in that they cause an appropriate amount of storage to be reserved.
- In the \fGextern\fR case
- there must be an external definition (see below)
- for the given identifiers
- somewhere outside the function in which they are declared.
- .pg
- There are some severe restrictions on
- .bd register
- identifiers:
- there can be at most 3 register identifiers in any function,
- and the type of a register identifier can only be
- .bd int,
- .bd char,
- or pointer (not
- .bd float,
- .bd double,
- structure, function, or array).
- Also the address-of
- operator
- .bd &
- cannot be applied to such identifiers.
- .a
- Except for these restrictions
- (in return for which one is rewarded with faster, smaller code),
- register identifiers behave as if they
- were automatic.
- In fact implementations of C
- are free to treat
- .bd register
- as synonymous with
- .bd auto.
- .pg
- If the sc-specifier is missing from a declaration, it
- is generally taken to be \fGauto\fR.
- .ms
- 8.2 Type specifiers
- .et
- The type-specifiers are
- .dp 6
- type-specifier:
- \fGint\fR
- \fGchar\fR
- \fGfloat
- \fGdouble
- struct \fI{ type-decl-list }\fG
- struct \fIidentifier { type-decl-list }\fG
- struct \fIidentifier
- .ed
- The \fGstruct\fR specifier is discussed in \(sc8.5.
- If the type-specifier is missing from a declaration,
- it is generally taken to be \fGint\fR.
- .ms
- 8.3 Declarators
- .et
- The declarator-list appearing in a declaration
- is a comma-separated sequence of declarators.
- .dp 2
- declarator-list:
- declarator
- declarator \fG,\fI declarator-list
- .ed
- The specifiers in the declaration
- indicate the type and storage class of the objects to which the
- declarators refer.
- Declarators have the syntax:
- .dp 6
- declarator:
- identifier
- \fG\**\fI declarator
- declarator \fG( )\fI
- declarator \fG[ \fIconstant-expression\*(op \fG]
- \fG( \fIdeclarator \fG)
- .ed
- The grouping in this definition is
- the same as in expressions.
- .ms
- 8.4 Meaning of declarators
- .et
- Each declarator is taken to be
- an assertion that when a construction of
- the same form as the declarator appears in an expression,
- it yields an object of the indicated
- type and storage class.
- Each declarator contains exactly one identifier; it is this identifier that
- is declared.
- .pg
- If an unadorned identifier appears
- as a declarator, then it has the type
- indicated by the specifier heading the declaration.
- .pg
- If a declarator has the form
- .sp .7
- \** D
- .sp .7
- for D a declarator, then the
- contained identifier has the type ``pointer to .^.^.'', where
- ``^.^.^.^'' is the type which the identifier would have had
- if the declarator had been simply D.
- .pg
- If a declarator has the form
- .sp .7
- D^(^^)
- .sp .7
- then the contained identifier has the type
- ``function returning ...'', where ``^.^.^.^'' is the
- type which the identifier would have
- had if the declarator had been simply D.
- .pg
- A declarator may have the form
- .sp .7
- D[constant-expression]
- .sp .3
- or
- .sp .3
- D[^^]
- .sp .7
- In the first case the constant
- expression
- is an expression
- whose value is determinable at compile time,
- and whose type is
- .ft G
- int.
- .ft R
- in the second the constant 1 is used.
- (Constant expressions are defined precisely in \(sc15.)^^
- Such a declarator makes the contained identifier have
- type ``array.''
- If the unadorned declarator D would
- specify a non-array of type ``.^.^.'',
- then the declarator
- ``D[^i^]''
- yields a 1-dimensional array with rank \fIi\fR of objects
- of type ``.^.^.''.
- If the unadorned declarator D would
- specify an \fIn^\fR-dimensional array
- with rank
- .ft I
- i\s6\d1\u\s10^\(mu^i\s6\d2\u\s10^\(mu^.^.^.^\(mu^i\s6\dn\u\s10,
- .ft R
- then the declarator ``D[^i\s6\dn+1\u\s10^]''
- yields an (\fIn^\fR+1^)\fR^-dimensional
- array with rank
- .ft I
- i\s6\d1\u\s10^\(mu^i\s6\d2\u\s10^\(mu^.^.^.^\(mu^i\s6\dn\u\s10\
- ^\(mu^i\s6\dn+1\u\s10\fR.
- .pg
- An array may be constructed from one of the basic types, from a pointer,
- from a structure,
- or from another array (to generate a multi-dimensional array).
- .pg
- Finally, parentheses in declarators do not alter the type
- of the contained identifier
- except insofar as they alter the binding
- of the components of the declarator.
- .pg
- Not all the possibilities
- allowed by the syntax above are actually
- permitted.
- The restrictions are as follows:
- functions may not return
- arrays, structures or functions,
- although they may return pointers to such things;
- there are no arrays of functions, although
- there may be arrays of pointers to functions.
- Likewise a structure may not contain a function,
- but it may contain a pointer to a function.
- .pg
- As an example, the declaration
- .sp .7
- .bG
- int i, \**ip, f^(^^), \**fip(^^), (\**pfi)^(^^);
- .eG
- .sp .7
- declares an integer \fIi\fR,
- a pointer \fIip\fR to an integer,
- a function \fIf\fR returning an integer,
- a function \fIfip\fR returning a pointer to an integer,
- and a pointer \fIpfi\fR to a function which
- returns an integer.
- Also
- .sp .7
- .bG
- float fa[17], \**afp[17];
- .eG
- .sp .7
- declares an array of \fGfloat\fR numbers and an array of
- pointers to \fGfloat\fR numbers.
- Finally,
- .sp .7
- .bG
- static int x3d[3][5][7];
- .sp .7
- .eG
- declares a static three-dimensional array of integers,
- with rank 3\(mu5\(mu7.
- In complete detail, \fIx3d\fR is an array of three items:
- each item is an array of five arrays;
- each of the latter arrays is an array of seven
- integers.
- Any of the expressions ``x3d'', ``x3d[^i^]'', ``x3d[^i^][^j^]'', ``x3d[^i^][^j^][^k^]''
- may reasonably appear in an expression.
- The first three have type ``array'',
- the last has type \fGint\fR.
- .ms
- 8.5 Structure declarations
- .et
- Recall that one of the forms for a structure specifier
- is
- .dp
- \fGstruct \fI{ type-decl-list }
- .ed
- The
- .ft I
- type-decl-list
- .ft R
- is a sequence of type declarations for the members of the structure:
- .dp 3
- type-decl-list:
- type-declaration
- type-declaration type-decl-list
- .ed
- A type declaration is just a declaration which does not
- mention a storage class (the storage class ``member of
- structure'' here being understood by context).
- .dp 2
- type-declaration:
- type-specifier declarator-list \fG;
- .ed
- Within the structure, the objects declared
- have addresses which increase as their declarations
- are read left-to-right.
- Each component of a structure
- begins on an addressing boundary appropriate
- to its type.
- On the \s8PDP\s10-11 the only requirement is that non-characters
- begin on a word boundary; therefore, there may
- be 1-byte, unnamed holes in a structure,
- and all structures
- have an even length in bytes.
- .pg
- Another form of structure specifier is
- .dp 1
- \fGstruct \fIidentifier { type-decl-list }
- .ed
- This form is the same as the one just discussed,
- except that the identifier is remembered
- as the
- .ft I
- structure tag
- .ft R
- of the structure specified by the list.
- A subsequent declaration may then be given
- using the structure tag but without the list,
- as in the third form of structure specifier:
- .dp
- \fGstruct \fIidentifier
- .ed
- Structure tags allow definition of self-referential
- structures; they also
- permit the long part of the declaration to be
- given once and used several times.
- It is however absurd to declare a structure
- which contains an instance of
- itself, as distinct from a pointer to an instance of itself.
- .pg
- A simple example of a structure declaration, taken from
- \(sc16.2 where its use is illustrated more fully, is
- .dp 6
- .bG
- struct tnode {
- char tword[20];
- int count;
- struct tnode \**left;
- struct tnode \**right;
- };
- .ed
- .eG
- which contains an array of 20 characters, an integer, and two pointers
- to similar structures.
- Once this declaration has been given, the following
- declaration makes sense:
- .sp .7
- .bG
- struct tnode s, \**sp;
- .br
- .eG
- .sp .7
- which declares
- \fIs\fR to be a structure of the given sort
- and \fIsp\fR to be a pointer to a structure
- of the given sort.
- .pg
- The names of structure members and structure tags may
- be the same as ordinary variables, since a distinction
- can be made by context.
- However, names of tags and members
- must be distinct.
- The same member name can appear in different
- structures only if the two members are of the same type
- and if their origin with respect to their structure is the
- same;
- thus separate structures can share a common initial segment.
-