1. Trang chủ
  2. » Công Nghệ Thông Tin

IT training c primer plus (5th ed ) prata 2004 12 03

875 263 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 875
Dung lượng 3,88 MB

Nội dung

C Primer Plus, Fifth Edition By Stephen Prata Publisher: Sams Pub Date: November 23, 2004 ISBN: 0-672-32696-5 Table of • Contents • Index Pages: 984 Copyright PREFACE Approach and Goals ABOUT THE AUTHOR ACKNOWLEDGMENTS WE WANT TO HEAR FROM YOU! Chapter Getting Ready Whence C? Why C? Whither C? What Computers Do High-level Computer Languages and Compilers Using C: Seven Steps Programming Mechanics Language Standards How This Book Is Organized Conventions Used in This Book Summary Review Questions Programming Exercise Chapter Introducing C A Simple Example of C The Example Explained The Structure of a Simple Program Tips on Making Your Programs Readable Taking Another Step in Using C While You're at It—Multiple Functions Introducing Debugging Keywords and Reserved Identifiers Key Concepts Summary Review Questions Programming Exercises Chapter Data and C A Sample Program Data Variables and Constants Data: Data-Type Keywords Basic C Data Types Using Data Types Arguments and Pitfalls One More Example: Escape Sequences Key Concepts Summary Review Questions Programming Exercises Chapter Character Strings and Formatted Input/Output Introductory Program Character Strings: An Introduction Constants and the C Preprocessor Exploring and Exploiting printf() and scanf() Key Concepts Summary Review Questions Programming Exercises Chapter Operators, Expressions, and Statements Introducing Loops Fundamental Operators Some Additional Operators Expressions and Statements Type Conversions Function with Arguments A Sample Program Key Concepts Summary Review Questions Programming Exercises Chapter C Control Statements: Looping Revisiting the while Loop The while Statement Which Is Bigger: Using Relational Operators and Expressions Indefinite Loops and Counting Loops The for Loop More Assignment Operators: +=, -=, *=, /=, %= The Comma Operator An Exit-Condition Loop: while Which Loop? Nested Loops Introducing Arrays A Loop Example Using a Function Return Value Key Concepts Summary Review Questions Programming Exercises Chapter C Control Statements: Branching and Jumps The if Statement Adding else to the if Statement Let's Get Logical A Word-Count Program The Conditional Operator: ?: Loop Aids: continue and break Multiple Choice: switch and break The goto Statement Key Concepts Summary Review Questions Programming Exercises Chapter Character Input/Output and Input Validation Single-Character I/O: getchar() and putchar() Buffers Terminating Keyboard Input Redirection and Files Creating a Friendlier User Interface Input Validation Menu Browsing Key Concepts Summary Review Questions Programming Exercises Chapter Functions Reviewing Functions ANSI C Function Prototyping Recursion Compiling Programs with Two or More Source Code Files Finding Addresses: The & Operator Altering Variables in the Calling Function Pointers: A First Look Key Concepts Summary Review Questions Programming Exercises Chapter 10 Arrays and Pointers Arrays Multidimensional Arrays Pointers and Arrays Functions, Arrays, and Pointers Pointer Operations Protecting Array Contents Pointers and Multidimensional Arrays Variable-Length Arrays (VLAs) Compound Literals Key Concepts Summary Review Questions Programming Exercises Chapter 11 Character Strings and String Functions Representing Strings and String I/O String Input String Output The Do-It-Yourself Option String Functions A String Example: Sorting Strings The ctype.h Character Functions and Strings Command-Line Arguments String-to-Number Conversions Key Concepts Summary Review Questions Programming Exercises Chapter 12 Storage Classes, Linkage, and Memory Management Storage Classes Storage-Class Specifiers Storage Classes and Functions A Random-Number Function and a Static Variable Roll 'Em Allocated Memory: malloc() and free() ANSI C Type Qualifiers Key Concepts Summary Review Questions Programming Exercises Chapter 13 File Input/Output Communicating with Files Standard I/O A Simple-Minded File-Condensing Program File I/O: fprintf(), fscanf(), fgets(), and fputs() Adventures in Random Access: fseek() and ftell() Behind the Scenes with Standard I/O Other Standard I/O Functions Key Concepts Summary Review Questions Programming Exercises Chapter 14 Structures and Other Data Forms Sample Problem: Creating an Inventory of Books Setting Up the Structure Declaration Defining a Structure Variable Arrays of Structures Nested Structures Pointers to Structures Telling Functions About Structures Saving the Structure Contents in a File Structures: What Next? Unions: A Quick Look Enumerated Types typedef: A Quick Look Fancy Declarations Functions and Pointers Key Concepts Summary Review Questions Programming Exercises Chapter 15 Bit Fiddling Binary Numbers, Bits, and Bytes Other Number Bases C's Bitwise Operators Bit Fields Key Concepts Summary Review Questions Programming Exercises Chapter 16 The C Preprocessor and the C Library First Steps in Translating a Program Manifest Constants: #define Using Arguments with #define Macro or Function? File Inclusion: #include Other Directives Inline Functions The C Library The Math Library The General Utilities Library The Assert Library memcpy() and memmove() from the string.h Library Variable Arguments: stdarg.h Key Concepts Summary Review Questions Programming Exercises Chapter 17 Advanced Data Representation Exploring Data Representation Beyond the Array to the Linked List Abstract Data Types (ADTs) Getting Queued with an ADT Simulating with a Queue The Linked List Versus the Array Binary Search Trees Other Directions Key Concepts Summary Review Questions Programming Exercises Appendix A Answers to the Review Quesions Answers to Review Questions for Chapter Answers to Review Questions for Chapter Answers to Review Questions for Chapter Answers to Review Questions for Chapter Answers to Review Questions for Chapter Answers to Review Questions for Chapter Answers to Review Questions for Chapter Answers to Review Questions for Chapter Answers to Review Questions for Chapter Answers to Review Questions for Chapter 10 Answers to Review Questions for Chapter 11 Answers to Review Questions for Chapter 12 Answers to Review Questions for Chapter 13 Answers to Review Questions for Chapter 14 Answers to Review Questions for Chapter 15 Answers to Review Questions for Chapter 16 Answers to Review Questions for Chapter 17 Appendix B Reference Section Section I: Additional Reading Section II: C Operators Section III: Basic Types and Storage Classes Section IV: Expressions, Statements, and Program Flow Section V: The Standard ANSI C Library with C99 Additions Section VI: Extended Integer Types Section VII: Expanded Character Support Section VIII: C99 Numeric Computational Enhancements Section IX: Differences Between C and C++ Index Copyright Copyright © 2005 by Sams Publishing All rights reserved No part of this book shall be reproduced, stored in a retrieval system, or transmitted by any means, electronic, mechanical, photocopying, recording, or otherwise, without written permission from the publisher No patent liability is assumed with respect to the use of the information contained herein Although every precaution has been taken in the preparation of this book, the publisher and author assume no responsibility for errors or omissions Nor is any liability assumed for damages resulting from the use of the information contained herein Printed in the United States of America First Printing: November, 2004 07 06 05 04 Trademarks All terms mentioned in this book that are known to be trademarks or service marks have been appropriately capitalized Sams Publishing cannot attest to the accuracy of this information Use of a term in this book should not be regarded as affecting the validity of any trademark or service mark Warning and Disclaimer Every effort has been made to make this book as complete and as accurate as possible, but no warranty or fitness is implied The information provided is on an "as is" basis Bulk Sales Sams Publishing offers excellent discounts on this book when ordered in quantity for bulk purchases or special sales For more information, please contact U.S Corporate and Government Sales 1-800-382-3419 corpsales@pearsontechgroup.com For sales outside of the U.S., please contact International Sales international@pearsoned.com Credits ASSOCIATE PUBLISHER Michael Stephens ACQUISITIONS EDITOR Loretta Yates MANAGING EDITOR Charlotte Clapp DEVELOPMENT EDITOR Songlin Qiu PROJECT EDITOR George E Nedeff COPY EDITOR Bart Reed INDEXER Chris Barrick PROOFREADER Paula Lowell TECHNICAL EDITOR Greg Perry PUBLISHING COORDINATOR Cindy Teeters MULTIMEDIA DEVELOPER Dan Scherf BOOK DESIGNER Gary Adair PAGE LAYOUT Bronkella Publishing DEDICATION With love to Vicky and Bill Prata, who, for more than 69 years, have been showing how rewarding a marriage can be —SP The inttypes.h header file (via the included stdint.h header file) defines two integer types, listed in Table RS.VI.5, that can hold pointer values accurately That is, if you assign a type void * value to one of these types, and then assign the integer type back to the pointer, no information is lost Either or both types might not exist Table RS.VI.5 Integer Types for Holding Pointer Values Type Name printf() Specifier scanf() Specifier Minimum Value Maximum Value intptr_t PRIdPTR SCNdPTR INTPTR_MIN INTPTR_MAX uintptr_t PRIuPTR SCBuPTR UINTPTR_MAX Extended Integer Constants You can indicate a long constant with the L suffix, as in 445566L How you indicate that a constant is type int32_t? Use macros defined in inttypes.h For example, the expression INT32_C(445566) expands to a type int32_t constant Essentially, the macro is a type cast to the underlying type—that is, to the fundamental type that represents int32_t in a particular implementation The macro names are formed by taking the type name, replacing the _t with _C, and making all the letters uppercase For example, to make 1000 a type uint_least64_t constant, use the expression UINT_LEAST64_C(1000) Section VII: Expanded Character Support C wasn't designed originally as an international programming language Its choice of characters was based on the more or less standard U.S keyboard The international popularity of C, however, has led to several extensions supporting different and larger character sets This section of the reference provides an overview of these additions Trigraph Sequences Some keyboards don't provide all the symbols used in C Therefore, C provides alternative representations of several symbols with a set of three-character sequences, called trigraph sequences Table RS.VII.1 lists these trigraphs Table RS.VII.1 Trigraph Sequences Trigraph Symbol Trigraph Symbol Trigraph Symbol ??= # ??( [ ??/ \ ??) ] ??' ^ ??< { ??! | ??> } ??- ~ C replaces all occurrences of these trigraphs in a source code file, even in a quoted string, with the corresponding symbol Thus, ??=include ??=define LIM 100 int main() ??< int q??(LIM??); printf("More to come.??/n"); ??> becomes the following: #include #define LIM 100 int main() { int q[LIM]; printf("More to come.\n"); } You may have to turn on a compiler flag to activate this feature Digraphs Recognizing the clumsiness of the trigraph system, C99 provides two-character tokens, called digraphs, that can be used instead of certain standard C punctuators Table RS.VII.2 lists these digraphs Table RS.VII.2 Digraphs Digraph Symbol Digraph Symbol Digraph Symbol ] } %: # %:%: ## Unlike trigraphs, digraphs within a quoted string have no special meaning Thus, %:include %:define LIM 100 int main() behaves the same as the following: #include #define LIM 100 int main() { int q[LIM]; printf("More to come.:>"); } // :> just part of string // :> same as } Alternative Spellings: iso646.h Using trigraph sequences, you can write the || operator as ??!??!, which is a bit unappealing C99, via the iso646.h header, provides macros that expand into operators, as shown in Table RS.VII.3 The standard refers to these macros as alternative spellings Table RS.VII.3 Alternative Spellings Macro Operator Macro Operator Macro Operator and && and_eq &= bitand & bitor | compl ~ not ! not_eq != or || or_eq |= xor xor_eq ^= ^ If you include the iso646.h header file, a statement such as if(x == M1 or x == M2) x and_eq 0XFF; is expanded to the following: if(x == M1 || x == M2) x &= 0XFF; Multibyte Characters The standard describes a multibyte character as a sequence of one or more bytes representing a member of the extended character set of either the source or execution environment The source environment is the one in which you prepare the source code; the execution environment is the one in which you run the compiled program The two can be different For example, you could develop a program in one environment with the intent of running in another environment The extended character set is a superset of the basic character set that C requires An implementation may provide an extended character set that allows you, for example, to enter keyboard characters not corresponding to the basic character set These can be used in string literals and character constants and can appear in files An implementation may also provide multibyte equivalents of characters in the basic character set that can be used instead of trigraphs or digraphs A German implementation, for example, might allow you to use an umlauted character in a string: puts("eins zwei drei vier fünf"); Universal Character Names (UCNs) Multibyte characters can be used in strings but not in identifiers Universal character names (UCNs) are a C99 addition that allows you to use characters from an extended character set as part of identifier names The system extends the escape sequence concept to allow encoding of characters from the ISO/IEC 10646 standard This standard is the joint work of the International Organization for Standardization (ISO) and the International Electrotechnical Commission (IEC) and provides numeric codes for a vast list of characters There are two forms of UCN sequences The first is \u hexquad, where hexquad is a sequence of four hexadecimal digits; \u00F6 is an example The second is \U hexquad hexquad; \U0000AC01 is an example Because each hexadecimal digit corresponds to four bits, the \u form can be used for codes representable by a 16-bit integer, and the \U form can be used for codes representable by a 32-bit integer If your system implements UCNs and includes the desired characters in the extended character set, UCNs can be used in strings, character constants, and identifiers: wchar_t value\u00F6\u00F8 = '\u00f6'; Wide Characters C99, through the wchar.h and wctype.h libraries, provides yet more support for larger character sets through the use of wide characters These header files define wchar_t as an integer type; the exact type is implementation dependent Its intended use is to hold characters from an extended character set that is a superset of the basic character set By definition, the char type is sufficient to handle the basic character set The wchar_t type may need more bits to handle a greater range of code values For example, char might be an 8-bit byte and wchar_t might be a 16-bit unsigned short Wide-character constants and string literals are indicated with an L prefix, and you can use the %lc and %ls modifiers to display wide-character data: wchar_t wch = L'I'; wchar_t w_arr[20] = L"am wide!"; printf("%lc %ls\n", wch, w_arr); If, for example, wchar_t is implemented as a 2-byte unit, the 1-byte code for 'I' would be stored in the low-order byte of wch Characters not from the standard set might require both bytes to hold the character code You could use universal character codes, for example, to indicate characters whose code values exceed the char range: wchar_t w = L'\u00E2'; /* 16-bit code value */ An array of wchar_t values can hold a wide-character string, with each element holding a single wide-character code A wchar_t value with a code value of is the wchar_t equivalent of the null character, and it is termed a null wide character It is used to terminate wide-character strings You can use the %lc and %ls specifiers to read wide characters: wchar_t wch; wchar_t w_arr[20]; puts("Enter your grade:"); scanf("%lc", &wch); puts("Enter your first name:"); scanff("%ls",w_arr); The wchar.h header file offers further wide-character support In particular, it provides wide-character I/O functions, wide-character conversion functions, and wide-character string-manipulation functions For the most part, they are widecharacter equivalents of existing functions For example, you can use fwprintf() and wprintf() for output and fwscanf() and wscanf() for input The main differences are that these functions require a wide-character control string and they deal with input and output streams of wide characters For example, the following displays information as a sequence of wide characters: wchar_t * pw = L"Points to a wide-character string"; int dozen = 12; wprintf(L"Item %d: %ls\n", dozen, pw); Similarly, there are getwchar(), putwchar(), fgetws(), and fputws() functions The header defines a WEOF macro that plays the same role that EOF does for byteoriented I/O It's required to be a value that does not correspond to a valid character Because it is possible that all values of wchar_t type are valid characters, the library defines a wint_t type that can encompass all wchar_t values plus WEOF There are equivalents to the string.h library functions For example, wcscpy(ws2, ws1) copies the wide-character string pointed to by ws1 to the wide-character array pointed to by ws2 Similarly, there is a wcscmp() function for comparing wide strings, and so on The wctype.h header file adds character-classification functions to the mix For example, iswdigit() returns true if its wide-character argument is a digit, and the iswblank() function returns true if its argument is a blank The standard values for a blank are a space, written as L' ', and a horizontal tab, written as L'\t' Wide Characters and Multibyte Characters Wide characters and multibyte characters are two different approaches to dealing with extended character sets A multibyte character, for example, might be a single byte, two bytes, three bytes, or more All wide characters will have just one width Multibyte characters might use a shift state (that is, a byte that determines how subsequent bytes are interpreted); wide characters don't have a shift state A file of multibyte characters would be read into an ordinary array of char using the standard input functions; a file of wide characters would be read into a wide-character array using one of the wide-character input functions C99, through the wchar.h library, provides functions for converting between these two representations The mbrtowc() function converts a multibyte character to a wide character, and the wcrtomb() function converts a wide character to a multibyte character Similarly, the mbstrtowcs() function converts a multibyte string to a wide character string, and the wcstrtombs() function converts a wide character string to a multibyte string Section VIII: C99 Numeric Computational Enhancements Historically, FORTRAN has been the premier language for numerical scientific and engineering computation C90 brought C computational methods into closer agreement with FORTRAN For example, the specification of floating-point characteristics used in float.h is based on the model developed by the FORTRAN standardization committee The C99 standard continues the work of enhancing C's appropriateness for computational work The IEC Floating-Point Standard The International Electotechnical Committee (IEC) has published a standard for floating-point calculations (IEC 60559) The standard includes discussion of floating-point formats, precision, NaNs, infinities, rounding practices, conversions, exceptions, recommended functions and algorithms, and so on C99 accepts this standard as a guide to the C implementation of floating-point calculations Most of the C99 additions to floating-point facilities are part of this effort, such as the fenv.h header file and several of the new math functions However, it could be that an implementation doesn't meet all the requirements of IEC 60559; for example, the underlying hardware may not be up to the task Therefore, C99 defines two macros that can be used in preprocessor directives to check for compliance First, the macro STDC_IEC_559 is conditionally defined as the constant if the implementation conforms to IEC 60559 floating-point specifications Second, the macro STDC_IEC_559_COMPLEX is conditionally defined as the constant if the implementation adheres to IEC 60559–compatible complex arithmetic If an implementation doesn't define these macros, there is no guarantee of IEC60559 compliance The fenv.h Header File The fenv.h header file provides a means of interacting with the floating-point environment That is, it allows you to set floating-point control mode values that govern how floating-point calculations take place, and it allows you to determine the value of floating-point status flags, or exceptions, that report information about the effects of an arithmetic calculation An example of a control mode setting is specifying the method used to round numbers An example of a status flag is a flag that is set if an operation produces floating-point overflow An operation that sets a status flag is described as raising an exception The status flags and control modes are meaningful only if the hardware supports them For example, you can't change the rounding method if the hardware doesn't have that option You use a preprocessor directive to turn support on: #pragma STDC FENV_ACCESS ON Support stays on until the program reaches the end of the block containing the pragma, or, if the pragma is external, to the end of the file or translation unit Alternatively, you can use the following directive to turn off support: #pragma STDC FENV_ACCESS OFF You also can issue the following pragma: #pragma STDC FENV_ACCESS DEFAULT This restores the default state for the compiler, which is implementation dependent This facility is important for those involved in critical floating-point calculations, but of limited interest to the general user, so this appendix doesn't go into the details The STDC FP_CONTRACT Pragma Some floating-point processors can contract a multiple-operator floating- expression into a single operation For example, a processor might be able to evaluate the following expression in one step: x*y - z This increases the speed of the calculation, but it can decrease the predictability of the calculation The STDC FP_CONTRACT pragma allows you to turn this feature on or off The default state is implementation dependent To turn the contraction feature off for a particular calculation, and then turn it back on again, you can this: #pragma STDC FP_CONTRACT OFF val = x * y - z; #pragma STDC FP_CONTRACT ON Additions to the math.h Library The C90 math library, for the most part, declares functions with type double arguments and type double return values, such as the following double sin(double); double sqrt(double); The C99 library provides type float and type long double versions of all these functions These functions use an f or an l suffix in the name, as follows: float sinf(float); long double sinl(long double); /* float version of sin() */ /* long double version of sin() */ Having function families with different levels of precision allows you to choose the most efficient combination of types and functions needed for a particular purpose C99 also adds several functions commonly used in scientific, engineering, and mathematical computations Table RS.V.14, which lists the type double versions of all the math functions, identifies the C99 additions In many cases, the functions return values that could be calculated using existing functions, but the new functions so faster or more accurately For instance, log1p(x) represents the same value as log(1 + x), but log1p(x) uses a different algorithm, one that is more accurate for small values of x So you would use the log() function for calculations in general, but you would use log1p() for small values of x if high accuracy were critical In addition to these functions, the math library defines several constants and functions related to classifying numbers and rounding them For example, a value can be classified as being infinite, not a number (NaN), normal, subnormal, and true zero (NaN is a special value indicating that a value is not a number; for example, asin(2.0) returns NaN because asin() is defined only for arguments in the range -1 to A subnormal number is one whose magnitude is smaller than the smallest value that can be represented to full precision.) There are also specialized comparison functions that behave differently from the standard relational operators when one or more arguments are abnormal values You can use C99's classification schemes to detect computational irregularities For example, the isnormal() macro from math.h returns true if its argument is a normal number Here is code using that function to terminate a loop when a number becomes subnormal: #include // for isnormal() float num = 1.7e-19; float numprev = num; while (isnormal(num)) // while num has full float precision { numprev = num; num /= 13.7f; } In short, there is expanded support for detailed control of how floating-point calculations are handled Support for Complex Numbers A complex number is a number with a real part and an imaginary part The real part is an ordinary real number, such as what's represented by the floating-point types The imaginary part represents an imaginary number An imaginary number, in turn, is a multiple of the square root of –1 In mathematics, complex numbers are often written in the form 4.2 + 2.0i; i symbolically represents the square root of –1 C99 supports three complex types: • • • float _Complex double _Complex long double _Complex A float _Complex value, for example, would be stored using the same memory layout as a two-element array of float, with the real value stored in the first element and the imaginary value in the second element C99 implementations may also support three imaginary types: • • • float _Imaginary double _Imaginary long double _Imaginary Including the complex.h header file lets you use complex for _Complex and imaginary for _Imaginary Arithmetic operations are defined for complex types following the usual rules of mathematics For example, the value of (a+b*I)*(c+d*I) is (a*cb*d)+(b*c+a*d)*I The complex.h header file defines some macros and several functions that accept complex numbers and return complex numbers In particular, the macro I represents the square root of –1 It enables you the following: double complex c1 = 4.2 + 2.0 * I; float imaginary c2= -3.0 * I; The complex.h header file prototypes several complex functions Many are complex equivalents of math.h functions, using a c prefix For example, csin() returns the complex sine of its complex argument Others relate specifically to the features of complex numbers For example, creal() returns the real part of a complex number, and cimag() returns the imaginary part as a real number That is, given that z is type double complex, the following is true: z = creal(z) + cimag(z) * I; If you are familiar with complex numbers and need to use them, you'll want to peruse the contents of complex.h If you use C++, you should be aware that the C++ complex header file provides a different way, based on classes, of handling complex numbers than does the C complex.h header file Section IX: Differences Between C and C++ For the most part, C++ is a superset of C, meaning that a valid C program is also a valid C++ program The main differences between C++ and C are the many additional features that C++ supports However, there are a few areas in which the C++ rules are slightly different from the C equivalents These are the differences that might cause a C program to work a little differently, or perhaps, not at all, if you compile it as a C++ program And these are the differences this appendix discusses If you compile your C programs using a compiler that does just C++ and not C, you need to know about these differences Although they affect very few of the examples in this book, the differences can cause some instances of valid C code to lead to error messages if the code is compiled as a C++ program The release of the C99 standard complicates issues because in some places it brings C closer to C++ For example, it allows interspersing declarations throughout the body of the code and recognizes the // comment indicator In other ways, C99 increases the separation from C++—for example, by adding variable arrays and the restrict keyword With C99 still in its infancy, we're faced with differences between C90 and C99, C90 and C++, and C99 and C++ But eventually, C99 will completely replace C90, so this section will face the future and discuss some of differences between C99 and C++ Function Prototypes In C++, function prototyping is mandatory, but it is optional in C This difference shows up if you leave the parentheses empty when declaring a function In C, empty parentheses mean you are foregoing prototyping, but in C++ they mean the function has no parameters That is, in C++, the prototype int slice(); means the same as the following: int slice(void); For example, the following sequence is acceptable, if old-fashioned, in C but an error in C++: int slice(); int main() { slice(20, 50); } int slice(int a, int b) { } In C, the compiler assumes you used the older form for declaring functions In C++, the compiler assumes that slice() is the same as slice(void) and that you failed to declare the slice(int, int) function Also, C++ allows you to declare more than one function of the same name, provided they have different argument lists char Constants C treats char constants as type int, and C++ treats them as type char For instance, consider this statement: char ch = 'A'; In C, the constant 'A' is stored in an int-sized chunk of memory; more precisely, the character code is stored in the int The same numeric value is also stored in the variable ch, but here it occupies just one byte of memory C++, on the other hand, uses one byte for 'A', as well as for ch This distinction doesn't affect any of the examples in this text However, some C programs make use of char constants being type int by using character notation to represent integer values For instance, if a system has a 4-byte int, you can this in C: int x = 'ABCD'; /* ok in C for 4-byte int but not for C++ */ The meaning of 'ABCD' is a 4-byte int in which the first byte stores the character code for the letter A, the second byte stores the character code of B, and so on Note that 'ABCD' is something quite different from "ABCD" The former is just a funny way of writing an int value, but the latter is a string and corresponds to the address of a 5-byte chunk of memory Consider the following code: int x = 'ABCD'; char c = 'ABCD'; printf("%d %d %c %c\n", x, 'ABCD', c, 'ABCD'); On our system, it produces this output: 1094861636 1094861636 D D This example illustrates that if you treat 'ABCD' as an int, it is a 4-byte integer value, but if you treat it as type char, the program looks only at the final byte Attempting to print 'ABCD' by using the %s specifier caused the program to crash on our system, because the numeric value of 'ABCD' (1094861636) was an outof-bounds address The rationale for using values such as 'ABCD' is that it provides a means to set each byte in the int independently, because each character corresponds exactly to one byte However, a better approach, because it doesn't depend on particular character codes, is to use hexadecimal values for integer constants, using the fact that each two-digit hexadecimal group corresponds to one byte Chapter 15, "Bit Fiddling," discusses this technique (Early versions of C didn't provide hexadecimal notation, which probably is why the multicharacter character constant technique was developed in the first place.) The const Modifier In C, a global const has external linkage, but in C++, it has internal linkage That is, the C++ declaration const double PI = 3.14159; is equivalent to the C declaration static const double PI = 3.14159; provided both declarations are outside of any function The C++ rule has the goal of making it simpler to use const in header files If the constant has internal linkage, each file that includes the header file gets its own copy of the constant If a constant has external linkage, one file has to have a defining declaration and the other files have to have a reference declaration, one that uses the keyword extern Incidentally, C++ can use the keyword extern to make a const value have external linkage, so both languages can create constants with internal linkage and external linkage The difference is just in which kind of linkage is used by default One additional property of the C++ const is that it can be used to declare the size of an ordinary array: const int ARSIZE = 100; double loons[ARSIZE]; /* in C++, same as double loons[100]; */ You can make the same declarations in C99, but in C99, the declaration creates a variable array In C++, but not in C, you can use const values to initialize other const values: const double RATE = 0.06; const double STEP = 24.5; const double LEVEL = RATE * STEP; // valid C++, C // valid C++, C // valid C++, invalid C Structures and Unions After you declare a structure or union having a tag, you can use the tag as a type name in C++: struct { int int }; struct duo n; duo a; b; duo m; /* valid C, C++ */ /* invalid C, valid C++ */ As a result, a structure name can conflict with a variable name For example, the following program compiles as a C program, but it fails as a C++ program because C++ interprets duo in the printf() statement as a structure type rather than as the external variable: #include float duo = 100.3; int main(void) { struct duo { int a; int b;}; struct duo y = { 2, 4}; printf ("%f\n", duo); /* ok in C, not in C++ */ return 0; } In C and in C++, you can declare one structure inside another: struct box { struct point {int x; int y; } upperleft; struct point lowerright; }; In C, you can use either structure later, but C++ requires a special notation for the nested structure: struct box ad; /* valid C, C++ */ struct point dot; /* valid C, invalid C++ */ box::point dot; /* invalid C, valid C++ */ Enumerations C++ is stricter about using enumerations than C is In particular, about the only useful things you can with an enum variable are assign an enum constant to it and compare it to other values You can't assign ints to an enum without an explicit type cast, and you can't increment an enum variable The following code illustrates these points: enum sample {sage, thyme, enum sample season; season = sage; season = 2; season = (enum sample) 3; season++; salt, pepper}; /* /* /* /* ok in C, C++ */ warning in C, error in C++ */ ok in C, C++ */ ok in C, error in C++ */ Also, C++ lets you drop the keyword enum when declaring a variable: enum sample {sage, thyme, salt, pepper}; sample season; /* invalid C, valid C++ */ As was the case with structures and unions, this can lead to conflicts if a variable and an enum type have the same name Pointer-to-void In C++, as in C, you can assign a pointer of any type to a pointer-to-void, but, unlike in C, you cannot assign a pointer-to-void to another type unless you use an explicit type cast The following code illustrates these points: int ar[5] = {4, 5, int * pi; void * pv; pv = ar; pi = pv; pi = (int * ) pv; 6,7, 8}; /* ok in C, C++ */ /* ok in C, invalid in C++ */ /* ok in C, C++ */ Another difference in C++ is that you can assign the address of a derived-class object to a base-class pointer, but that relates to features that don't even exist in C Boolean Types In C++, the Boolean type is bool, and true and false are keywords In C, the Boolean type is _Bool, but including the header file stdbool.h makes bool, true, and false available Alternative Spellings In C++, the alternative spellings of or for ||, and so on, are keywords In C99, they are defined as macros, and you need to include iso646.h to make them available Wide-Character Support In C++, wchar_t is a built-int type, and wchar_t is a keyword In C99, the wchar_t type is defined in several header files (stdde ... linking a source code file called concrete .c produces a file called concrete.exe Some compilers provide an option to create an executable named concrete.com instead In either case, you can run the... Yates MANAGING EDITOR Charlotte Clapp DEVELOPMENT EDITOR Songlin Qiu PROJECT EDITOR George E Nedeff COPY EDITOR Bart Reed INDEXER Chris Barrick PROOFREADER Paula Lowell TECHNICAL EDITOR Greg Perry... Ritchie (197 8) became the accepted standard, usually referred to as K&R C or classic C In particular, the "C Reference Manual" in that book's appendix acted as the guide to C implementations Compilers,

Ngày đăng: 05/11/2019, 16:02

TỪ KHÓA LIÊN QUAN