📄 appa.html
字号:
type <tt>void *</tt>, may be converted, by a cast, by assignment, or bycomparison, to a pointer of any type. This produces a null pointer that isequal to another null pointer of the same type, but unequal to any pointerto a function or object.<p>Certain other conversions involving pointers are permitted, but haveimplementation-defined aspects. They must be specified by an explicittype-conversion operator, or cast (Pars.<a href="#sa.7.5">A.7.5</a> and<a href="#sa.8.8">A.8.8</a>).<p>A pointer may be converted to an integral type large enough to hold it; therequired size is implementation-dependent. The mapping function is alsoimplementation-dependent.<p>A pointer to one type may be converted to a pointer to another type. Theresulting pointer may cause addressing exceptions if the subject pointerdoes not refer to an object suitably aligned in storage. It is guaranteedthat a pointer to an object may be converted to a pointer to an object whosetype requires less or equally strict storage alignment and back again withoutchange; the notion of ``alignment'' is implementation-dependent, but objectsof the <tt>char</tt> types have least strict alignment requirements. As describedin <a href="#sa.6.8">Par.A.6.8</a>, a pointer may also be converted to type<tt>void *</tt> and back again without change.<p>A pointer may be converted to another pointer whose type is the same exceptfor the addition or removal of qualifiers (Pars.<a href="#sa.4.4">A.4.4</a>,<a href="#sa.8.2">A.8.2</a>) of the objecttype to which the pointer refers. If qualifiers are added, the new pointer isequivalent to the old except for restrictions implied by the new qualifiers.If qualifiers are removed, operations on the underlying object remain subjectto the qualifiers in its actual declaration.<p>Finally, a pointer to a function may be converted to a pointer to anotherfunction type. Calling the function specified by the converted pointer isimplementation-dependent; however, if the converted pointer is reconvertedto its original type, the result is identical to the original pointer.<h3><a name="sa.6.7">A.6.7 Void</a></h3>The (nonexistent) value of a <tt>void</tt> object may not be used in any way,and neither explicit nor implicit conversion to any non-void type may beapplied. Because a void expression denotes a nonexistent value, such anexpression may be used only where the value is not required, for example asan expression statement (<a href="#sa.9.2">Par.A.9.2</a>) or as the leftoperand of a comma operator (<a href="#sa.7.18">Par.A.7.18</a>).<p>An expression may be converted to type <tt>void</tt> by a cast. For example, avoid cast documents the discarding of the value of a function call used as anexpression statement.<p><dl><dd><font size="-1"><tt>void</tt> did not appear in the first edition of this book, but has becomecommon since.</font></dl><h3><a name="sa.6.8">A.6.8 Pointers to Void</a></h3>Any pointer to an object may be converted to type <tt>void *</tt> without lossof information. If the result is converted back to the original pointer type,the original pointer is recovered. Unlike the pointer-to-pointer conversionsdiscussed in <a href="#sa.6.6">Par.A.6.6</a>, which generally require anexplicit cast, pointers may be assigned to and from pointers of type<tt>void *</tt>, and may be compared with them.<p><dl><dd><font size="-1">This interpretation of <tt>void *</tt> pointers is new; previously, <tt>char *</tt>pointers played the role of generic pointer. The ANSI standard specificallyblesses the meeting of <tt>void *</tt> pointers with object pointers inassignments and relationals, while requiring explicit casts for other pointermixtures.</font></dl><h2><a name="sa.7">A.7 Expressions</a></h2>The precedence of expression operators is the same as the order of the majorsubsections of this section, highest precedence first. Thus, for example,the expressions referred to as the operands of <tt>+</tt>(<a href="#sa.7.7">Par.A.7.7</a>) are those expressions defined inPars.<a href="#sa.7.1">A.7.1</a>-<a href="#sa.7.6">A.7.6</a>.Within each subsection, the operatorshave the same precedence. Left- or right-associativity is specified in eachsubsection for the operators discussed therein. The grammar given in<a href="#sa.13">Par.13</a> incorporates the precedence and associativity ofthe operators.<p>The precedence and associativity of operators is fully specified, but theorder of evaluation of expressions is, with certain exceptions, undefined,even if the subexpressions involve side effects. That is, unless the definitionof the operator guarantees that its operands are evaluated in a particularorder, the implementation is free to evaluate operands in any order, or evento interleave their evaluation. However, each operator combines the valuesproduced by its operands in a way compatible with the parsing of theexpression in which it appears.<p><dl><dd><font size="-1">This rule revokes the previous freedom to reorder expressions with operatorsthat are mathematically commutative and associative, but can fail to becomputationally associative. The change affects only floating-pointcomputations near the limits of their accuracy, and situations where overflowis possible.</font></dl><p>The handling of overflow, divide check, and other exceptions in expressionevaluation is not defined by the language. Most existing implementations ofC ignore overflow in evaluation of signed integral expressions and assignments,but this behavior is not guaranteed. Treatment of division by 0, and allfloating-point exceptions, varies among implementations; sometimes it isadjustable by a non-standard library function.<h3><a name="sa.7.1">A.7.1 Pointer Conversion</a></h3>If the type of an expression or subexpression is ``array of <em>T</em>,'' forsome type <em>T</em>, then the value of the expression is a pointer to the firstobject in the array, and the type of the expression is altered to ``pointer to<em>T</em>.'' This conversion does not take place if the expression is in theoperand of the unary <tt>&</tt> operator, or of <tt>++</tt>, <tt> --</tt>,<tt>sizeof</tt>, or as the left operand of an assignment operator or the <tt>.</tt>operator. Similarly, an expression of type ``function returning <em>T</em>,''except when used as the operand of the <tt>&</tt> operator, is converted to``pointer to function returning <em>T</em>.''<h3><a name="sa.7.2">A.7.2 Primary Expressions</a></h3>Primary expressions are identifiers, constants, strings, or expressions inparentheses.<p><em> primary-expression<br> identifier<br> constant<br> string<br> (expression)</em><p>An identifier is a primary expression, provided it has been suitably declaredas discussed below. Its type is specified by its declaration. An identifieris an lvalue if it refers to an object (<a href="#sa.5">Par.A.5</a>) and if itstype is arithmetic, structure, union, or pointer.<p>A constant is a primary expression. Its type depends on its form as discussedin <a href="#sa.2.5">Par.A.2.5</a>.<p>A string literal is a primary expression. Its type is originally ``array of<tt>char</tt>'' (for wide-char strings, ``array of <tt>wchar_t</tt>''), butfollowing the rule given in <a href="#sa.7.1">Par.A.7.1</a>, this is usuallymodified to ``pointer to <tt>char</tt>'' (<tt>wchar_t</tt>) and the result is apointer to the first character in the string. The conversion also does notoccur in certain initializers; see <a href="#sa.8.7">Par.A.8.7</a>.<p>A parenthesized expression is a primary expression whose type and value areidentical to those of the unadorned expression. The precedence of parenthesesdoes not affect whether the expression is an lvalue.<h3><a name="sa.7.3">A.7.3 Postfix Expressions</a></h3>The operators in postfix expressions group left to right.<p><em> postfix-expression:<br> primary-expression<br> postfix-expression[expression]<br> postfix-expression(argument-expression-list<sub>opt</sub>)<br> postfix-expression.identifier<br> postfix-expression<tt>-></tt>identifier<br> postfix-expression<tt>++</tt><br> postfix-expression<tt>--</tt><p> argument-expression-list:<br> assignment-expression<br> assignment-expression-list <tt>,</tt> assignment-expression</em><h4><a name="sa.7.3.1">A.7.3.1 Array References</a></h4>A postfix expression followed by an expression in square brackets is a postfixexpression denoting a subscripted array reference. One of the two expressionsmust have type ``pointer to <em>T</em>'', where <em>T</em> is some type, and theother must have integral type; the type of the subscript expression is <em>T</em>.The expression <tt>E1[E2]</tt> is identical (by definition) to <tt>*((E1)+(E2))</tt>.See <a href="#sa.8.6.2">Par.A.8.6.2</a> for further discussion.<h4><a name="sa.7.3.2">A.7.3.2 Function Calls</a></h4>A function call is a postfix expression, called the function designator,followed by parentheses containing a possibly empty, comma-separated list ofassignment expressions (<a href="#sa.7.17">Par.A7.17</a>), which constitute thearguments to the function. If the postfix expression consists of an identifierfor which no declaration exists in the current scope, the identifier isimplicitly declared as if the declaration<p> <tt>extern int</tt> <em>identifier</em><tt>();</tt><p>had been given in the innermost block containing the function call. The postfixexpression (after possible explicit declaration and pointer generation,<a href="#sa.7.1">Par.A7.1</a>)must be of type ``pointer to function returning <em>T</em>,'' for some type<em>T</em>, and the value of the function call has type <em>T</em>.<p><dl><dd><font size="-1">In the first edition, the type was restricted to ``function,'' and an explicit<tt>*</tt> operator was required to call through pointers to functions. The ANSIstandard blesses the practice of some existing compilers by permitting thesame syntax for calls to functions and to functions specified by pointers. Theolder syntax is still usable.</font></dl><p>The term <em>argument</em> is used for an expression passed by a function call;the term <em>parameter</em> is used for an input object (or its identifier)received by a function definition, or described in a function declaration. Theterms ``actual argument (parameter)'' and ``formal argument (parameter)''respectively are sometimes used for the same distinction.<p>In preparing for the call to a function, a copy is made of each argument; allargument-passing is strictly by value. A function may change the values of itsparameter objects, which are copies of the argument expressions, but thesechanges cannot affect the values of the arguments. However, it is possible topass a pointer on the understanding that the function may change the valueof the object to which the pointer points.<p>There are two styles in which functions may be declared. In the new style, thetypes of parameters are explicit and are part of the type of the function;such a declaration os also called a function prototype. In the old style,parameter types are not specified. Function declaration is issued in<a href="#sa.8.6.3">Pars.A.8.6.3</a> and <a href="#sa.10.1">A.10.1</a>.<p>If the function declaration in scope for a call is old-style, then defaultargument promotion is applied to each argument as follows: integral promotion(<a href="#sa.6.1">Par.A.6.1</a>) is performed on each argument of integraltype, and each <tt>float</tt> argument is converted to <tt>double</tt>. Theeffect of the call is undefined ifthe number of arguments disagrees with the number of parameters in thedefinition of the function, or if the type of an argument after promotiondisagrees with that of the corresponding parameter. Type agreement dependson whether the function's definition is new-style or old-style. If it isold-style, then the comparison is between the promoted type of the argumentsof the call, and the promoted type of the parameter, if the definition isnew-style, the promoted type of the argument must be that of the parameteritself, without promotion.<p>If the function declaration in scope for a call is new-style, then thearguments are converted, as if by assignment, to the types of the corresponding
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -