Do a collation of the C language. Don't say the most basic. List some knowledge points that are easy to forget and make mistakes.
1, Pointer
1. Definition of pointer
int a = 100; int b = 200; int *p_a = &a; //The pointer variable must be defined with *. Note that the address symbol is taken, and the pointer p_a points to a printf("%d\n", *p_a); //In addition to the definition, * p_a represents the data pointed to by the pointer. p_a = &b; //In addition to the definition, p_a represents the pointer address. printf("%d\n", *p_a);
The pointer variable must be defined with * and cannot be assigned with *.
2. Pointer to array
Example 1:
#include <stdio.h> int main(){ int arr[] = { 99, 15, 100, 888, 252 }; int len = sizeof(arr) / sizeof(int); //Find array length int i; for(i=0; i<len; i++){ printf("%d ", *(arr+i) ); //Arr is the first element address, arr+i is the ith element address, and * (arr+i) represents the value of the ith element } printf("\n"); return 0; }
Example 2:
#include <stdio.h> int main(){ int arr[] = { 99, 15, 100, 888, 252 }; int *p = &arr[2]; //The pointer p points to the second element "100" of the array, or it can be written as int *p = arr + 2; printf("%d, %d, %d, %d, %d\n", *(p-2), *(p-1), *p, *(p+1), *(p+2) ); return 0; }
Pointer to 2D array
3. The difference between character array and constant string
char str[] = "http://c.biancheng.net "; / / character array char *str = "http://c.biancheng.net"; // Constant string
The most fundamental difference is that the storage areas in memory are different. Character arrays are stored in the global data area or stack area, and the second form of strings are stored in the constant area. The strings in the global data area and stack area have read and write permissions, while the strings in the constant area only have read permissions and no write permissions. Therefore, constant strings can only be assigned during initialization and cannot be modified.
4. Pointer variables are used as parameters of functions
#include <stdio.h> void swap(int *p1, int *p2){ //Pay attention to formal parameter writing int temp; //Temporary variable temp = *p1; *p1 = *p2; *p2 = temp; } int main(){ int a = 66, b = 99; swap(&a, &b); //The argument is the address printf("a = %d, b = %d\n", a, b); return 0; }
5. Array as function parameter
Example:
#include <stdio.h> int max(int *intArr, int len){ //Array as a function parameter, pay attention to the writing method of int *intArr int i, maxValue = intArr[0]; for(i=1; i<len; i++){ if(maxValue < intArr[i]){ maxValue = intArr[i]; } } return maxValue; } int main(){ int nums[6], i; int len = sizeof(nums)/sizeof(int); for(i=0; i<len; i++){ scanf("%d", nums+i); } printf("Max value is %d!\n", max(nums, len)); //Function call, pass in array parameters, Num table, array header address return 0; }
For basic types of data such as int, float, char, etc., the memory they occupy is often only a few bytes, so it is very fast to copy them in memory. The array is a collection of a series of data. The number of data is unlimited, which may be few or thousands. Copying them in memory may be a long process, which will seriously slow down the efficiency of the program. C language does not support the direct assignment of data sets from the syntax, and it is implemented by using a pointer like method at the bottom.
6. Pointer function
A pointer function is a function whose return value is a pointer.
Example:
#include <stdio.h> #include <string.h> char *strlong(char *str1, char *str2){ //Pay attention to the writing of pointer function * strlong if(strlen(str1) >= strlen(str2)){ return str1; //The return value is a pointer }else{ return str2; } } int main(){ char str1[30], str2[30], *str; gets(str1); gets(str2); str = strlong(str1, str2); //call printf("Longer string: %s\n", str); return 0; }
The pointer returned by the pointer function should not point to local variables as much as possible. After the function is run, all local data defined in it will be destroyed, resulting in the failure to ensure the correctness of the return value, for example:
#include <stdio.h> int *func(){ int n = 100; return &n; //Returns a pointer to a local variable of a function } int main(){ int *p = func(); printf("abcdefg\n"); printf("value = %d\n", *p); //*The value of p cannot be determined to be 100 return 0; }
7. Secondary pointer
Definition of secondary pointer:
#include <stdio.h> int main(){ int a =100; int *p1 = &a; //p1 is a level 1 pointer int **p2 = &p1; //p2 is a level 2 pointer return 0; }
p1 represents the address of a, * p1 represents the value of a, & p1 represents the address of A.
p2 represents the address of the primary pointer p1, that is, the address of a* p2 represents the address of a** p2 represents the value of A.
in other words:
&p1=p2; //Address of a p1=*p2 //a's address *p1=**p2 //Value of a
8. void pointer
Void is used in the function definition to indicate that the function has no return value or that the type of data pointed to by the pointer is unknown. The return value of C language dynamic memory allocation function malloc() is of type void *, and forced type conversion is required when using:
void* malloc(int size); char *str = (char *)malloc(sizeof(char) * 30);
9. The difference between arrays and pointers
An example of the inequivalence between array and pointer is to find the length of the array. At this time, only the array name can be used, not the array pointer:
#include <stdio.h> int main(){ int a[6] = {0, 1, 2, 3, 4, 5}; int *p = a; //The pointer p points to the array int len_a = sizeof(a) / sizeof(int); int len_p = sizeof(p) / sizeof(int); printf("len_a = %d, len_p = %d\n", len_a, len_p); return 0; }
Result: len_a = 6, len_p = 1
Explanation: an array is a collection of data. p is just a pointer to int type. Using sizeof for p is the length of the pointer variable itself.
10. Pointer array (each element of the array is a pointer)
Definition method:
#include <stdio.h> int main(){ int a = 16, b = 932, c = 100; int *arr[3] = {&a, &b, &c}; //Defines an array of pointers int **parr = arr; //Define a pointer to the pointer array, secondary pointer printf("%d, %d, %d\n", *arr[0], *arr[1], *arr[2]); printf("%d, %d, %d\n", **(parr+0), **(parr+1), **(parr+2)); return 0; }
Refer to the previous secondary pointer
arr[0]express a Your address, arr[1]express b Address of; *arr[0]Representation variable a,*arr[1]Representation variable b; &arr[0]express a Your address,&arr[1]express b Address of; arr Represents the starting address of the pointer array. Namely a The address of the address is&arr[0]; parr Represents the starting address of the pointer array. Namely a The address of the address is&arr[0];parr+1 express b The address of the address is&arr[1]; *(parr+0)express a Your address,*(parr+1)express b Address of **(parr+0)express a The value of,**(parr+1)express b Value of
11. Pointer array and string array
Pointer array can be used in combination with string array:
#include <stdio.h> int main(){ char *str0 = "c.biancheng.net"; char *str1 = "C Language Chinese network"; char *str2 = "C Language"; char *str[3] = {str0, str1, str2}; //Note that the element of the pointer array is the address, and the data type should be defined as char printf("%s\n%s\n%s\n", str[0], str[1], str[2]); return 0; }
Analyze an example:
#include <stdio.h> int main(){ char *lines[5] = { "COSC1283/1284", "Programming", "Techniques", "is", "great fun" }; char *str1 = lines[1]; char *str2 = *(lines + 3); char c1 = *(*(lines + 4) + 6); char c2 = (*lines + 5)[5]; char c3 = *lines[0] + 2; printf("str1 = %s\n", str1); printf("str2 = %s\n", str2); printf(" c1 = %c\n", c1); printf(" c2 = %c\n", c2); printf(" c3 = %c\n", c3); return 0; }
Output:
str1 = Programming str2 = is c1 = f c2 = 2 c3 = E
Explanation:
1, lines[1]Represents the address of the second string. Print str1 Get the second string 2, lines The address representing the address of the first string, lines + 3 The address representing the address of the fourth string,*(lines + 3) Represents the address of the fourth string. Print str2 Get the fourth string 3, lines + 4 The address representing the address of the fifth string,*(lines + 4)+6 Represents the address of the fifth string plus 6, which is the character“ f"Your address, so*(*(lines + 4) + 6)Representation character f. 4, *lines Represents the address of the first string,*lines + 5 Represents the address of the first character "2" in the string*lines + 5 Address as the starting address of a new array,(*lines + 5)[5]It means the address of the first character "2" in the string, and the address of the fifth character to the right is the address of the second "2". 5, lines[0]Represents the address of the first string(Start address),*lines[0]Represents the first character of the string“ C",*lines[0] + 2 Representation character“ C"do ASCII Code calculation.
12. Function pointers and pointer functions
Function pointer: refers to the definition of a pointer to the first address of the function code. Functions can be called through the function pointer.
Definition of function pointer:
#include <stdio.h> int max(int a, int b){ return a>b ? a : b; } int main(){ int x, y, maxval; int (*pmax)(int, int) = max; //Define the function pointer pmax to point to the max function, which can also be a direct address. Note that the writing method (* pmax) should be bracketed, otherwise * pmax(int, int) represents the pointer function. printf("Input two numbers:"); scanf("%d %d", &x, &y); maxval = (*pmax)(x, y); //Calling a function through a pointer printf("Max value: %d\n", maxval); return 0; }
Function and usage scenario of function pointer:
For example, in embedded system, some function functions (system functions) of microcontroller are solidified in rom (similar to BIOS in PC) User code does not recognize these functions and cannot be called directly by function names. So when we want to call these system functions in user programs, we can transfer the entrance address of the system function to the function pointer to achieve the purpose of calling rom programs.
Pointer function: refers to the definition of a function whose return value type is pointer. Pay attention to the differences, as mentioned earlier.
2, Structure
1. Structure and structure array definition
//Create a stu structure template struct stu{ char *name; int num; int age; char group; float score; }; //The structure stu1 is defined and initialized, or not initialized. struct stu stu1 = { "Tom", 12, 18, 'A', 136.5 }; printf("name is %s,num is %d ...", stu1.name,stu1.num); //Define the structure array class. Each element of the array is a stu structure and can not be initialized. struct stu class[] = { { "Li ping", 5, 18, 'C', 145.0 }, { "Zhang ping", 4, 19, 'A', 130.5 }, { "He fang", 1, 18, 'A', 148.5 }, { "Cheng ling", 2, 17, 'F', 139.0 }, { "Wang ming", 3, 17, 'B', 144.5 } }; printf("first student name is %s, num is %d...", class[0].name, class[0].num);
2. Structure pointer and structure array pointer
Structure pointer:
struct stu{ char *name; int num; int age; char group; float score; }stu1 = { "Tom", 12, 18, 'A', 136.5 }; //Another way to define stu1 struct stu *p = &stu1; //Define a structure pointer p to stu1 structure. Pay attention to the address character printf("stu name is %s", p->name); //Print the name variable of the structure
Structure array pointer:
struct stu{ ...... } class[] = { { "Li ping", 5, 18, 'C', 145.0 }, { "Zhang ping", 4, 19, 'A', 130.5 }, { "He fang", 1, 18, 'A', 148.5 }, { "Cheng ling", 2, 17, 'F', 139.0 }, { "Wang ming", 3, 17, 'B', 144.5 } }; struct stu *p = class; //Define a structure pointer to point to the structure array. Note that there is no address character printf("first stu name is %s", p->name); //Print first student name p++; //p represents the address of the first structure, and p + + represents the address of the second structure of the array printf("second stu name is %s", p->name);
3. Structure and structure array as function parameters
#include<stdio.h> struct stu{ char *name; int num; int age; char group; float score; }; void func1(struct stu s) //Pay attention to formal parameter writing { printf("func1 name is %s\n",s.name); } void func2(struct stu *p2) //Pay attention to formal parameter writing { printf("func2 name is %s\n", p2->name); } void func3(struct stu *p3) //Pay attention to formal parameter writing { printf("func3 first name is %s\n", p3->name); p3++; printf("func3 second name is %s\n", p3->name); } int main() { struct stu stu1 = { "Tom", 12, 18, 'A', 136.5 }; struct stu class[] = { { "Li ping", 5, 18, 'C', 145.0 }, { "Zhang ping", 4, 19, 'A', 130.5 }, { "He fang", 1, 18, 'A', 148.5 }, { "Cheng ling", 2, 17, 'F', 139.0 }, { "Wang ming", 3, 17, 'B', 144.5 } }; func1(stu1); //Direct incoming structure func2(&stu1); //Pass in structure pointer func3(class); //Pass in structure array pointer }
4. Enum keyword, enum type
enum week{ Mon, Tues, Wed, Thurs, Fri, Sat, Sun }; enum week day = Mon; //day=0
Understand enum week {Mon, Tues, wed, Thurs, Fri, sat, sun} as macro definition:
#define Mon 0; #define Tues 1; ...
Can.
5. union keyword, Consortium
union data{ int n; char ch; short m; }; union data a; a.n = 0x40; printf("%X, %c, %hX\n", a.n, a.ch, a.m);
Each member of the structure will occupy different memory and have no influence on each other; All members of the community occupy the same memory. Modifying one member will affect all other members. For example, the number of bytes occupied by the above data union depends on int, which is 4 bytes.
6. Size end and discrimination method
Big end mode: refers to placing the low order of data (for example, 34 in 1234 is the low order) on the high address of memory, and the high order of data (for example, 12 in 1234 is the high order) on the low address of memory.
Small end mode: it refers to placing the low bit of data on the low address of memory and the high bit of data on the high address of memory.
For example, in a 32-bit system, an int data 0x12345678, small end mode:
Memory address : 0x4000 0x4001 0x4002 0x4003 Storage content : 0x78 0x56 0x34 0x12
Big end mode:
Memory address : 0x4000 0x4001 0x4002 0x4003 Storage content : 0x12 0x34 0x56 0x78
How to distinguish the big end or small end mode adopted by cpu?
The concept of consortium can be used:
#include <stdio.h> int main(){ union{ int n; char ch; } data; data.n = 0x00000001; if(data.ch == 1){ printf("Little-endian\n"); }else{ printf("Big-endian\n"); } return 0; }
1 is the low order of the data. If data.ch==1, it means that the low order of the data is in the low order of the address, which is the small end mode, otherwise it is the large end mode. The schematic diagram is as follows:
7. bs bit field
Its members are used to store one or more data bits. I don't think this is commonly used. Just know that there is such a thing.
3, Other
1. typedef keyword
typedef is used to define aliases for data types:
//Define an alias for the int type typedef int INTEGER; INTEGER a, b; a = 1; b = 2; //Define an alias for an array typedef char ARRAY[20]; ARRAY a,b,c; // Equivalent to char a[20], b[20],c[20] //Structure definition alias typedef struct stu{ char name[20]; int age; char sex; } STU; STU stu1,stu2; //Two dimensional array pointer definition alias typedef int (*PTR_TO_ARR)[4]; PTR_TO_ARR p1; //Function pointer definition alias typedef int (*PTR_TO_FUNC)(int, int); PTR_TO_FUNC pfunc;
An example of an alias defined by a two-dimensional array pointer:
#include <stdio.h> int main(){ int str[][4] = { { 0, 1, 2, 3 }, { 4, 5, 6, 7 }, { 8, 9, 10, 11 } }; typedef int(*PTR_TO_ARR)[4]; PTR_TO_ARR p1 = str; printf("%d\n", **p1); //Print one element on the first line return 0; }
An example of a function pointer definition alias:
#include <stdio.h> int func1(int a, int b) { printf("a is %d,b is %d\n", a, b); } int main(){ typedef int(*FUNCDEF)(int,int); FUNCDEF pfunc = func1; (*pfunc)(1, 2); return 0; }
The difference between typedef and #define
1. #define can extend the type name, but not the type name defined by typedef.
#define INTERGE int unsigned INTERGE n; //no problem typedef int INTERGE; unsigned INTERGE n; //Error, cannot add unsigned before interface
2. When several variables are defined continuously, typedef can ensure that all variables defined are of the same type, while #define cannot.
#define PTR_INT int * PTR_INT p1, p2; //In fact, it is equal to: int *p1, p2. Originally, I wanted to define two int pointers, but p2 is int typedef int * PTR_INT PTR_INT p1, p2; //Both p1 and p2 are int pointers
2. const keyword
The value of the variable defined by const cannot be changed and remains fixed throughout the scope:
const int a=100; a=50; //Error, the variable defined by const cannot be modified
When used with a pointer, the data pointed to by the pointer can not be changed, the address of the pointer can not be changed, or both:
const int *p1; //The data pointed to cannot be modified int const *p2; //The data pointed to cannot be modified int * const p3; //The address of p3 cannot be modified const int * const p4; //Address and pointing data cannot be modified int const * const p5; //Address and pointing data cannot be modified
const is used as a function parameter modifier
const is usually used in function parameters. If the parameter is a pointer, it can prevent the data pointed to by the pointer from being modified inside the function:
example:
#include <stdio.h> size_t strnchr(const char *str, char ch){ //The formal parameter pointer is modified by const, and the data pointed to cannot be changed int i, n = 0, len = strlen(str); for(i=0; i<len; i++){ if(str[i] == ch){ n++; } } return n; } int main(){ char *str = "http://c.biancheng.net"; char ch = 't'; int n = strnchr(str, ch); printf("%d\n", n); return 0; }
3. static and extern keywords
extern keyword
extern can be placed in front of a variable or function to indicate the definition of the variable or function. In other files, it prompts the compiler to find its definition in other modules when encountering this variable and function. For example:
In main.c:
extern void func(); //Functions and global variables are defined in other files, prompting you to find them in other files extern int m;
Note: exterb is only used for declaration, so it is not recommended:
extern datatype name = value; //Equivalent to datatype name = value, extern does not work
static keyword
When static modifies a global variable or function, its scope will be modified. The global variable or function modified by static is only valid for this file.
Static modification of local variables will change the storage area of variables. The static modified local variables will be stored in the global data area (the same as the storage area of global variables), while the non static modified local variables should be in the stack space. Therefore, it will not be destroyed because of the end of the function call. At the same time, note that the variables in the global data area can only be initialized (defined) once.
Here is an example:
#include <stdio.h> int func(){ static int n = 0; //static modifies a local variable n++; printf("Function is called %d times.\n", n); return n; } int main(){ int i, n = 0; for(i = 1; i<=5; i++){ func(); } printf("n = %d\n", n); return 0; }
Operation results:
Function is called 1 times.
Function is called 2 times.
Function is called 3 times.
Function is called 4 times.
Function is called 5 times.
n = 0
Note that static int n is initialized only once, and static int n and N in main do not affect each other (n in main is in stack space)
For more dynamic and static libraries and the creation and linking of shared libraries, see linux system programming - creation and linking of static libraries and shared libraries.
4. Vocalite keyword