Basic knowledge of embedded C language -- memory management & Function & pointer & array

Memory management:

local variableStatic local variableglobal variablestatic global
ScopeValid within {} of the defined variableValid within {} of the defined variableThe whole project, all documentsCurrent file
life cycleThe program runs to the variable definition to open up space, and the space is released after the function is completedThe space has been opened before the main function is executed, and the space is not released until the program is finishedThe space has been opened before the main function is executed, and the space is not released until the program is finishedThe space has been opened before the main function is executed, and the space is not released until the program is finished
Uninitialized valuerandom000


Note: in In h, global variables are only declared and not defined, and the definitions are only placed in c documents.

 memset:

memcpy:

memcmp:

malloc:

free:

Array

1. The minimum storage unit of the computer is Byte, which is composed of 8 bits, whether 32-bit or 64 bit CPU.

2. break: forcibly jump out of the loop body and execute the statement after the loop statement block;

Continue: judge the condition of returning the loop body from the continue point and continue the next loop action.

3. int *p: define the p pointer variable, which is used to point to an address, which stores an int type data.

4. One dimensional array

eg: int a[5];

  • a[0]: element 0
  • &A [0]: address of the 0th element
  • Array name a: represents the array and the address of the 0th element, which is equal to & A [0]. Therefore, the array name is a constant, an address, and cannot be assigned.
  • &a: The address of the array is numerically equal to & A [0], a, & A.
  • &A [0] + 1: the address of the element plus 1 indicates that it crosses an element
  • a+1: a = & A [0], so it also means crossing an element
  • &A + 1: add 1 to the address of the whole array, which means crossing an array

5. Two dimensional array

eg: int a[3][4]

  • Defines an array with three rows and four columns. The array name is a and the element type is integer.
  • The elements of two-dimensional array a are stored in rows. That is, save line 0 first, and then save the next line.
  • a[0] of one-dimensional array represents the 0th element, and a[0] of two-dimensional array represents the 0th row.
  • a[0][0]: element 0 in line 0
  • &A [0] [0]: address of element 0 in line 0
  • a[0]: represents the array name of the one-dimensional array on line 0, a[0] = & a[0] [0]
  • &A [0]: address of line 0
  • a: The array name of the two-dimensional array, which represents the two-dimensional array and the first line address, a = & A [0]
  • &a: Address of two-dimensional array
  • &A [0] [0] + 1: add 1 to the element address to span an element
  • a[0] + 1: add 1 to the element address to span an element
  • &A [0] + 1: add 1 to the line address to span one line
  • a + 1: add 1 to the line address to span one line
  • &A + 1: add 1 to the address of the two-dimensional array and span the entire array

6. Character array

int a[10]   //Each element is of type int, so this is a numeric array
char a[10]  //Each element is of type char, so this is a character array

A string is an array of \ 0} characters in a character array.

eg:

① Normal character array:

char a[5] = {'a','b','c','d','e'};

② The character array contains the \ 0} character, which is also a string:

char a[5] = {'a','b','c','d','\0'};

③ A character array is defined and stored as {abcd{ABCD \ 0::

char a[5] = "abcd";

④ Defines a character array with 100 elements:

char a[100] = "abcd";

⑤ Fill the 0 th element of the array with \ 0, and the other elements are \ 0:

char a[100] = "\0";

⑥ Clear a character array to 0:
 

char a[100] = {0};

Difference between character array and string:

  • There is no string data type in C language, which can be replaced by char array;
  • The string must be an array of char , but the array of char , may not be a string;
  • The char array ending with the number 0 (equivalent to the character '\ 0') is a string, but if the char array does not end with the number 0, it is not a string, but an ordinary character array

⑦ For ordinary character array, if it is printed with% s' (% s' refers to the output string format, which starts printing from the starting address of the character array, that is, the address of the first element, until \ 0 '), there will be garbled code if there is no \ 0' end character.

function

1. When defining a function, the parameter in () is called a formal parameter, because this formal parameter is only a formal parameter. There is no space for the formal parameter when defining a function. The formal parameter will allocate space only when it is called.

2. When calling a function, the parameters in () are called arguments. The type and number of arguments must be the same.

3. The header file only declares, not defines; Only in c) as defined in.

4. Prevent header files from repeatedly containing:

#ifndef# macro (the name of the macro should be the same as the file, in uppercase)

#define macro

#endif 

② #pragma once

5. Static function: a function decorated with static when defining a function. Static functions can only be called by functions in the current file.

Pointer

5. Define pointer: replace the defined variable with * p +.

eg: int a, replace a with * p to get int *p.

6. int *p: combined with * indicates that this is a pointer variable;

P is a variable, and the type of P , is: drag the variable p itself black, and the remaining type is the type of pointer variable, that is, , int *;

The address of the pointer variable "p" used to save what type of data: smear the pointer variable "p" together with the latest * and the rest is the type of saved data, eg: int **p, which saves the "int * data type.

7. Pointer width = sizeof (drag the nearest * of pointer variable and pointer variable to black, and the remaining length)

Width is also called step size, that is, how many bytes the pointer plus 1 # spans.

The pointer is incremented by 1 to span a step.

eg:

char *p1
short *p2
int *p4
int **psizeof(int *) = 4

8. A wild pointer is a pointer that has not been initialized. The pointer pointing is random and cannot be operated.

The address saved by the pointer # p # must be defined (applied to the system).

9. Null pointer is to assign the value of the pointer to 0, that is, null. eg: int *p = NULL.

Function of null pointer: if the pointer is used, assign the pointer to null. Judge whether the pointer is null when using it to know whether the pointer has been used.

Look at the following code:

int main()
{
    
    int *p = NULL;      //Assign the value of the pointer to 0, i.e. null
    *p = 200;           //err, because p saves the address 0x0000, this address cannot be used  
    printf("%d\n", *p);

    system("pause");
    return 0;
}

10. Universal pointer (void *)

The universal pointer can store any address, but if you want to operate the content of the space pointed to by the universal pointer, you need to convert the universal pointer through forced type conversion, as shown below.

int main()
{
    int a = 10;
    short b = 20;

    void* p = (void*)&a;      //The universal pointer can store any address. You need to convert the pointed address to void * type first
    void* q = (void*)&b;

    //printf("%d\n", *p);          //err, P is void *, I don't know how many bytes to take
    printf("%d\n", *(int*)p);      //Cast type conversion: convert from "* address" to "* ((int *) address)"
    printf("%d\n", *(short*)q);

    system("pause");
    return 0;
}

Output is:

10
20

In addition:

① void b; / / error, you cannot define a variable of void type because the compiler does not know how much space is allocated to the variable.

However, the void * type can be defined because the pointers are 4 bytes.

②     printf("%d\n", *(int*)p); / / forced type conversion: convert from "* address" to "* ((int *) address)"

In this statement, p is the address of a, but the type of p is void *. In order to get the value of 4-byte a, first convert the address type into 4-byte int * type by forced type conversion, and then take the content in the address of int * type, that is, the value of A.

11. const decorated pointer

See if const modifies * or p.

(1) Modify *, the content of the space pointed to by P cannot be modified by * p *.

const int *p = &a;
*p = 100;          //err

(2) Modify the variable "p", then the address saved by "p" cannot be modified.

int *const p = &a;
p = &b;          //err

(3) The direction of p ^ itself cannot be changed, and the content of p pointing to space cannot be modified through * p ^.

const int *const p = &a;

12. Operate array elements through pointers

The pointer is incremented by 1 to span a step.

int *p; Step size = sizeof(int)

int main(int argc, char const *argv[])
{
    int a[10] = {0};
// a represents the array name and the address of the first element
    int *p = a;   // Pointer p holds the address of the first element
    for (int i = 0; i < sizeof(a) / sizeof(a[0]); i++)
    {
        *(p + i) = i;  //The pointer is incremented by 1 to span a step
    }
    for (int i = 0; i < sizeof(a) / sizeof(a[0]); i++)
    {
        printf("%d ", a[i]);
    }



    system("pause");
    return 0; 
}

13. Pointer operation

The addition of two pointers is meaningless; Subtract the two pointers (with the same type) to get the number of elements crossed in the middle. See the code below:

int main(int argc, char const *argv[])
{
    int a[5] = { 1,2,3,4,5 };
    int* p = a;
    int* q = (int *)(&a + 1) - 1;
    printf("%d\n", *(p + 3));
    printf("%d\n", q - p);

    system("pause");
    return 0; 
}

Output is:

4
4

14. As shown in the following code, the four "printf" have the same meaning. That is, [] = * ().

int main(int argc, char const *argv[])
{
    int a[5] = { 1,2,3,4,5 };
    int* p = a;

    for (int i = 0; i < sizeof(a) / sizeof(a[0]); i++)
    {
        printf("%d ", a[i]);
        printf("%d ", *(p + i));
        printf("%d ", p[i]);
        printf("%d ", *(a + i));
    }

    system("pause");
    return 0; 
}

15. Pointer array

Integer array: every element of the array is an integer

Pointer array: each element of the array is a pointer

eg: int *arr[3] = {&a, &b, &c};

16. Pointers and functions

(1) As the formal parameter of the function, the pointer can change the value of the argument.

eg: exchange two numbers

void swap(int *x, int *y)
{
    int k = *x;
    *x = *y;
    *y = k;
    printf("x = %d y = %d\n", *x, *y);
}

int main(int argc, char const *argv[])
{
    int a = 10;
    int b = 20;
    swap(a, b);
    printf("a = %d b = %d\n", a, b);

    system("pause");
    return 0; 
}

(2) Array as an argument to a function

Arrays as formal parameters of functions degenerate into pointers.  

void print_arr(int *b, int len)
{
    int n = sizeof(b) / sizeof(b[0]);  //If b is int * type and b[0] is int type, then n=4/4=1
    printf("n = %d\n", n);
    for (int i = 0; i < len; i++)
    {
        printf("%d ", b[i]);
    } 
    printf("\n");
}

int main()
{
    int a[5] = {1,2,3,4,5};
    print_arr(a, sizeof(a) / sizeof(a[0]));  //The address of the first element is passed here, so an int * type should also be defined in the function.

    system("pause");
    return 0;
}

(3) Pointer as the return value of the function

The space of local variables will be released after the end of the function, so if num is defined as a global variable, its address can be returned.

int num = 0;
int *get_num()
{
    srand(time(NULL));
    num = rand();
    return &num;      //The space of local variables will be released after the end of the function, so if num is defined as a global variable, its address can be returned.
}

int main()
{
    int *p = get_num();
    printf("%d\n", *p);

    system("pause");
    return 0;
}

Exercise:

char arr[] = "hello world";
char *p = arr;
int i = 0;
for(; i<sizeof(arr)/sizeof(char); ++i)
{
    printf("%c", p[i]);
}

The output is: hello world

The difference between + + i and i + + in the for loop: the results are the same. Statement 3 can only be executed after the code block is executed.

17. String constant

int main()
{
    char a[] = "helloworld";  //Defines a character array with the content helloworld
    char* p = a;              //Defines a pointer to hold the address of the first element of the array
    p = "abcd";               //There is a literal constant area for string constants. When '' is used, it takes the address of the first element of the string

    *p = 'm';  //err, the content of the text constant area cannot be changed

    system("pause");
    return 0;
}

18. Character pointer as formal parameter

char* my_strcat(char* src, char* dst)
{
    int n = strlen(src);
    int i = 0;
    while (*(dst + i) != 0)
    {
        *(src + n + i) = *(dst + i);
        //Equivalent to src[n+i] = dst[i];
        i++;
    }
    *(src + n + i) = 0;    //End of string plus \ 0
    return src;
}

int main()
{
    char str1[128] = "hello";
    char str2[128] = "12345";
    printf("%s\n", my_strcat(str1, str2));   //In a chain call, the return value of the previous function is used as the parameter of the next function

    system("pause");
    return 0;
}

19. const modified pointer variable

int main()
{
        char  buf[] = "hello";
        char  str[] = "acbg";
        const char  *p = buf;//const modifies the pointer. The space content pointed to by the pointer cannot be modified through the pointer
        //*p = 'b';  err cannot modify the contents of that space through the P pointer
        char  * const  k = buf;//After the pointer variable k is initialized, the pointer of the k pointer variable itself cannot be changed
//      k = "world"; err 
//      k = str; err

        system("pause");
        return 0;
}

20. Character pointer array

Is an array, and each element is a character pointer.

int main()
{
    char* num[3] = { "haha","hehe","xixi" };
    char** p = num;
    //Define a pointer to store the address of the first element of num. if the first element num[0] is of type char *, the address of char * is char * *.
    //Therefore, p represents the address of the first element in num [], i.e. & num [0];
    //*p represents the value of num[0], that is, the address of "haha";
    // p+1 represents & num[1], then * (p+1) represents the value of num[1], that is, the address of "hehe";
    //*(* (p+1)+1) represents the first e in "hehe";

    for (int i = 0; i < 3; i++)
    {
        printf("%s\n", p[i]);
    }
    printf("%c\n", *(*(p + 1) + 3)); // == *(p[1]+3) == p[1][3]

    system("pause");
    return 0;
}

Output is:

haha
hehe
xixi
e

The following figure shows the above code.

 21. The character pointer array is used as the formal parameter of the main function

int main(int argc, cahr* argv[ ])

argc is the number of parameters when executing the executable program;

argv is a character pointer array that holds the address of the first element of the parameter (string).

22. Exercises

(1)

       void sum(int *a)
       { 
           a[0]=a[1];
       }
       main( )
       {
           int aa[10]={1,2,3,4,5,6,7,8,9,10},i=0;
           for(i=2;i>=0;i--)  
              sum(&aa[i]);
           printf("%d\n",aa[0]);
       }

The output is: 4.

Resolution: when the sum() function is called for the first time, the address of aa[2] is passed in, then a in the sum() function points to aa[2], a[0] is equal to aa[2], and a[1] is equal to aa[3].

(2)

char s[10];
s = "abcd";

Parsing: error. s , is an array name, is a constant, and cannot be assigned.

(3)

If there are the following variable definitions, the following statements are legal:

int i=0, a[10]={0}, *p=NULL;
A. p=a+2  B. p=a[5]  C. p=a[2]+2  D.p=&(i+2)

Analysis: A

A: Legal. A represents the address of the first element, and a+2 represents the address of a[2];

B. C: the left p of the equal sign is of type int * and the right of the equal sign is of type int;

D: i+2 is a constant. You cannot take an address for a constant.

(4)

The output of the following program is:

int f(char* s)
{
    char* p = s;
    while (*p != '\0')
    {
        p++;
    }
    return(p - s);
}

int main()
{
    printf("%d\n", f("HENAN"));

    system("pause");
    return 0;
}

Analysis: 5

Process: the main function calls the f() function and passes in the string, then s points to the address of the first element; Then, p also points to the address of the first element; In while, if the string terminator is not encountered, p+1; Until the end is the length of the string.

(5)

void fun(char s1[])
{
    int i, j;
    for (i = j = 0; *(s1 + i) != '\0'; i++)
    {
        if (*(s1 + i) < 'n')    //*(s1+i) is equivalent to s1[i]
        {
            *(s1 + j) = *(s1 + i);
            j++;
        }
    }
    *(s1 + j) = '\0';
}

int main()
{
    char str[]="morning",*p;
    p = str;
    fun(p);
    puts(p);

    system("pause");
    return 0;
}

Parsing: mig

① When an array is used as a formal parameter of a function, it will degenerate into a pointer, that is, char s1 [] is equivalent to char *s1. If p points to the address of the first element, s1 also points to the address of the first element;

② When s1[i] < 'n', assign the value of s1[i] to s1[j], and then j + +, I + +, continue the cycle.

(6)

The output of the following program is:

int main()
{
    char str[]="abc\0def\0gh";
    char* p = str;
    printf("%s\n",p+5);
    printf("helloxx\0xxworld\n");
    printf("\n------------\n");
    printf("hello%sworld\n", "xx\0xx");

    system("pause");
    return 0;
}

Output is:

ef
helloxx
------------
helloxxworld

Resolution:

When printf() outputs a string, it ends when it encounters the first \ 0 @.

(7)

void fun(char* c, int d)
{
    *c = *c + 1;
    d = d + 1;
    printf("%c,%c,", *c, d);
}

int main()
{
    char a = 'A', b = 'a';
    fun(&b, a);
    printf("%c,%c\n", a, b);

    system("pause");
    return 0;
}

Output: b,B,A,b

Resolution: if the address is passed in, the value will be changed.

(8)

int a = 2;
int f(int* a)
{
    return (*a)++;
}

int main()
{
    int s = 0;
    int a = 5;
    s += f(&a);
    s += f(&a);
    printf("%d\n", s);
}

Output: 11

Resolution:

The f() function called in main() passes in the address of the local variable a;

return(*a) + +, first return * a, that is, the value of local variable a, and then execute + +, that is, a+1.

Similarly, look at the following question:

int main()
{
    int a[5] = {1,3,5,7,9};
    int *p = a;
    printf("%d\n", (*p)++);
    printf("%d\n", *(p++));
    printf("%d\n", *p++);
    printf("%d\n", *p);
}

Output: 1 2 3 5

Parsing: the printf() function is evaluated from right to left.

First: like the above, first output * p, that is, the value of a[0], and then execute * p+1, that is, a[0] = a[0]+1 = 2;

The second one: at this time, + P still points to a[0]. When executing * (P + +), execute from right to left. If you see that there is p + +, execute the output * P first, and then execute + +. After this statement is executed, the output is 2, and P points to a[1];

The third: operator priority. If * and + + have the same priority, then * p + + = * (p + +) will be executed from right to left according to printf(). After this statement is executed, the output is 3, and p points to a[2];

Fourth: output a[2].

Keywords: C C++

Added by beginneratphp on Thu, 30 Dec 2021 20:42:38 +0200