What Are the Differences Between the Two Classic Standards of C Language?

Follow+Star Public Account Number, don’t miss the wonderful content

Editor | StrongerHuang

WeChat Public Account | Embedded ColumnThe C language has been around for over 50 years, and it is a classic and commonly used programming language. Most universities require students to learn C language as part of their curriculum, and in the embedded field, C language is an essential skill.

In recent years, C language has also been one of the popular languages. Today, I will share the differences between the two classic standards of C language: C89 and C99.

C Standard History

The development of the C language has exceeded 50 years. Previously, I shared an article on the Origin of C Language Compilers, which described the initial development of the C language. I also shared an article titled The 100-Year Development History of ANSI, which discusses the 100-year history of ANSI (American National Standards Institute). Here, I will describe the history of C89, C99, and C11 again:In 1983, the American National Standards Institute (ANSI) formed a committee to establish a standard for the C language. Since this standard was published in 1989, it is commonly referred to as the C89 standard. Some people also call the C89 standard ANSI C.In 1990, the ANSI C89 standard was adopted as an international standard by the International Organization for Standardization (ISO) and the International Electrotechnical Commission (IEC), named ISO/IEC 9899:1990 – Programming languages C, and is often referred to as the C90 standard. Therefore, C89 and C90 generally refer to the same standard, with C89 being the more commonly used term.In March 2000, the ISO and IEC adopted the second C language standard, named ISO/IEC 9899:1999 – Programming languages — C, referred to as the C99 standard.In December 2011, the ISO and IEC adopted the third C language standard, named ISO/IEC 9899:2011 – Information technology — Programming languages — C, referred to as the C11 standard. For our commonly used development environments MDK and IAR, C89, C99, and C11 are all supported.What Are the Differences Between the Two Classic Standards of C Language?Currently, C99 is the most widely used standard, and generally speaking, C99 is compatible with C89.

C89 and C99 Main Differences

Here are the main differences summarized:1. Enhanced ArraysVariable-Length ArraysIn C99, when programmers declare arrays, the dimensions of the array can be determined by any valid integer expression, including expressions whose values can only be determined at runtime. Such arrays are called variable-length arrays.However, only local arrays can be variable-length, and the dimensions of variable-length arrays do not change during the array’s lifetime. In other words, variable-length arrays are not dynamic; only the size of the array can change, and you can use * to define a variable-length array of uncertain length.Type Modifiers in Array DeclarationsIn C99, if you need to use an array as a function parameter, you can use the static keyword in the brackets of the array declaration, which tells the compiler that the array pointed to by the parameter will contain at least the specified number of elements. You can also use the restrict, volatile, and const keywords in the brackets of the array declaration, but only for function parameters. If you use restrict, the pointer is the only way to access that object. If you use const, the pointer always points to the same array. Using volatile has no meaning.2. Single-Line CommentsSingle-line comment markers “//” have been introduced, allowing comments to be used like in C++.3. Dispersed Code and DeclarationsModifications to the Preprocessor4. Variable Declarations in For StatementsIn C99, programmers can define one or more variables in the initialization part of the for statement, and the scope of these variables is limited to the loop body controlled by the for statement. For example, the code:

for(int i=0; i<10; i++){\n    // do something ...\n}

5. Compound AssignmentIn C99, compound assignment can specify array, structure, or union expressions of object types. When using compound assignment, the type should be specified in parentheses, followed by an initialization list enclosed in braces; if the type is an array, the size of the array cannot be specified. The created object is unnamed.Example:

double *fp = (double[]) {1.1, 2.2, 3.3};

This statement creates a pointer fp to double, which points to the first element of this 3-element array. Compound assignments created in the file scope are valid for the entire lifetime of the program. Compound assignments created within a module are local objects and do not exist after exiting the module.6. Designated InitializersIn C99, this feature is very useful for programmers who frequently use sparse arrays. Designated initializers typically have two uses: for arrays, and for structures and unions. The format for arrays is: [index] = vol; where index represents the array subscript, 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 for initializing structures or unions is as follows: member-name (member name) When performing designated initialization on a structure, a simple method is allowed to initialize specified members within the structure.For example:

struct example{ int k, m, n; } object = {m = 10,n = 200};

Here, k is not initialized. There are no restrictions on the order of initializing structure members.7. Enhancements to printf() and scanf() Function SeriesIn C99, the printf() and scanf() function series introduced features for handling long long int and unsigned long long int data types. The format specifier for long long int is ll.In printf() and scanf() functions, ll applies to d, i, o, u, and x format specifiers.Additionally, C99 introduced the hh specifier. When using d, i, o, u, and x format specifiers, hh is used to specify char type parameters. Both ll and hh specifiers can be used with the n specifier.The format specifiers a and A, when used in the printf() function, will output hexadecimal floating-point numbers. The format is: [-]0xh, hhhhp + d. When using the A format specifier, x and p must be uppercase. The A and a format specifiers can also be used in the scanf() function to read floating-point numbers. When calling the printf() function, it is allowed to add the l specifier before the %f specifier, i.e., %lf, but it has no effect.8. New Libraries in C99C89 Standard Header Files:

  • <assert.h> Defines the macro assert()
  • <ctype.h> Character handling
  • <errno.h> Error reporting
  • <float.h> Defines floating-point values related to implementation
  • <limits.h> Defines various limits related to implementation
  • <locale.h> Supports the function setlocale()
  • <math.h> Various definitions used in the math function library
  • <setjmp.h> Supports non-local jumps
  • <signal.h> Defines signal values
  • <stdarg.h> Supports variable-length parameter lists
  • <stddef.h> Defines commonly used constants
  • <stdio.h> Supports file input and output
  • <stdlib.h> Other various declarations
  • <string.h> Supports string functions
  • <time.h> Supports system time functions

C99 New Header Files and Libraries

  • <complex.h> Supports complex number algorithms
  • <fenv.h> Provides access to floating-point status flags and other aspects of the floating-point environment
  • <inttypes.h> Defines a standard, portable set of integer types. Also supports functions for handling maximum-width integers
  • <iso646.h> Introduced in the first revision in 1995, used to define macros corresponding to various operators
  • <stdbool.h> Supports boolean data types. Defines the macro bool for compatibility with C++
  • <stdint.h> Defines a standard, portable set of integer types. This file is included in <inttypes.h>
  • <tgmath.h> Defines macros for general types of floating-point
  • <wchar.h> Introduced in the first revision in 1995, used to support multi-byte and wide-character functions
  • <wctype.h> Introduced in the first revision in 1995, used to support multi-byte and wide-character classification functions

10. __func__ Predefined IdentifierUsed to indicate the function name stored in __func__, similar to string assignment.11. Other Changes in FeaturesRelaxed conversion restrictionsRestrictions C89 Standard C99 StandardMaximum nesting level of data blocks 15 127Maximum nesting level of conditional statements 8 63Number of valid characters in internal identifiers 31 63Number of valid characters in external identifiers 6 31Number of members in structures or unions 127 1023Number of parameters in function calls 31 127Implicit int rule no longer supportedImplicit function declarations removedConstraints on return valuesIn C99, non-void functions must use a return statement with a return value.Extended integer typesExtended Type Meaningint16_t Integer length is exactly 16 bitsint_least16_t Integer length is at least 16 bitsint_fast32_t The most robust integer type, with a length of at least 32 bitsintmax_t Maximum integer typeuintmax_t Maximum unsigned integer typeImprovements to integer type promotion rules:

  • In C89, values of types char, short int, or int in expressions can be promoted to int or unsigned int types.
  • In C99, each integer type has a level. For example, long long int has a higher level than int, and int has a higher level than char.
  • In expressions, any integer type with a level lower than int or unsigned int can be replaced with int or unsigned int types.

12. New Data Types_BoolValues are 0 or 1. C99 introduced the header file <stdbool.h> to define the macros bool, true, and false, allowing programmers to write applications compatible with both C and C++. When writing new applications, the bool macro in the <stdbool.h> header file should be used._Complex and _ImaginaryComplex 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 to _Complex and _Imaginary, so when writing new applications, the complex and imaginary macros in the <complex.h> header file should be used.long long intC99 introduced long long int (-(2e63 – 1) to 2e63 – 1) and unsigned long long int (0 to 2e64 – 1). The long long int can support an integer length of 64 bits.These are the main differences, and I hope they are helpful to everyone.Disclaimer:This article’s material is sourced from the internet, and the copyright belongs to the original author. If there are any copyright issues, please contact me for removal.

———— END ————

What Are the Differences Between the Two Classic Standards of C Language?

● Column “Embedded Tools”

● Column “Embedded Development”

● Column “Keil Tutorial”

● Selected Tutorials from the Embedded Column

Follow the public account Reply “Add Group” to join the technical exchange group according to the rules, reply “1024” to see more content.

Click “Read the Original” to see more shares.

Leave a Comment