⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 c5

📁 UNIX v6源代码 这几乎是最经典的unix版本 unix操作系统设计和莱昂氏unix源代码分析都是用的该版
💻
📖 第 1 页 / 共 2 页
字号:
specifier is ignored in external definitions..ul12.  Compiler control lines.etWhen a line of a C program beginswith the character \fG#\fR, it is interpreted not bythe compiler itself, but by a preprocessor which is capableof replacing instances of given identifierswith arbitrary token-strings and of insertingnamed files into the source program.In order to cause this preprocessor to be invoked, itis necessary that the very first line of the programbegin with \fG#\fR.Since null lines are ignored by the preprocessor,this line need contain no other information..ms12.1  Token replacement.etA compiler-control line of the form.dp 1	\fG# define \fIidentifier token-string.ed(note: no trailing semicolon)causes the preprocessor to replace subsequent instancesof the identifier with the given string of tokens(except within compiler control lines).The replacement token-string has comments removed fromit, and it is surrounded with blanks.No rescanning of the replacement string is attempted.This facility is most valuable for definition of ``manifest constants'',as in.sp .7.nf.bG	# define tabsize 100	.^.^.	int table[tabsize];.sp .7.eG.fi.ms12.2  File inclusion.etLarge C programsoften contain many external data definitions.Since the lexical scope of external definitionsextends to the end of the program file,it is good practiceto put all the external definitions fordata at the start of theprogram file, so that the functions defined withinthe file need not repeat tedious and error-pronedeclarations for each external identifier they use.It is also useful to put a heavily used structure definitionat the start and use its structure tag to declarethe \fGauto\fR pointers to the structureused within functions.To further exploitthis technique when a large C programconsists of several files, a compiler control line ofthe form.dp 1	\fG# include "\fIfilename^\fG".edresults in the replacement of thatline by the entire contents of the file\fIfilename\fR..pg.ul13.  Implicit declarations.etIt is not always necessary to specifyboth the storage class and the typeof identifiers in a declaration.Sometimes the storage class is supplied bythe context: in external definitions,and in declarations of formal parametersand structure members.In a declaration inside a function,if a storage class but no typeis given, the identifier is assumedto be \fGint\fR;if a type but no storage class is indicated,the identifier is assumed tobe \fGauto\fR.An exception to the latter rule is made forfunctions, since \fGauto\fR functions are mean$ing$less(C being incapable of compiling code into the stack).If the type of an identifier is ``function returning ...'',it is implicitly declared to be \fGextern\fR..pgIn an expression, an identifierfollowed by \fG(\fR and not currently declaredis contextuallydeclared to be ``function returning \fGint\fR''..pgUndefined identifiers not followed by \fG(\fRare assumed to be labels whichwill be defined later in the function.(Since a label is not an lvalue, this accountsfor the ``Lvalue required'' errormessagesometimes noticed whenan undeclared identifier is used.)Naturally, appearance ofan identifier as a label declares it as such..pgFor some purposes it is best to consider formalparameters as belonging to their own storage class.In practice, C treats parameters as if theywere automatic (except that, as mentionedabove, formal parameter arrays and \fGfloat\fRsare treated specially)..ul14.  Types revisited.etThis section summarizes the operationswhich can be performed on objects of certain types..ms14.1  Structures.etThere are only two things that can be done witha structure:pick out one of its members (by means of the\fG^.^\fR or \fG\(mi>\fR operators); or take its address (by unary \fG&\fR).Other operations, such as assigning from or toit or passing it as a parameter, draw anerror message.In the future, it is expected thatthese operations, but not necessarilyothers, will be allowed..ms14.2  Functions.etThere are only two things thatcan be done with a function:call it, or take its address.If the name of a function appears in anexpression not in the function-name position of a call,a pointer to the function is generated.Thus, to pass one function to another, onemight say.bG.sp .7.nf	int f(^^);	...	g(^f^);.sp .7.eG.ft RThen the definition of \fIg \fRmight read.sp .7.bG	g^(^funcp^)	int (\**funcp)^(^^);	{		.^.^.		(\**funcp)^(^^);		.^.^.	}.sp .7.eG.fiNotice that \fIf\fR was declaredexplicitly in the calling routine since its first appearancewas not followed by \fG(\fR^..ms14.3  Arrays, pointers, and subscripting.etEvery time an identifier of array type appearsin an expression, it is converted into a pointerto the first member of the array.Because of this conversion, arrays are notlvalues.By definition, the subscript operator\fG[^]\fR is interpretedin such a way that``E1[E2]'' is identical to``\**(^(^E1)^+^(E2^)^)''.Because of the conversion ruleswhich apply to \fG+\fR, if E1 is an array and E2 an integer,then E1[E2] refers to the E2-th member of E1.Therefore,despite its asymmetricappearance, subscripting is a commutative operation..pgA consistent rule is followed in the case ofmulti-dimensional arrays.If E is an \fIn^\fR-dimensionalarrayof rank.ft Ii^\(mu^j^\(mu^.^.^.^\(muk,.ft Rthen E appearing in an expression is converted toa pointer to an (\fIn\fR\(mi1)-dimensionalarray with rank.ft Ij^\(mu^.^.^.^\(muk..ft RIf the \fG\**\fR operator, either explicitlyor implicitly as a result of subscripting,is applied to this pointer,the result is the pointed-to (\fIn\fR\(mi1)-dimensional array,which itself is immediately converted into a pointer..pgFor example, consider.sp .7.bG	int x[3][5];.sp .7.eGHere \fIx\fR is a 3\(mu5 array of integers.When \fIx\fR appears in an expression, it is convertedto a pointer to (the first of three) 5-membered arrays of integers.In the expression ``x[^i^]'',which is equivalent to ``\**(x+i)'',\fIx\fR is first converted to a pointer as described;then \fIi\fR is converted to the type of \fIx\fR,which involves multiplying \fIi\fR by thelength the object to which the pointer points,namely 5 integer objects.The results are added and indirection applied toyield an array (of 5 integers) which in turn is converted toa pointer to the first of the integers.If there is another subscript the same argument appliesagain; this time the result is an integer..pgIt follows from all this that arrays in C are storedrow-wise (last subscript varies fastest)and that the first subscript in the declaration helps determinethe amount of storage consumed by an arraybut plays no other part in subscript calculations..ms14.4  Labels.etLabels do nothave a type of their own; they aretreatedas having type ``array of \fGint\fR''.Label variables should be declared ``pointerto \fGint\fR'';before execution of a \fGgoto\fR referring to thevariable,a label (or an expressionderiving from a label) should be assigned to thevariable..pgLabel variables are a bad idea in general;the \fGswitch\fR statement makes themalmost always unnecessary..ul15.  Constant expressions.etIn several places C requires expressions which evaluate toa constant:after.ft Gcase,.ft Ras array bounds, and in initializers.In the first two cases, the expression caninvolve only integer constants, character constants,and.ft Gsizeof.ft Rexpressions, possiblyconnected by the binary operators.tr ^^.dp	+   \(mi   \**   /   %   &   \(or   ^   <<   >>.edor by the unary operators.dp	\(mi   \*~.ed.tr ^\|Parentheses can be used for grouping,but not for function calls..pgA bit more latitude is permitted for initializers;besides constant expressions as discussed above,one can also apply the unary \fG&\fRoperator to external scalars,and to external arrays subscriptedwith a constant expression.The unary \fG&\fR can alsobe applied implicitlyby appearance of unsubscripted external arrays.The rule here is that initializers mustevaluate either to a constant or to the addressof an external identifier plus or minus a constant.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -