Declarations in C
1. Declarations and definitions
declarative syntax
Descriptors (describing types or modifying default attributes) List of declaration expressions
- descriptor
- Type Description: int, float
- Storage properties: static, auto
- Type qualification: const, volatile
Declaration VS Definition
- Description type: range of values and legal operations
- Definition of: allocate storage space
2. Initialization
explicit initialization
- Static variables (including global variables): use theconstant expression (math.)initialization(math.) linear (of degree one)
- Automatic variables: initialized at each execution with an assignment statement
non-explicit initialization
- Static variables (including global variables): initialized at compile time, default value is 0
- Automatic variables: initialized at runtime, invalid by default
3. Complex declarations and typedefs
complex declaration
Left/Right Rule: Start with the innermost parenthesis (undefined identifier), look to the right of it, then to the left of it, and reverse direction when you encounter a parenthesis. Once you have parsed the contents of the parentheses you can jump out of them and repeat the process until you have finished parsing.
int *(*(*f)(int))[10];
// (*f) f is a pointer to a function.
// (*f1(int)) f1 is a function pointer, the return value of the function pointed to is a pointer, and the argument is (int)
// int *f2[10] f2 is an array pointer to the array int * a[10]
// In summary, f is a pointer to a function whose argument is (int) and whose return value is a pointer to an array of int *a[10] of type int*.
// pointer to function returning pointer to array[10] of pointer to int
char (*(*x())[]) (); // *x(), x is a pointer to array[10] of pointer to int.
// *x(), x is a function whose return value is a pointer of type
// *(x1)[], x1 is an array of pointers with elements of type pointer
// char x2(), x2 is a function with return value type char
// In summary, x is a function whose return value is a pointer array whose element type is a pointer to a function whose return value is char
// function returning pointer to array[] of pointer to function returning char
char (*(*x[3])())[5]; // function returning pointer to array[] of pointer to function returning char
// *x[3], x is an array with elements of pointer type
// *x1(), x1 is a function whose return value is a pointer
// char x2[5], x2 is an array, element type is char
// In summary, x is an array whose element type is a pointer to a function whose return value type is an array pointer to an array whose element type is char
// array[3] of pointer to function returning pointer to array[5] of char
Unixcdecl The program implements the parsing of declarations, see
typedef
The syntax is similar to the declaration, using the identifier as an alias for the type
1. Make the code clearer and more concise
-
Defining variables such as structures, unions, enumerations, etc.
typedef struct student { char name[]; int score; } T_Stu, *PT_Stu; T_Stu tStu1 = {"Bob", 78}; PT_Stu ptStu1 = &tStu1; typedef enum color { red, white, block, } colot_t; color_t color1 = red;
-
Simplifying complex statements
// int *(*array[10])(int *p); typedef int *(func_ptr)(int *p); func_prt array[10];
2. Increasing code portability
The int type is allocated different storage bytes under different compilers and platforms, and portability is enhanced by using customized datatypes instead of built-in types.
#ifdef PIC_16
typedef unsigned long u32 // 2 bytes for int, 4 bytes for long
#else
typedef unsigned int u32 // 4 bytes for both int and long in PIC_32
#endif
Scenarios for typedef
- Creating an alias for a data type
- Cross-platform type of specified length, u32
- Data types related to OS, BSP, network bytes, such as size_t, pid_t, etc.
- Opaque data types, need to hide data structure implementation details, only open function interface
Avoiding typedef abuse: refer to the Linux Kernel Documennt's CodingStyle.
4. Discriminating
-
Array and Pointer Parameters
int fun(char *str); int func(char str[]); // Both are consistent only in the current declaration context
-
Array and Pointer Initialization
char *p = "hello"; char a[] = "hello"; // special form, equivalent char a[] = {'h', 'e', 'l', 'l', 'o', '\0'};
-
Declarations and Definitions
int a; // Variable declarations and definitions extern int b; // Variable declaration void f1(void){}; // function declaration and definition void f2(void); // Declaration of the function
-
typedef VS #define
A typedef is equivalent to storing the class keyword, a macro definition is just string replacement
- typedef does not support the continued use of storage class keywords such as static
- Macro definitions do not support pointer declarations
- typedef is scoped, and macro definitions are globally replaced in the preprocessing phase
#define int *POINTER_TO_INT POINTER_TO_INT a, b, c; // b, c cannot be declared as pointers. // with the const keyword typedef char* PTCHAR1. #define PTCHAR2 char*;; // b, c cannot be declared as a pointer type // with the const keyword. const PTCHAR1 p1; // PTCHAR1 as type, transposable with consat, const modifies p1, pointer constant const PTCHAR2 p2; // Equivalent to const char* p2; char swappable with const, const modifies (*p2), constant pointer
//TODO Declarations in the Linux kernel, when learning Linux source code
5. Reference
- C and Pointers
- 3.2 Declarations
- 3.3 typedef
- 13.2 Advanced statements
- Self-Mastery in Embedded C.
- 7.5 typedef
- 7.8.2 Complex declarations
- 9.4 Deep parsing of header files
- C Programming Language
- 2.4 Declarations
- 4.9 Initialization
- 5.12 Complex declarations
- 6.7 Type definitions (typedef)
- C Expert Programming
- 3 Declarations in C
- 4.3 Declarations and definitions