C language Standard
in 1978, Dennis Ritchie (Dennis Ritchie) and Brian Kernighan published the first edition of the "C programming language". The C language standard described in the book is also called "K&r C" by C language programmers, and the second edition contains some ANSI C standards. K&r c mainly introduces the following features:
Structure (struct) type
Long int type
unsigned integer (unsigned int) type
Change the operator =+ and =-to + = and =. Because =+ and =-will cause the compiler to not know if the user is going to process i = +10 or I =-10, it makes the processing confusing.
Even after many years after the ANSI C standard was proposed, K&r C is still the minimum standard for many compilers, and many of the older compilations still run the K&r C standard.
C89
1989, the C language was standardized by ANSI (ANSI x3.159-1989). One purpose of standardization is to extend K&r C. This standard includes a number of new features. After the publication of K&r, some new features were unofficially added to the C language.
void function
function returns the struct or union type
void * Data type
In the process of ANSI standardization, some new features were added. ANSI also provides a set of standard function libraries. ANSI ISO (International Organization for Standardization) set up the ISO/IEC JTC1/SC22/WG14 Working Group to stipulate the international standard C language. Through minor modifications to the ANSI standard, ISO 9,899:1990 was eventually passed. Subsequently, ISO standards are adopted by ANSI.
Improvements to the traditional C-language to Ansi/iso standard C language include:
Added a real library of standards
New preprocessing commands and features
function prototypes allow specifying parameter types in function declarations
Some new keywords, including const, volatile and signed
Wide character, wide string and byte multi-character
Many minor changes and clarifications to the rules of engagement, declarations, and type checks
After the WG14 Working Group, in 1995, two technical revisions (defect fixes) and a supplement (extension) were made to the standards promulgated in 1985. Here are all the changes made in 1995:
3 new Standard library header files Iso646.h, wctype.h and Wchar.h
Several new notations and predefined macros for better support for internationalization
printf/sprintf function A series of new format codes
A large number of functions and some types and constants for multibyte and wide-byte characters
C99
After the ANSI standard was established, the C language specification has not changed much in a period of time, but C + + has continued to grow and develop in its own standardization establishment process. Standard Amendment one established a new standard for C in 1995, but only revised the details of some C89 standards and added more and wider international character set support. However, this standard leads to the publication of ISO 9,899:1999 in 1999. It is usually become C99. C99 was adopted by ANSI in March 2000.
The features included in the C99 are:
Increased compiler restrictions, such as the source program required to support at least 4095 bytes per line, variable name function name requirements support to 63 bytes (extern request support to 31)
The preprocessing is enhanced. For example:
Macros support taking variable parameters #define MACRO (...) __va_args__
When using macros, if the arguments are not written, things like #,## in macros will expand into empty strings. (It would have been a mistake before)
Support//Line comment (this feature is actually supported on many compilers of C89)
Added new keyword restrict, inline, _complex, _imaginary, _bool
Supports long long, long double _complex, float _complex type
Support for::> <%%>%:%:%:, and so on strange symbol substitution, d&e mentioned this
Arrays with indefinite lengths are supported. The length of the array can be used as a variable. When declaring type, use int a[*]. But given the efficiency and the implementation, it's not a new type of thing. So you can't use it in the global, or struct union, if you use something like this, the goto statement is restricted.
A variable declaration does not have to be placed at the beginning of a statement block, and the For statement advocates such a for (int i=0;i<100;++i) that is, the declaration of int i is placed inside, I only works in the for.
When something like a struct needs a temporary construct, it can be used (type_name) {xx,xx,xx} This is a bit like C + + constructor
You can now write this when you initialize the structure:
struct {int a[3],b;} hehe[] = {[0].A = {1}, [1].A = 2};
struct {int A, B, C, D;} hehe = {. A = 1,. C = 3, 4,. B = 5}//3,4 is assigned to. C,.D
Within a string,/U supports Unicode characters
Description of supported floating-point numbers in 16
So the format string for printf scanf supports the Ll/ll (I64 in VC6) corresponding to the new long long type.
The internal data description for floating-point numbers supports the new standard, which can be specified with the #pragma compiler
In addition to the existing __line__ __file__, a __func__ is supported to get the current function name
For the expression of a very number, the compiler is also allowed to do the simplification
Modified the definition of/% handling negative numbers, such as the old standard -22/7 =-3,-22% 7 =-1 and now -22/7 =-4,-22% 7 = 6
Cancel Write function return type the default is int
Allow the last array defined by struct to write [] do not specify its length description
const const int i; will be treated as const int i;
Added and modified some standard header files, such as definition of bool <stdbool.h> definition of some standard length int <inttypes.h> define the <wctype of <complex.h> definition wide character. H> a bit of the generic flavor of the math function <tgmath.h> with the floating-point number related <fenv.h>. <stdarg.h> One more va_copy can be copied ... The parameters. <time.h> a struct TMX extended the struct TM.
Input and output support for wide characters and long integers
As opposed to the c89 change, there are
1. Add Restrict pointer
C99 adds a restrict type modifier that is applied to the pointer, which is the only way to initially access the object that the pointer refers to, so the object can be accessed only by using a restrict pointer expression. The Restrict pointer pointer is primarily used as a function argument, or points to a memory variable that is allocated by the malloc () function. The Restrict data type does not change the semantics of the program.
If a function defines two restrict pointer variables, the compiler assumes they point to two different objects, and the memcpy () function is a typical example of an application of the Restrict pointer. The C89 memcpy () function prototype is as follows:
Code: void *memcpy (void *s1, const void *S2, size_t size);
If S1 and S2 point to objects that overlap, their actions are undefined. The memcpy () function can only be used for objects that do not overlap. The memcpy () function prototype in C99 is as follows: code: void *memcpy (void *restrict s1, const void *restrict s2,size_t size);
By using restrict to modify S1 and S2, you can ensure that they point to different objects in the prototype.
2, inline (inline) keyword
In addition to maintaining a structured and functional definition, inline functions enable programmers to write efficient code. Each invocation and return of a function consumes a considerable amount of system resources, especially when a function call occurs in a loop statement that has a lot of repetitions. In general, when a function call occurs, the variable needs to be in the stack, and the various register memory needs to be saved. When the function returns, the contents of the register need to be restored. If the function is extended online within the code, these save and restore operations will occur again when the code executes, and the execution of the function call will be much faster. The online extension of a function produces longer code, so only functions that have a significant effect on application performance should be inline, as well as functions with shorter lengths.
3. New data types
_bool
The value is 0 or 1. C99 is added to the header folder <stdbool.h> to define bool, true, and false macros, so that programmers can write applications that are compatible with C and C + +. When writing a new application, you should use the
The BOOL macro in the <stdbool.h> header file.
_complex and _imaginary
The plural types defined in the C99 standard are as follows: Float_complex;float_imaginary;double_complex;double_imaginary;long Double_complex;long Double_ Imaginary.
The <complex.h> header file defines the complex and imaginary macros and expands them into _complex and _imaginary, so when writing a new application, you should use <stdbool.h> The complex and imaginary macros in the header file.
Long Long int
Long Long Int (-(2e63-1) to 2e63-1) and unsigned long int (0-2e64-1) are introduced in the C99 standard. Long int can support an integer length of 64 bits.
4, the increase of the logarithmic group
Variable-length arrays
In C99, when a programmer declares an array, the dimensions of the array can be determined by any valid integer expression, including an expression that determines its value only at run time, which is called a variable-length array, but only the local array can be longer.
The dimensions of variable-length arrays are invariant within the array lifetime, that is, variable-length arrays are not dynamic. What can be changed is the size of the array. You can use * to define variable-length arrays of indeterminate length.
Type modifiers in the array declaration
In C99, if you need to use an array as a function variable, you can use the static keyword within the square brackets of the array declaration, which is tantamount to telling the compiler that the array that the variable points to will contain at least the specified number of elements. You can also use the Restrict,volatile,const keyword within the square brackets of an array declaration, but only for function variables. If you use restrict, the pointer is the only way to initially access the object. If you use const, the pointer always points to the same array. Using volatile doesn't make any sense.
5. Single note
A single-line comment tag "//" is introduced, which can be used like C + +.
6. Disperse code and statement
7, the modification of the pretreatment procedure
A, variable list
A macro can take an argument with an ellipsis (...) in a macro definition. Said The internal preprocessing identifier __va_args__ determines where the variable will be replaced. Example: #define MYSUM (...) sum (__va_args__) statement mysum (K,M,N);
will be converted to: Sum (k, M, N); A variable can also contain a variable. Example: #define Compare (Compf, ...) Compf (__va_args__) Compare (strcmp, "small", "large"); will be replaced by: strcmp ("small", "large");
B, _pragma operator
C99 introduces another way to define compilation directives in a program: the _PRAGMA operator. The format is as follows:
_pragma ("directive")
where directive is the compilation instruction to be never really count. The _PRAGMA operator allows compilation directives to participate in macro substitution.
C, Internal compilation instructions
Stdcfp_contract On/off/default If on, floating-point expressions are treated as stand-alone units based on hardware. The default value is the defined tool.
Stdcfevn_access On/off/default tells the compiler to access the floating-point environment. The default value is the defined tool.
STDC Cx_limited_range On/off/default, if the value is on, is equivalent to telling the compiler that certain formulas containing complex numbers are reliable. The default is off.
D, the new internal macros
__stdc_hosted__ if the operating system exists, it is 1
__stdc_version__ 199991L or higher. Represents the version of C
If the __stdc_iec_599__ supports IEC 60559 floating-point operations, it is 1
If the __stdc_iec_599_complex__ support IEC 60599 Complex number operation, then 1
__STDC_ISO_10646__ is supported by compilers to describe the year and month formats for the ISO/IEC 10646 standard: YYYMMML
9. Compound Assignment
In C99, a compound assignment, you can specify an array, struct, or union expression of an object type. When you use compound assignment, you should specify the type in parentheses followed by an initialization list enclosed by curly braces, or the size of the array if the type is a group. The object being built is unnamed.
Example: Double *FP = (double[]) {1.1, 2.2, 3.3};
This statement is used to establish a pointer FP that points to double, and the pointer points to the first element of the array of 3 elements. Composite assignments that are established within a file domain are valid only for the entire lifetime of the program. The composite assignment created within the module is a local object that no longer exists after exiting the module.
10, flexible array structure members
In C99, the last element in the structure allows an array of unknown size, which is called a flexible array member, but a flexible array member in the structure must precede at least one other member. A flexible array member allows a structure to contain a variable sized array. The size of the structure returned by sizeof does not include the memory of the flexible array. Structures containing flexible array members are dynamically allocated for memory using the malloc () function, and the allocated memory should be larger than the size of the structure to accommodate the expected size of the flexible array.
11, the specified initialization character
In C99, this feature is useful for programmers who often use sparse arrays. The specified initializers are usually used in two ways: for arrays, and for structs and unions. Format used for arrays: = Vol; where index represents the subscript of the Array, and vol represents the initialization value of this array element.
For example: int x[10] = {[0] = 10, [5] = 30}; Only x[0] and x[5] are initialized. The format used for structs or unions is as follows:
Member-name (member name)
A simple method of initializing a specified member of a struct is allowed in a specified initialization of a struct.
For example: struct example{int k, m, n;} object = {m = 10,n = 200};
Where, there is no initialization of K. There is no limit to the order in which structural members are initialized.
12, printf () and scanf () function series enhancements
The printf () and scanf () functions series in C99 introduce attributes that deal with long long int and unsigned long int data types. A format modifier of type long int is LL. In the printf () and scanf () functions, LL applies to the D,i,o,u and X format specifiers. In addition, C99 also introduced the HH modifier. When using the D,i,o,u and X format specifiers, HH is used to specify a char type variable. Both ll and HH modifiers can be used with the n specifier.
When format modifiers A and a are used in the printf () function, the results output hexadecimal floating-point numbers. The format is as follows: [-]0xh, hhhhp + D using the A format modifier, x and P must be uppercase. The A and a format modifiers can also be used in the scanf () function to read floating-point numbers. When you invoke the printf () function, you allow the%f specifier to be preceded by an L modifier, that is,%LF, but it does not work.
13, C99 New Library
Standard header file in C89
<assert.h> define macro assert ()
<ctype.h> character processing
<errno.h> Error Reporting
<float.h> define floating-point values related to implementation
<limits.h> define the various limits associated with implementation
<locale.h> support function setlocale ()
<math.h> the various definitions used in the mathematical function library
<setjmp.h> support non-local jump
<signal.h> Define signal values
<stdarg.h> supports variable-length variable-element lists
<stddef.h> Define common constants
<stdio.h> support file input and output
<stdlib.h> various other statements
<string.h> Support String Functions
<time.h> Support System Time function
C99 New header files and libraries
<complex.h> Support Complex number algorithm
<fenv.h> gives access to floating-point status tokens and other aspects of the floating-point environment
<inttypes.h> defines a standard, portable collection of integral types. Functions that handle the largest-width integers are also supported
<iso646.h> first introduced in the first revision of this 1995 to define macros that correspond to various operators
<stdbool.h> supports Boolean data type types. Define macro bool so that it is compatible with C + +
<stdint.h> defines a standard, portable collection of integral types. This file is included in <inttypes.h>
<tgmath.h> defining generic types of floating-point macros
<wchar.h> first introduced in the first revision of 1995 to support multibyte and wide byte functions
<wctype.h> first introduced in the first revision in 1995 to support multibyte and wide byte classification functions
14. __func__ Predefined identifiers
Used to indicate the name of the function that the __func__ holds, similar to the string assignment.
15, other characteristics of the changes
Relaxed conversion restrictions
implied int rule is no longer supported
implicit function declaration deleted
Constraints on the return value
C99, a Non-empty type function must use a return statement with the returned value.
Extended Integer Type
Improvement of the rule of integer type lifting
In C89, a value of type char,short int or int in an expression can be promoted to an int or unsigned int type.
In C99, there is one level for each type of integer. For example, a long long int has a higher level than int,int char, and so on. In an expression, any integer type whose level is less than int or unsigned int can be replaced with an int or unsigned int type.
But companies are showing a different interest in C99 's support. While GCC and other commercial compilers support most of C99 's features, Microsoft and Borland seem uninterested.
GCC supports C99 and is opened by--STD = C99 command line arguments. For example: gcc--std = C99 test.c. GCC is the GNU89 standard by default
C Language Statement
Precedence Rule Analysis
A. The declaration begins with his first identifier (name) and reads sequentially in order of precedence:
B priority from high to low is:
The part of the B.1 declaration that is enclosed in parentheses.
B.2 suffix operator:
parentheses () indicate that this is a function, and the square brackets [] indicate that this is an array.
B.3 prefix operator: asterisk * denotes "point ... The pointer "
C if the const and/or volatile keyword is followed by a type descriptor (such as Int,long, etc.), it is used as a subtype specifier. In other cases, the const and/or volatile keywords are used as the adjacent pointer asterisk to the left of it.
Cases:
char * const * (*next) ();
A first, look at the variable name (identifier) "Next" and notice that it is enclosed in parentheses directly
B.1 so first the thing in parentheses as a whole, "next is a point ... The pointer "
B then consider something outside the parentheses, choosing between the asterisk prefix and the bracket suffix
The B.2 B.2 rule tells us that higher priority is the function bracket on the right, so "next is a function pointer, pointing to a return ..." The function "
B.3 then, process the prefix "*" to get what the pointer refers to
C Finally, interpret "char * const" as a constant pointer to a character
A little more intuitive to see the picture below
So this statement means that "next" is a pointer to a function that returns another pointer to a constant pointer of type char.
Example 2 char * (* c[10]) (int **p)
So the combination is C is a function pointer array, his return type is char *, the parameter is int **p
The following is a program from the C expert Programming analysis statement
#include <stdio.h> #include <string.h> #include <ctype.h> #include <stdlib.h> #define Maxtokens
#define Maxtokenlen the enum Type_tag {IDENTIFIER, QUALIFIER, type};
struct token{char type;
Char String[maxtokenlen];
};
int top =-1;
struct token stack[maxtokens];
struct token this; #define POP stack[top--] #define PUSH (s) stack[++top] = s enum type_tag classify_string (void) {char *s = this.string
;
if (!strcmp (S, "const")) {strcpy (S, "read-only");
return QUALIFIER;
} if (!strcmp (S, "volatile")) return QUALIFIER;
if (!strcmp (S, "Void")) return TYPE;
if (!strcmp (S, "char")) return TYPE;
if (!strcmp (S, "signed")) return TYPE;
if (!strcmp (S, "unsigned")) return TYPE;
if (!strcmp (S, "short")) return TYPE;
if (!strcmp (s, "int")) return TYPE;
if (!strcmp (S, "Void")) return TYPE;
if (!strcmp (S, "long") return TYPE; if (!strcMP (S, "float") return TYPE;
if (!strcmp (S, "double")) return TYPE;
if (!strcmp (s, "struct")) return TYPE;
if (!strcmp (S, "union")) return TYPE;
if (!strcmp (S, "enum")) return TYPE;
return IDENTIFIER;
} void GetToken (void) {char *p = this.string;
while ((*p = GetChar ()) = = ");
if (Isalnum (*p)) {while (isalnum (*++p = GetChar ()));
Ungetc (*p, stdin);
*p = '/0 ';
This.type = Classify_string ();
Return
} if (*p = = ' * ') {strcpy (this.string, "Pointer to");
This.type = ' * ';
Return
} this.string[1] = '/0 ';
This.type = *p;
Return
} read_to_first_identifer () {GetToken ();
while (This.type!= IDENTIFIER) {push (this);
GetToken ();
printf ("%s is", this.string);
GetToken ();
Deal_with_arrays () {while (This.type = ' [') {printf ("array");
GetToken (); if (IsDigit (This.string[0])) {printf ("0..%d", Atoi (this.string)-1);
GetToken ();
} gettoken ();
printf ("of");
} Deal_with_function_args () {while (This.type!= ') ') {GetToken ();
} gettoken ();
printf ("function returning");}
Deal_with_pointers () {while (Stack[top].type = = ' * ') {printf ("%s", pop.string);
} deal_with_declarator () {switch (this.type) {case ' [':d eal_with_arrays ();
Case ' (':d Eal_with_function_args ();
} deal_with_pointers ();
while (top >= 0) {if (Stack[top].type = = ' (') {pop;
GetToken ();
Deal_with_declarator ();
else printf ("%s", pop.string);
} main () {read_to_first_identifer ();
Deal_with_declarator ();
printf ("n");
return 0;}