📄 library_28.html
字号:
function typically designs a convention for the caller to tell it howmany arguments it has, and what kind. It is up to you to define anappropriate calling convention for each variadic function, and write allcalls accordingly.<P>One kind of calling convention is to pass the number of optionalarguments as one of the fixed arguments. This convention works providedall of the optional arguments are of the same type.<P>A similar alternative is to have one of the required arguments be a bitmask, with a bit for each possible purpose for which an optionalargument might be supplied. You would test the bits in a predefinedsequence; if the bit is set, fetch the value of the next argument,otherwise use a default value.<P>A required argument can be used as a pattern to specify both the numberand types of the optional arguments. The format string argument to<CODE>printf</CODE> is one example of this (see section <A HREF="library_11.html#SEC135" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_11.html#SEC135">Formatted Output Functions</A>).<P>Another possibility is to pass an "end marker" value as the lastoptional argument. For example, for a function that manipulates anarbitrary number of pointer arguments, a null pointer might indicate theend of the argument list. (This assumes that a null pointer isn'totherwise meaningful to the function.) The <CODE>execl</CODE> function worksin just this way; see section <A HREF="library_23.html#SEC406" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_23.html#SEC406">Executing a File</A>.<P><A NAME="IDX1934"></A><A NAME="IDX1935"></A><A NAME="IDX1936"></A><H4><A NAME="SEC478" HREF="library_toc.html#SEC478" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_toc.html#SEC478">Calling Variadic Functions</A></H4><P>You don't have to write anything special when you call a variadic function.Just write the arguments (required arguments, followed by optional ones)inside parentheses, separated by commas, as usual. But you should prepareby declaring the function with a prototype, and you must know how theargument values are converted.<P>In principle, functions that are <EM>defined</EM> to be variadic must alsobe <EM>declared</EM> to be variadic using a function prototype wheneveryou call them. (See section <A HREF="library_28.html#SEC475" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_28.html#SEC475">Syntax for Variable Arguments</A>, for how.) This is becausesome C compilers use a different calling convention to pass the same setof argument values to a function depending on whether that functiontakes variable arguments or fixed arguments.<P>In practice, the GNU C compiler always passes a given set of argumenttypes in the same way regardless of whether they are optional orrequired. So, as long as the argument types are self-promoting, you cansafely omit declaring them. Usually it is a good idea to declare theargument types for variadic functions, and indeed for all functions.But there are a few functions which it is extremely convenient not tohave to declare as variadic--for example, <CODE>open</CODE> and<CODE>printf</CODE>.<A NAME="IDX1937"></A><A NAME="IDX1938"></A><P>Since the prototype doesn't specify types for optional arguments, in acall to a variadic function the <DFN>default argument promotions</DFN> areperformed on the optional argument values. This means the objects oftype <CODE>char</CODE> or <CODE>short int</CODE> (whether signed or not) arepromoted to either <CODE>int</CODE> or <CODE>unsigned int</CODE>, asappropriate; and that objects of type <CODE>float</CODE> are promoted to type<CODE>double</CODE>. So, if the caller passes a <CODE>char</CODE> as an optionalargument, it is promoted to an <CODE>int</CODE>, and the function should getit with <CODE>va_arg (<VAR>ap</VAR>, int)</CODE>.<P>Conversion of the required arguments is controlled by the functionprototype in the usual way: the argument expression is converted to thedeclared argument type as if it were being assigned to a variable ofthat type.<P><H4><A NAME="SEC479" HREF="library_toc.html#SEC479" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_toc.html#SEC479">Argument Access Macros</A></H4><P>Here are descriptions of the macros used to retrieve variable arguments.These macros are defined in the header file <TT>`stdarg.h'</TT>.<A NAME="IDX1939"></A><P><A NAME="IDX1940"></A><U>Data Type:</U> <B>va_list</B><P>The type <CODE>va_list</CODE> is used for argument pointer variables.<P><A NAME="IDX1941"></A><U>Macro:</U> void <B>va_start</B> <I>(va_list <VAR>ap</VAR>, <VAR>last_required</VAR>)</I><P>This macro initializes the argument pointer variable <VAR>ap</VAR> to pointto the first of the optional arguments of the current function;<VAR>last_required</VAR> must be the last required argument to the function.<P>See section <A HREF="library_28.html#SEC481" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_28.html#SEC481">Old-Style Variadic Functions</A>, for an alternate definition of <CODE>va_start</CODE>found in the header file <TT>`varargs.h'</TT>.<P><A NAME="IDX1942"></A><U>Macro:</U> <VAR>type</VAR> <B>va_arg</B> <I>(va_list <VAR>ap</VAR>, <VAR>type</VAR>)</I><P>The <CODE>va_arg</CODE> macro returns the value of the next optional argument,and modifies the value of <VAR>ap</VAR> to point to the subsequent argument.Thus, successive uses of <CODE>va_arg</CODE> return successive optional arguments.<P>The type of the value returned by <CODE>va_arg</CODE> is <VAR>type</VAR> asspecified in the call. <VAR>type</VAR> must be a self-promoting type (not<CODE>char</CODE> or <CODE>short int</CODE> or <CODE>float</CODE>) that matches the typeof the actual argument.<P><A NAME="IDX1943"></A><U>Macro:</U> void <B>va_end</B> <I>(va_list <VAR>ap</VAR>)</I><P>This ends the use of <VAR>ap</VAR>. After a <CODE>va_end</CODE> call, further<CODE>va_arg</CODE> calls with the same <VAR>ap</VAR> may not work. You should invoke<CODE>va_end</CODE> before returning from the function in which <CODE>va_start</CODE>was invoked with the same <VAR>ap</VAR> argument.<P>In the GNU C library, <CODE>va_end</CODE> does nothing, and you need not everuse it except for reasons of portability.<P><H3><A NAME="SEC480" HREF="library_toc.html#SEC480" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_toc.html#SEC480">Example of a Variadic Function</A></H3><P>Here is a complete sample function that accepts a variable number ofarguments. The first argument to the function is the count of remainingarguments, which are added up and the result returned. While trivial,this function is sufficient to illustrate how to use the variablearguments facility.<P><PRE>#include <stdarg.h>#include <stdio.h>intadd_em_up (int count,...){ va_list ap; int i, sum; va_start (ap, count); /* Initialize the argument list. */ sum = 0; for (i = 0; i < count; i++) sum += va_arg (ap, int); /* Get the next argument value. */ va_end (ap); /* Clean up. */ return sum;}intmain (void){ /* This call prints 16. */ printf ("%d\n", add_em_up (3, 5, 5, 6)); /* This call prints 55. */ printf ("%d\n", add_em_up (10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)); return 0;}</PRE><P><H4><A NAME="SEC481" HREF="library_toc.html#SEC481" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_toc.html#SEC481">Old-Style Variadic Functions</A></H4><A NAME="IDX1944"></A><P>Before ANSI C, programmers used a slightly different facility forwriting variadic functions. The GNU C compiler still supports it;currently, it is more portable than the ANSI C facility, since supportfor ANSI C is still not universal. The header file which defines theold-fashioned variadic facility is called <TT>`varargs.h'</TT>.<P>Using <TT>`varargs.h'</TT> is almost the same as using <TT>`stdarg.h'</TT>.There is no difference in how you call a variadic function;See section <A HREF="library_28.html#SEC478" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_28.html#SEC478">Calling Variadic Functions</A>. The only difference is in how you definethem. First of all, you must use old-style non-prototype syntax, likethis:<P><PRE>treebuild (va_alist) va_dcl{</PRE><P>Secondly, you must give <CODE>va_start</CODE> just one argument, like this:<P><PRE> va_list p; va_start (p);</PRE><P>These are the special macros used for defining old-style variadicfunctions:<P><A NAME="IDX1945"></A><U>Macro:</U> <B>va_alist</B><P>This macro stands for the argument name list required in a variadicfunction. <P><A NAME="IDX1946"></A><U>Macro:</U> <B>va_dcl</B><P>This macro declares the implicit argument or arguments for a variadicfunction.<P><A NAME="IDX1947"></A><U>Macro:</U> void <B>va_start</B> <I>(va_list <VAR>ap</VAR>)</I><P>This macro, as defined in <TT>`varargs.h'</TT>, initializes the argumentpointer variable <VAR>ap</VAR> to point to the first argument of the currentfunction.<P>The other argument macros, <CODE>va_arg</CODE> and <CODE>va_end</CODE>, are the samein <TT>`varargs.h'</TT> as in <TT>`stdarg.h'</TT>; see section <A HREF="library_28.html#SEC479" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_28.html#SEC479">Argument Access Macros</A> fordetails.<P>It does not work to include both <TT>`varargs.h'</TT> and <TT>`stdarg.h'</TT> inthe same compilation; they define <CODE>va_start</CODE> in conflicting ways.<P><A NAME="IDX1948"></A><H2><A NAME="SEC482" HREF="library_toc.html#SEC482" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_toc.html#SEC482">Null Pointer Constant</A></H2><P>The null pointer constant is guaranteed not to point to any real object.You can assign it to any pointer variable since it has type <CODE>void*</CODE>. The preferred way to write a null pointer constant is with<CODE>NULL</CODE>.<P><A NAME="IDX1949"></A><U>Macro:</U> void * <B>NULL</B><P>This is a null pointer constant.<P>You can also use <CODE>0</CODE> or <CODE>(void *)0</CODE> as a null pointerconstant, but using <CODE>NULL</CODE> is cleaner because it makes the purposeof the constant more evident.<P>If you use the null pointer constant as a function argument, then forcomplete portability you should make sure that the function has aprototype declaration. Otherwise, if the target machine has twodifferent pointer representations, the compiler won't know whichrepresentation to use for that argument. You can avoid the problem byexplicitly casting the constant to the proper pointer type, but werecommend instead adding a prototype for the function you are calling.<P><H2><A NAME="SEC483" HREF="library_toc.html#SEC483" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_toc.html#SEC483">Important Data Types</A></H2><P>The result of subtracting two pointers in C is always an integer, but theprecise data type varies from C compiler to C compiler. Likewise, thedata type of the result of <CODE>sizeof</CODE> also varies between compilers.ANSI defines standard aliases for these two types, so you can refer tothem in a portable fashion. They are defined in the header file <TT>`stddef.h'</TT>.<A NAME="IDX1950"></A><P><A NAME="IDX1951"></A><U>Data Type:</U> <B>ptrdiff_t</B><P>This is the signed integer type of the result of subtracting twopointers. For example, with the declaration <CODE>char *p1, *p2;</CODE>, theexpression <CODE>p2 - p1</CODE> is of type <CODE>ptrdiff_t</CODE>. This willprobably be one of the standard signed integer types (<CODE>shortint</CODE>, <CODE>int</CODE> or <CODE>long int</CODE>), but might be a nonstandardtype that exists only for this purpose.<P><A NAME="IDX1952"></A><U>Data Type:</U> <B>size_t</B><P>This is an unsigned integer type used to represent the sizes of objects.The result of the <CODE>sizeof</CODE> operator is of this type, and functionssuch as <CODE>malloc</CODE> (see section <A HREF="library_3.html#SEC21" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_3.html#SEC21">Unconstrained Allocation</A>) and<CODE>memcpy</CODE> (see section <A HREF="library_5.html#SEC61" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_5.html#SEC61">Copying and Concatenation</A>) accept arguments ofthis type to specify object sizes.<P><STRONG>Usage Note:</STRONG> <CODE>size_t</CODE> is the preferred way to declare anyarguments or variables that hold the size of an object.<P>In the GNU system <CODE>size_t</CODE> is equivalent to either<CODE>unsigned int</CODE> or <CODE>unsigned long int</CODE>. These typeshave identical properties on the GNU system, and for most purposes, youcan use them interchangeably. However, they are distinct as data types,which makes a difference in certain contexts.<P>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -