C –FAQ:

Description
1. C –FAQ:Q: How should I decide which integer type to use?A: If you might need large values (above 32,767 or below -32,767), uselong. Otherwise, if space is very…

Please download to get full document.

View again

of 85
All materials on our website are shared by users. If you have any questions about copyright issues, please report us to resolve them. We are always happy to assist you.
Information
Category:

Education

Publish on:

Views: 0 | Pages: 85

Extension: PDF | Download: 0

Share
Transcript
  • 1. C –FAQ:Q: How should I decide which integer type to use?A: If you might need large values (above 32,767 or below -32,767), uselong. Otherwise, if space is very important (i.e. if there are large arrays or manystructures), use short. Otherwise, use int. If well-defined overflow characteristicsare important and negative values are not, or if you want to steer clear of sign-extension problems when manipulating bits or bytes, use one of thecorresponding unsigned types.Although character types (especially unsigned char) can be used as ``tinyintegers, doing so is sometimes more trouble than its worth. The compiler willhave to emit extra code to convert between char and int (making the executablelarger), and unexpected sign extension can be troublesome.A similar space/time tradeoff applies when deciding between float and double.(Many compilers still convert all float values to double during expressionevaluation.) None of the above rules apply if pointers to the variable must have aparticular type.Base Minimum Minimum Maximum Maximumtype size(bits) value(signed) value(signed) value(unsigned)Char 8 -127 127 255Short 16 -32767 32767 65535Int 16 -32767 32767 65535long 32- -2,147,483,647 2,147,483,647 4,294,967,295Q: Why arent the sizes of the standard types precisely defined?A: Though C is considered relatively low-level as high-level languages go, itdoes take the position that the exact size of an object (i.e. in bits) is animplementation detail. Most programs do not need precise control over thesesizes; many programs that do try to achieve this control would be better off ifthey didnt.
  • 2. Type int is supposed to represent a machines natural word size. Its the righttype to use for most integer variables;Q: Since C doesnt define sizes exactly, Ive been using typedefs like int16and int32. I can then define these typedefs to be int, short, long, etc. dependingon what machine Im using. That should solve everything, right?A: If you truly need control over exact type sizes, this is the right approach.There remain several things to be aware of: • There might not be an exact match on some machines. (There are, for example, 36-bit machines.) • A typedef like int16 or int32 accomplishes nothing if its intended meaning is ``at least the specified size, because types int and long are already essentially defined as being ``at least 16 bits and ``at least 32 bits, respectively. • Typedefs will never do anything about byte order problems (e.g. if youre trying to interchange data or conform to externally-imposed storage layouts). • You no longer have to define your own typedefs, because the Standard header <inttypes.h> contains a complete set.Q: What should the 64-bit type be on a machine that can support it?A: The new C99 Standard specifies type long long as effectively being atleast 64 bits, and this type has been implemented by a number of compilers forsome time. (Others have implemented extensions such as __longlong.) On theother hand, its also appropriate to implement type short int as 16, int as 32,and long int as 64 bits, and some compilers do.
  • 3. Q: Whats wrong with this declaration?char* p1, p2;I get errors when I try to use p2.A: Nothing is wrong with the declaration--except that it doesnt do what youprobably want. The * in a pointer declaration is not part of the base type; it ispart of the declarator containing the name being declared . The correct form is:char *p1, *p2;Q: Im trying to declare a pointer and allocate some space for it, but its notworking. Whats wrong with this code?char *p;*p = malloc(10);A: The pointer you declared is p, not *p.Q: Why is this loop always executing once? 1.for(i = start; i < end; i++); 2. { 3. printf("%dn", i); 4. }
  • 4. A: The accidental extra semicolon hiding at the end of the line 1 so thereoccurs an error.Q: I cant seem to define a linked list successfully. I tried typedef struct { char *item; NODEPTR next; } *NODEPTR;but the compiler gave me error messages. Cant a structure in C contain a pointerto itself?A: The correct form is that : 1. To fix this code, first give the structure a tag (e.g. ``struct node). Then, declare the next field as a simple struct node *, or disentangle the typedef declaration from the structure definition, or both. One corrected version would be: typedef struct node { char *item; struct node*next; } *NODEPTR; Or typedef struct node*NODEPTR; struct node { char *item; NODEPTRnext; }; 2. Finally, here is a rearrangement incorporating both suggestions: struct node { char *item; struct node*next; }; typedef struct node *NODEPTR;Q: Whats the difference between const char *p, char const *p?
  • 5. A: The first two are interchangeable; they declare a pointer to a constantcharacter (you cant change any pointed-to characters). char * const p declares aconstant pointer to a (variable) character (i.e. you cant change the pointer).Q: This code, straight out of a book, isnt compiling:int f(){ char a[] = "Hello, world!";}A: Perhaps you have an old, pre-ANSI compiler, which doesnt allowinitialization of ``automatic aggregates (i.e. non-static local arrays, structures,or unions). You have four possible workarounds: • If the array wont be written to or if you wont need a fresh copy during any subsequent calls, you can declare it static (or perhaps make it global). • If the array wont be written to, you could replace it with a pointer: f() { char *a = "Hello, world!"; } You can always initialize local char * variables to point to string literals • If neither of the above conditions hold, youll have to initialize the array by hand with strcpy when the function is called: f() { char a[14]; strcpy(a, "Hello, world!"); } • Get an ANSI-compatible compiler.
  • 6. Q: Whats wrong with this initialization?char *p = malloc(10);My compiler is complaining about an ``invalid initializer, or something.A: Is the declaration of a static or non-local variable? Function calls areallowed in initializers only for automatic variables (that is, for local, non-staticvariables).Q: This program works correctly, but it dumps core after it finishes. Why? 1. struct list { 1. char *item; 2. struct list *next; 2. } /* Here is the main program. */3.main(argc, argv) { ... }A: A missing semicolon at the end of the structure declaration(i.e., line 2)causes main to be declared as returning a structure.Q: Ive experimented with the codeint i = 3;
  • 7. i = i++;on several compilers. Some gave i the value 3, and some gave 4. Which compileris correct?A: There is no correct answer; the expression is undefined. (Also, note thatneither i++ nor ++i is the same as i+1. If you want to increment i, use i=i+1, i+=1,i++, or ++i, not some combination. See also question)Under Cs integral promotion rules, the multiplication is carried out using intarithmetic, and the result may overflow or be truncated before being promotedand assigned to the long int left-hand side. Use an explicit cast on at least one ofthe operands to force long arithmetic: long int c = (long int)a * b;or perhaps long int c = (long int)a * (long int)b;Q: If you cant assign to arrays, then how can int f(char str[]) { if(str[0] == 0) str = "none"; ... }work?A: In this code, str is a function parameter, so its declaration is rewritten bythe compiler. In other words, str is a pointer (of type char *), and it is legal toassign to it.
  • 8. How should I decide which integer type to use?A: If you might need large values (tens of thousands), use long. Otherwise, if space is very important, use short. Otherwise, use int.1.4: What should the 64-bit type be on a machine that can support it?A: C99 specifies long long.1.7: Whats the best way to declare and define global variables?A: The best arrangement is to place each definition in some relevant .c file, with an external declaration in a header file.1.11: What does extern mean in a function declaration?A: Nothing, really; the keyword extern is optional here.1.12: Whats the auto keyword good for?A: Nothing.1.14: I cant seem to define a linked list node which contains a pointer to itself.
  • 9. A: Structures in C can certainly contain pointers to themselves; the discussion and example in section 6.5 of K&R make this clear. Problems arise if an attempt is made to define (and use) a typedef in the midst of such a declaration; avoid this.1.21: How do I declare an array of N pointers to functions returning pointers to functions returning pointers to char?A: char *(*(*a[N])())(); Using a chain of typedefs, or the cdecl program, makes these declarations easier.1.25: My compiler is complaining about an invalid redeclaration of a function, but I only define it once.A: Calling an undeclared function declares it implicitly as returning int.1.25b: Whats the right declaration for main()?A: See questions 11.12a through 11.15.1.30: What am I allowed to assume about the initial values of variables which are not explicitly initialized?A: Uninitialized variables with "static" duration start out as 0,
  • 10. as if the programmer had initialized them. Variables with "automatic" duration, and dynamically-allocated memory, start out containing garbage (with the exception of calloc).1.31: Why cant I initialize a local array with a string?A: Perhaps you have a pre-ANSI compiler.1.31b: Whats wrong with "char *p = malloc(10);" ?A: Function calls are not allowed in initializers for global or static variables.1.32: What is the difference between char a[] = "string"; and char *p = "string"; ?A: The first declares an initialized and modifiable array; the second declares a pointer initialized to a not-necessarily- modifiable constant string.1.34: How do I initialize a pointer to a function?A: Use something like "extern int func(); int (*fp)() = func;" .Section 2. Structures, Unions, and Enumerations
  • 11. 2.1: Whats the difference between struct x1 { ... }; and typedef struct { ... } x2; ?A: The first structure is named by a tag, the second by a typedef name.2.2: Why doesnt "struct x { ... }; x thestruct;" work?A: C is not C++.2.3: Can a structure contain a pointer to itself?A: See question 1.14.2.4: How can I implement opaque (abstract) data types in C?A: One good way is to use structure pointers which point to structure types which are not publicly defined.2.4b: Is there a good way of simulating OOP-style inheritance in C?A: There are some clumsy ways, but nothing like C++.2.6: I came across some code that declared a structure with the last member an array of one element, and then did some tricky
  • 12. allocation to make it act like the array had several elements. Is this legal or portable?A: An official interpretation has deemed that it is not strictly conforming with the C Standard.2.8: Is there a way to compare structures automatically?A: No.2.10: Can I pass constant values to functions which accept structure arguments?A: In C99 you can use "compound literals".2.11: How can I read/write structures from/to data files?A: It is relatively straightforward to use fread and fwrite.2.12: How can I turn off structure padding?A: There is no standard method.2.13: Why does sizeof report a larger size than I expect for a structure type?
  • 13. A: The alignment of arrays of structures must be preserved.2.14: How can I determine the byte offset of a field within a structure?A: ANSI C defines the offsetof() macro in <stddef.h>.2.15: How can I access structure fields by name at run time?A: Build a table of names and offsets, using the offsetof() macro.2.18: I have a program which works correctly, but dumps core after it finishes. Why?A: Check to see if main() is misdeclared, perhaps because a preceding structure type declaration is missing its trailing semicolon, causing main() to be declared as returning a structure. See also questions 10.9 and 16.4.2.20: Can I initialize unions?A: In the original ANSI C, only the first-named member; in C99, using "designated initializers", yes, any member.2.22: Whats the difference between an enumeration and a set of preprocessor #defines?
  • 14. A: There is little difference. The C Standard states that enumerations are compatible with integral types.2.24: Is there an easy way to print enumeration values symbolically?A: No.Section 3. Expressions3.1: Why doesnt the code "a[i] = i++;" work?A: The variable i is both modified and separately referenced in the same expression.3.2: Under my compiler, the code "int i = 7; printf("%dn", i++ * i++);" prints 49. Regardless of the order of evaluation, shouldnt it print 56?A: The operations implied by the postincrement and postdecrement operators ++ and -- are performed at some time after the operands former values are yielded and before the end of the expression, but not necessarily immediately after, or before other parts of the expression are evaluated.3.3: What should the code "int i = 3; i = i++;" do?
  • 15. A: The expression is undefined.3.3b: Heres a slick expression: "a ^= b ^= a ^= b". It swaps a and b without using a temporary.A: Not portably; its behavior is undefined.3.4: Dont precedence and parentheses dictate order of evaluation?A: Operator precedence and explicit parentheses impose only a partial ordering on the evaluation of an expression, which does not generally include the order of side effects.3.5: But what about the && and || operators?A: There is a special exception for these operators: left-to-right evaluation is guaranteed.3.8: Whats a "sequence point"?A: A point (at the end of a full expression, or at the ||, &&, ?:, or comma operators, or just before a function call) at which all side effects are guaranteed to be complete.3.9: So given a[i] = i++; we dont know which cell of a[] gets written to, but i does get incremented by one, right?
  • 16. A: Not necessarily! Once an expression or program becomes undefined, *all* aspects of it become undefined.3.12a: Whats the difference between ++i and i++?A: ++i adds one to i and "returns" the incremented value; i++ returns the prior, unincremented value.3.12b: If Im not using the value of the expression, should I use ++i or i++ to increment a variable?A: Since the two forms differ only in the value yielded, they are entirely equivalent when only their side effect is needed.3.14: Why doesnt the code "int a = 1000, b = 1000; long int c = a * b;" work?A: You must manually cast one of the operands to (long).3.16: Can I use ?: on the left-hand side of an assignment expression?A: No.Section 4. Pointers
  • 17. 4.2: Whats wrong with "char *p; *p = malloc(10);"?A: The pointer you declared is p, not *p.4.3: Does *p++ increment p, or what it points to?A: *p++ increments p. To increment the value pointed to by p, use (*p)++ .4.5: I want to use a char * pointer to step over some ints. Why doesnt "((int *)p)++;" work?A: In C, a cast operator is a conversion operator, and by definition it yields an rvalue, which cannot be assigned to, or incremented with ++.4.8: I have a function which accepts, and is supposed to initialize, a pointer, but the pointer in the caller remains unchanged.A: The called function probably altered only the passed copy of the pointer.4.9: Can I use a void ** pointer as a parameter so that a function can accept a generic pointer by reference?A: Not portably.
  • 18. 4.10: I have a function which accepts a pointer to an int. How can I pass a constant like 5 to it?A: In C99, you can use a "compound literal". Otherwise, declare a temporary variable.4.11: Does C even have "pass by reference"?A: Not really, though it can be simulated.4.12: Ive seen different syntax used for calling functions via pointers.A: The extra parentheses and explicit * are now officially optional, although some older implementations require them.4.15: How do I convert an int to a char *?A: See question 13.1, 8.6, or 19.25, depending on what youre trying to do.Section 5. Null Pointers5.1: What is this infamous null pointer, anyway?
  • 19. A: For each pointer type, there is a special value -- the "null pointer" -- which is distinguishable from all other pointer values and which is not the address of any object or function.5.2: How do I get a null pointer in my programs?A: A constant 0 in a pointer context is converted into a null pointer at compile time. A "pointer context" is an initialization, assignment, or comparison with one side a variable or expression of pointer type, and (in ANSI standard C) a function argument which has a prototype in scope declaring a parameter as being of pointer type. In other contexts (function arguments without prototypes, or in the variable part of variadic function calls) a constant 0 with an appropriate explicit cast is required.5.3: Is the abbreviated pointer comparison "if(p)" to test for non- null pointers valid?A: Yes. The construction "if(p)" works, regardless of the internal representation of null pointers, because the compiler essentially rewrites it as "if(p != 0)" and goes on to convert 0 into the correct null pointer.5.4: What is NULL and how is it defined?A: NULL is simply a preprocessor macro, defined as a null pointer
  • 20. constant, typically 0 or ((void *)0), which is used (as a stylistic convention, in preference to unadorned 0s) to generate null pointers.5.5: How should NULL be defined on a machine which uses a nonzero bit pattern as the internal representation of a null pointer?A: The same as on any other machine: as 0. (The compiler makes the translation, upon seeing a 0, not the preprocessor; see also question 5.4.)5.6: If NULL were defined as "((char *)0)," wouldnt that make function calls which pass an uncast NULL work?A: Not in the most general case. (A cast might still required to tell the compiler which kind of null pointer is required, since it may be different from (char *)0.)5.9: If NULL and 0 are equivalent as null pointer constants, which should I use?A: Either; the distinction is entirely stylistic.5.10: But wouldnt it be better to use NULL, in case the value of NULL changes?A: No. NULL is a constant zero, so a constant zero is equally
  • 21. sufficient.5.12: I use the preprocessor macro "#define Nullptr(type) (type *)0" to help me build null pointers of the correct type.A: This trick, though valid, does not buy much.5.13: This is strange. NULL is guaranteed to be 0, but the null pointer is not?A: A "null pointer" is a language concept whose particular internal value does not matter. A null pointer is requested in source code with the character "0". "NULL" is a preprocessor macro, which is always #defined as 0 (or ((void *)0)).5.14: Why is there so much confusion surrounding null pointers?A: The fact that null pointers are represented both in source code, and internally to most machines, as zero invites unwarranted assumptions. The use of a preprocessor macro (NULL) may seem to suggest that the value could change some day, or on some weird machine.5.15: Im confused. I just cant understand all this null pointer stuff.A: A simple rule is, "Always use `0 or `NULL for null pointers,
  • 22. and always cast them when they are used as arguments in function calls."5.16: Given all the confusion surrounding null pointers, wouldnt it be easier simply to require them to be represented internally by zeroes?A: Such a requirement would accomplish little.5.17: Seriously, have any actual machines really used nonzero null pointers?A: Machines manufactured by Prime, Honeywell-Bull, and CDC, as well as Symbolics Lisp Machines, have done so.5.20: What does a run-time "null pointer assignment" error mean?A: It means that you
  • Related Search
    We Need Your Support
    Thank you for visiting our website and your interest in our free products and services. We are nonprofit website to share and download documents. To the running of this website, we need your help to support us.

    Thanks to everyone for your continued support.

    No, Thanks