c language - review of basic knowledge points

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

Keywords: C Back-end

Added by jamie85 on Sat, 13 Nov 2021 00:58:27 +0200