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

📄 unx17.htm

📁 Linux Unix揭密.高质量电子书籍.对学习Linux有大帮助,欢迎下载学习.
💻 HTM
📖 第 1 页 / 共 3 页
字号:
<BR></P>

<HR ALIGN=CENTER>

<NOTE>

<IMG SRC="note.gif" WIDTH = 35 HEIGHT = 35><B>NOTE:</B> The second statement in an else condition can be another if statement. This situation might cause the grammar to be indeterminant if the structure

<BR>

<BR>if (expr) if (expr) statment else statement

<BR>

<BR>is not parsed cleanly.

<BR>

<BR>As the code is written, the else is considered applicable to the second if. To make it applicable with the first if, surround the second if statement with curly braces. For example:

<BR>

<BR>$ if (expr) {if (expr) statement} else statement

<BR></NOTE>

<HR ALIGN=CENTER>

<P>The third type of conditional execution is more complicated. The switch statement first evaluates an expression. Then it looks down a series of case statements to find a label that matches the expression's value and executes the statements following the 

label. A special label default exists if no other conditions are met. If you want only a set of statements executed for each label, you must use the break statement to leave the switch statement.

<BR></P>

<P>This covers the simplest building blocks of a C program. You can add more power by using functions and by declaring complex data types.

<BR></P>

<P>If your program requires different pieces of data to be grouped on a consistent basis, you can group them into structures. Listing 17.3 shows a structure for a California driver's license. Note that it includes integer, character, and character array 
(string) types.

<BR></P>

<UL>

<LH><B>Listing 17.3. An example of a structure.</B></LH></UL>

<PRE>struct license {

        char name[128];

        char address[3][128];

        int zipcode;

        int height, weight,month, day, year;

        char license_letter;

        int license_number;

        };

struct license licensee;

struct license *user;</PRE>

<P>Since California driver's license numbers consist of a single character followed by a seven digit number, the license ID is broken into two components. Similarly, the licensee's address is broken into three lines, represented by three arrays of 128 
characters.

<BR></P>

<P>Accessing individual fields of a structure requires two different techniques. To read a member of a locally defined structure, you append a dot to the variable, then the field name. For example:

<BR></P>

<PRE>licensee.zipcode=94404;</PRE>

<P>To use a pointer, to the structure, you need -&gt; to point to the member:

<BR></P>

<PRE>user-&gt;zipcode=94404;</PRE>

<P>Interestingly, if the structure pointer is incremented, the address is increased not by 1, but by the size of the structure.

<BR></P>

<P>Functions are an easy way to group statements and to give them a name. These are usually related statements that perform repetitive tasks such as I/O. printf, described above, is a function. It is provided with the standard C library. Listing 17.4 
illustrates a function definition, a function call, and a function.

<BR></P>

<HR ALIGN=CENTER>

<NOTE>

<IMG SRC="note.gif" WIDTH = 35 HEIGHT = 35><B>NOTE:</B> The three-dot ellipsis simply means that some lines of sample code are not shown here, in order to save space.

<BR></NOTE>

<HR ALIGN=CENTER>

<UL>

<LH><B>Listing 17.4. An example of a function.</B></LH></UL>

<PRE>int swapandmin( int *, int *);        /* Function declaration */

...

int i,j,lower;

i=2; j=4;

lower=swapandmin(&amp;i, &amp;j);            /* Function call */

...

int swapandmin(int *a,int *b)        /* Function definition */

{

int tmp;

tmp=(*a);

(*a)=(*b);

(*b)=tmp;

if ((*a)&lt;(*b)) return(*a);

return(*b);

}</PRE>

<P>ANSI C and K&amp;R differ most in function declarations and calls. ANSI requires that function arguments be prototyped when the function is declared. K&amp;R required only the name and the type of the returned value. The declaration in Listing 17.4 
states that a function swapandmin will take two pointers to integers as arguments and that it will return an integer. The function call takes the addresses of two integers and sets the variable named lower with the return value of the function.

<BR></P>

<P>When a function is called from a C program, the values of the arguments are passed to the function. Therefore, if any of the arguments will be changed for the calling function, you can't pass only the variable&#151;you must pass the address, too. 
Likewise, to change the value of the argument in the calling routine of the function, you must assign the new value to the address.

<BR></P>

<P>In the function in Listing 17.4, the value pointed to by a is assigned to the tmp variable. b is assigned to a, and tmp is assigned to b. *a is used instead of a to ensure that the change is reflected in the calling routine. Finally, the values of *a 
and *b are compared, and the lower of the two is returned.

<BR></P>

<P>If you included the line

<BR></P>

<PRE>printf(&quot;%d %d %d&quot;,lower,i,j);</PRE>

<P>after the function call, you would see 2 4 2 on the output.

<BR></P>

<P>This sample function is quite simple, and it is ideal for a macro. A macro is a technique used to replace a token with different text. You can use macros to make code more readable. For example, you might use EOF instead of (-1) to indicate the end of a 

file. You can also use macros to replace code. Listing 17.5 is the same as Listing 17.4 except that it uses macros.

<BR></P>

<UL>

<LH><B>Listing 17.5. An example of macros.</B></LH></UL>

<PRE>#define SWAP(X,Y) {int tmp; tmp=X; X=Y; Y=tmp; }

#define MIN(X,Y) ((X&lt;Y) ? X : Y )

...

int i,j,lower;

i=2; j=4;

SWAP(i,j);

lower=MIN(i,j);</PRE>

<P>When a C program is compiled, macro replacement is one of the first steps performed. Listing 17.6 illustrates the result of the replacement.

<BR></P>

<UL>

<LH><B>Listing 17.6. An example of macro replacement.</B></LH></UL>

<PRE>int i,j,lower;

i=2; j=4;

{int tmp; tmp=i; i=j; j=tmp; };

lower= ((i&lt;j) ? i : j );</PRE>

<P>The macros make the code easier to read and understand.

<BR></P>

<H3 ALIGN="CENTER">

<CENTER><A ID="I13" NAME="I13">

<FONT SIZE=4><B>Creating a Simple Program</B>

<BR></FONT></A></CENTER></H3>

<P>For your first program, write a program that prints a chart of the first ten integers and their squares, cubes, and square roots.

<BR></P>

<H4 ALIGN="CENTER">

<CENTER><A ID="I14" NAME="I14">

<FONT SIZE=3><B>Writing the Code</B>

<BR></FONT></A></CENTER></H4>

<P>Using the text editor of your choice, enter all the code in Listing 17.7 and save it in a file called sample.c.

<BR></P>

<UL>

<LH><B>Listing 17.7. Source code for </B><B>sample.c</B><B>.</B></LH></UL>

<PRE>#include &lt;stdio.h&gt;

#include &lt;math.h&gt;

main()

{

int i;

double a;

for(i=1;i&lt;11;i++)

        {

        a=i*1.0;

        printf(&quot;%2d. %3d %4d %7.5f\n&quot;,i,i*i,i*i*i,sqrt);

        }

}</PRE>

<P>The first two lines are header files. The stdio.h file provides the function definitions and structures associated with the C input and output libraries. The math.h file includes the definitions of mathematical library functions. You need it for the 
square root function.

<BR></P>

<P>The main loop is the only function that you need to write for this example. It takes no arguments. You define two variables. One is the integer i, and the other is a double-precision floating point number called a. You wouldn't have to use a, but you 
can for the sake of convenience.

<BR></P>

<P>The program is a simple for loop that starts at 1 and ends at 11. It increments i by 1 each time through. When i equals 11, the for loop stops executing. You could have also written i&lt;=10, because the expressions have the same meaning.

<BR></P>

<P>First, you multiply i by 1.0 and assign the product to a. A simple assignment would also work, but the multiplication reminds you that you are converting the value to a double-precision floating point number.

<BR></P>

<P>Next, you call the print function. The format string includes three integers of widths 2, 3, and 4. After the first integer is printed, you print a period. After the first integer is printed, you print a floating point number that is seven characters 
wide with five digits following the decimal point. The arguments after the format string show that you print the integer, the square of the integer, the cube of the integer, and the square root of the integer.

<BR></P>

<H4 ALIGN="CENTER">

<CENTER><A ID="I15" NAME="I15">

<FONT SIZE=3><B>Compiling the Program</B>

<BR></FONT></A></CENTER></H4>

<P>To compile this program using the C compiler, enter the following command:

<BR></P>

<PRE>cc sample.c -lm</PRE>

<P>This command produces an output file called a.out. This is the simplest use of the C compiler. It is one of the most powerful and flexible commands on a UNIX system.

<BR></P>

<P>A number of different flags can change the compiler's output. These flags are often dependent on the system or compiler. Some flags are common to all C compilers. These are described in the following paragraphs.

<BR></P>

<P>The -o flag tells the compiler to write the output to the file named after the flag. The cc -o sample sample.c command would put the program in a file named sample.

<BR></P>

<HR ALIGN=CENTER>

<NOTE>

<IMG SRC="note.gif" WIDTH = 35 HEIGHT = 35><B>NOTE:</B> The output discussed here is the compiler's output, not the sample program. Compiler output is usually the program, and in every example here, it is an executable program.

<BR></NOTE>

<HR ALIGN=CENTER>

<P>The -g flag tells the compiler to keep the symbol table (the data used by a program to associate variable names with memory locations), which is necessary for debuggers. Its opposite is the -O flag, which tells the compiler to optimize the 
code&#151;that is, to make it more efficient. You can change the search path for header files with the -I flag, and you can add libraries with the -l and -L flags.

<BR></P>

<P>The compilation process takes place in several steps.

<BR></P>

<OL>

<LI>First, the C preprocessor parses the file. To parse the file, it sequentially reads the lines, includes header files, and performs macro replacement.

<BR>

<BR></LI>

<LI>The compiler parses the modified code for correct syntax. This builds a symbol table and creates an intermediate object format. Most symbols have specific memory addresses assigned, although symbols defined in other modules, such as external variables, 

do not.

<BR>

<BR></LI>

<LI>The last compilation stage, linking, ties together different files and libraries and links the files by resolving the symbols that have not been resolved yet.

<BR>

<BR></LI></OL>

<H4 ALIGN="CENTER">

<CENTER><A ID="I16" NAME="I16">

<FONT SIZE=3><B>Executing the Program</B>

<BR></FONT></A></CENTER></H4>

<P>The output from this program appears in Listing 17.8.

<BR></P>

<UL>

<LH><B>Listing 17.8. Output from the </B><B>sample.c</B><B> program.</B></LH></UL>

<PRE>$ sample.c

 1.   1    1 1.00000

 2.   4    8 1.41421

 3.   9   27 1.73205

 4.  16   64 2.00000

 5.  25  125 2.23607

 6.  36  216 2.44949

 7.  49  343 2.64575

 8.  64  512 2.82843

 9.  81  729 3.00000

10. 100 1000 3.16228</PRE>

<HR ALIGN=CENTER>

<NOTE>

<IMG SRC="note.gif" WIDTH = 35 HEIGHT = 35><B>NOTE:</B> To execute a program, just type its name at a shell prompt. The output will immediately follow.

<BR></NOTE>

<HR ALIGN=CENTER>

<H3 ALIGN="CENTER">

<CENTER><A ID="I17" NAME="I17">

<FONT SIZE=4><B>Building Large Applications</B>

<BR></FONT></A></CENTER></H3>

<P>C programs can be broken into any number of files, so long as no function spans more than one file. To compile this program, you compile each source file into an intermediate object before you link all the objects into a single executable. The -c flag 
tells the compiler to stop at this stage. During the link stage, all the object files should be listed on the command line. Object files are identified by the .o suffix.

<BR></P>

<H4 ALIGN="CENTER">

<CENTER><A ID="I18" NAME="I18">

<FONT SIZE=3><B>Making Libraries with </B><B><I>ar</I></B>

<BR></FONT></A></CENTER></H4>

<P>If several different programs use the same functions, they can be combined in a single library archive. The ar command is used to build a library. When this library is included on the compile line, the archive is searched to resolve any external 
symbols. Listing 17.9 shows an example of building and using a library.

<BR></P>

<UL>

<LH><B>Listing 17.9. Building a large application.</B></LH></UL>

<PRE>cc -c sine.c

cc -c cosine.c

cc -c tangent.c

ar c libtrig.a sine.o cosine.o tangent.o

cc -c mainprog.c

cc -o mainprog mainprog.o libtrig.a</PRE>

<H4 ALIGN="CENTER">

<CENTER><A ID="I19" NAME="I19">

<FONT SIZE=3><B>Building Large Applications with </B><B><I>make</I></B>

<BR></FONT></A></CENTER></H4>

<P>Of course, managing the process of compiling large applications can be difficult. UNIX provides a tool that takes care of this for you. make looks for a makefile, which includes directions for building the application.

<BR></P>

<P>You can think of the makefile as being its own programming language. The syntax is

<BR></P>

<PRE>target: dependencies

        Commandlist</PRE>

<P>Dependencies can be targets declared elsewhere in the makefile, and they can have their own dependencies. When a make command is issued, the target on the command line is checked; if no targets are specified on the command line, the first target listed 

in the file is checked.

<BR></P>

<P>When make tries to build a target, first the dependencies list is checked. If any of them requires rebuilding, it is rebuilt. Then, the command list specified for the target itself is executed.

<BR></P>

<P>make has its own set of default rules, which are executed if no other rules are specified. One rule specifies that an object is created from a C source file using $(cc) $(CFLAGS) -c (source file). CFLAGS is a special variable; a list of flags that will 

be used with each compilation can be stored there. These flags can be specified in the makefile, on the make command line, or in an environment variable. make checks the dependencies to determine whether a file needs to be made. It uses the mtime field of 

a file's status. If the file has been modified more recently than the target, the target is remade.

<BR></P>

<P>Listing 17.10 shows an example of a makefile.

<BR></P>

<UL>

<LH><B>Listing 17.10. An example of a </B><B>makefile</B><B>.</B></LH></UL>

<PRE>CFLAGS= -g

igfl: igfl.o igflsubs.o

        cc -g -o igfl igfl.o igflsubs.o -lm

igflsubs.o: igfl.h

clean:

        rm -f *.o</PRE>

<P>Listing 17.10 uses several targets to make a single executable called igfl. The two C files are compiled into objects by implicit rules. Only igflsubs.o is dependent on a file, igfl.h. If igfl.h has been modified more recently than igflsubs.o, a new 
igfl.o is compiled.

<BR></P>

<P>Note that there is a target called clean. Because there are no dependencies, the command is always executed when clean is specified. This command removes all the intermediate files. Listing 17.11 shows the output of make when it is executed for the 
first time.

<BR></P>

<UL>

<LH><B>Listing 17.11. Output of </B><B>make</B><B>.</B></LH></UL>

<PRE>cc -g  -target sun4 -c  igfl.c

cc -g  -target sun4 -c  igflsubs.c

cc -g -o igfl igfl.o igflsubs.o -lm</PRE>

<H3 ALIGN="CENTER">

<CENTER><A ID="I20" NAME="I20">

<FONT SIZE=4><B>Debugging Tools</B>

<BR></FONT></A></CENTER></H3>

<P>Debugging is a science and an art unto itself. Sometimes, the simplest tool&#151;the code listing&#151;is best. At other times, however, you need to use other tools. Three of these tools are lint, prof, and sdb. Other available tools include escape, 
cxref, and cb. Many UNIX commands have debugging uses.

<BR></P>

<P>lint is a command that examines source code for possible problems. The code might meet the standards for C and compile cleanly, but it might not execute correctly. Two things checked by lint are type mismatches and incorrect argument counts on function 

calls. lint uses the C preprocessor, so you can use similar command-like options as you would use for cc.

<BR></P>

<P>The prof command is used to study where a program is spending its time. If a program is compiled and linked with -p as a flag, when it executes, a mon.out file is created with data on how often each function is called and how much time is spent in each 

function. This data is parsed and displayed with prof. An analysis of the output generated by prof helps you determine where performance bottlenecks occur. Although optimizing compilers can speed your programs, this analysis significantly improves program 

performance.

<BR></P>

<P>The third tool is sdb&#151;a symbolic debugger. When a program is compiled with -g, the symbol tables are retained, and a symbolic debugger can be used to track program bugs. The basic technique is to invoke sdb after a core dump and get a stack trace. 

This indicates the source line where the core dump occurred and the functions that were called to reach that line. Often, this is enough to identify the problem. It is not the limit of sdb, though.

<BR></P>

<P>sdb also provides an environment for debugging programs interactively. Invoking sdb with a program enables you to set breakpoints, examine variable values, and monitor variables. If you suspect a problem near a line of code, you can set a breakpoint at 

that line and run the program. When the line is reached, execution is interrupted. You can check variable values, examine the stack trace, and observe the program's environment. You can single-step through the program, checking values. You can resume 
execution at any point. By using breakpoints, you can discover many of the bugs in your code that you've missed.

<BR></P>

<P>cpp is another tool that can be used to debug programs. It will perform macro replacements, include headers, and parse the code. The output is the actual module to be compiled. Normally, though, cpp is never executed by the programmer directly. Instead 

it is invoked through cc with either a -E or -P option. -E will put the output directly to the terminal; -P will make a file with a .i suffix.

<BR></P>

<H3 ALIGN="CENTER">

<CENTER><A ID="I21" NAME="I21">

<FONT SIZE=4><B>Summary</B>

<BR></FONT></A></CENTER></H3>

<P>In this chapter, we've discussed the basics of the C language: building C programs, running them, and debugging them. While this overview isn't enough to make you an expert C programmer, you can now understand how programmers develop their products. You 

should also be able to read a C program and know what the program is doing.

<BR></P>

<P><A HREF="unx16.htm"><IMG SRC="bluprev.gif" WIDTH = 32 HEIGHT = 32 BORDER = 0 ALT="Previous Page"></A>

<A HREF="index.htm"><IMG SRC="blutoc.gif" WIDTH = 32 HEIGHT = 32 BORDER = 0 ALT="TOC"></A>

<A HREF="unxpt4au.htm"><IMG SRC="blunext.gif" WIDTH = 32 HEIGHT = 32 BORDER = 0 ALT="Next Page"></A>

<A HREF="index.htm"><IMG SRC="bluprev.gif" WIDTH = 32 HEIGHT = 32 BORDER = 0 ALT="Home"></A>

</P></BODY></HTML>

⌨️ 快捷键说明

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