3

Summary

1) The essence pointer is a variable. The special feature is that pointer is the memory address (the number of each storage unit in the : the smallest storage unit in the computer is 1 byte, that is, the number of each byte is A memory address)

2) All elements in the program exist in memory, so program elements can be accessed through memory addresses

3) The essence memory address is an unsigned integer (4 bytes or 8 bytes); 4 bytes and 8 bytes correspond to 32 bits and 64 bits, respectively, so the 32-bit and 64-bit systems we often refer to is the maximum memory address that can be accessed by 1610667c63c248. Because 64-bit systems can support greater memory addressing, 64-bit systems can run more programs simultaneously than 32-bit systems.

4) Only through memory address + length can the value saved in a variable be determined. The memory address is just a starting value. Only when the type information is used to know how much memory it occupies and how to read it, can the value stored in the variable be accurately read.

5) When the function parameter is a pointer ( call by address), the value of the external variable of the function can be modified within the function; using a pointer as a parameter can be used as a outgoing parameter, so that the function can return multiple values.

6) For the array int a[5], a and &a:

  • a can be regarded as , representing the address of the first element of the array, the value is 0xA, the type is int*, that is, the memory length is 4
  • &a is the address of the array, the value is 0xA, and the type is int(*)[5], that is, the memory length is 20. Pointer to the array: int(*pArr)[5] = &a;

7) The equivalent usage of pointers and arrays:

int a = {1, 2, 3, 4, 5};
int* p = a;

a[i] <--> *(a + i)
     <--> *(p + i) <--> p[i]

8) In C language, the type of string constant is char* (const char* in C++);
int v = *p++; equivalent to int v = *p; p++; because (*) has the same priority as (++)

9) The function is essentially a piece of code in memory, and occupies a piece of continuous memory. The function name is the entry address of the function (the starting address of the function body code). By caller of the function name, nature to specify a specific address jump execution. Therefore, you can define a pointer to save the entry address of the function: type (*pFunc)(param) = funcName;

10) Q: Since functions can be directly called by function names, why do we need function pointers?
Answer: You can define function pointer parameters. uses the same code to achieve different functions. The calling function only knows that the function prototype is like this, but it doesn't know which function will be called. function pointer is the implementation mechanism of the callback function: when the function is used as a parameter, it constitutes a callback;

11) The essence of the heap space is the spare "memory warehouse" , the available memory reserved in the unit of

12) In the C language, the void* pointer and other types of pointers type* can perform mutual assignment, because the C language does not strictly check the pointer. However, you must pay attention to the data type of the operation when using it. void* is only an initial address and does not contain the length information of .

13) malloc is used to apply for memory in the heap space in bytes; free is used to return the memory in the heap space, malloc is not free, memory leaks; multiple frees, crashes.

14) The pointer is a variable, so naturally there will be pointers to pointers, that is, multi-level pointers. Before variables can use pointers to call by address, then you can also use multi-level pointers to call pointers by address, changing the value of the external pointer inside the function.

two-dimensional array is essentially a one-dimensional array, so the two-dimensional array name a represents the first element of the array, that is, a[0] represents a one-dimensional array; the type of a is type (*)[size2 ]

int arr[2] = {0};
int* pa = arr;
int (*pArr)[2] = &arr;


int bArr[2][2] = {0};
int (*pb)[2] = bArr;
typedef int (oneDimension)[2];
oneDimension (*pbArr)[2] = &bArr;

16) forbidden to return the address of a local variable, because the life of a local variable ends after the function call ends. What is returned at this time is a wild pointer.

1. Pointer

1.1 The nature of pointers

The pointer is essentially variable in the C language

  • Because it is a variable, used to save the specific value
  • , the value saved by the pointer 1610667c63c5b7 is the address in the memory
  • What is a memory address?

    • Memory is a storage component in a computer, and each storage unit has a fixed and unique number (each storage unit: 1 byte)
    • The number of the storage unit in the memory is the memory address

All elements in the program exist in memory, so program elements can be accessed through memory addresses.

Get address:

  • Get the address of the program element through the & operator in C language
  • & Get the starting address of variables, functions, and arrays
  • memory address is essentially an unsigned integer (4 or 8 bytes)

    int var = 0;
    
    printf("var address = %p\n", &var);

1.2 Pointer syntax

Pointer definition syntax: type * pointer

  • type-data type, determines the length range when accessing memory
  • * -flag, which means to define a pointer variable
  • pointer-variable name, follow C language naming rules

Pointer memory access: * pointer

  • The pointer access operator (*) acts on the pointer variable to access memory data
  • The type of pointer determines the length range when accessing memory through the address
  • The pointer type uniformly occupies 4 bytes or 8 bytes

Military rules when you first learn the pointer:

  • A pointer of type type* type (such as float and int type variables, both are 4 bytes, but the binary in the memory is different. If the stored int is int, it can be read as a float , It must be wrong)
  • prohibits the assignment of pointers of different types to each other
  • forbidden to assign ordinary values to pointers as addresses

    • Note: The address saved by the pointer must be a valid address

Question: Is it really impossible to exchange the values of two variables in a function before?
Thinking: If you want to exchange the values of two variables, you must modify the variables outside the function number inside the function? What if the parameter is a pointer? Is it feasible to pass in the address of the variable and directly modify the address through the memory address in the function?

void swap(int* a, int* b)
{
    int t = *a;
    *a = *b;
    *b = t;
}

By passing pointers, the variables outside the function can be modified inside the function. In addition, the return of the function can only return one value. If a pointer is used in the parameter, the function can return multiple values. passes the parameter.

2. Pointers and arrays

Question: The essence of an array is a piece of contiguous memory. So, what is the address of the array? How to get it?

2.1 Pointers and ordinary arrays

  • Use the address character & to get the address of the array: &a, &a represents an address (the address of the array), the value is 0xA, the type is int(*)[5] , that is, the length is 20. Pointer to array: int(*pName)[5] = &a;
  • The array name can be seen as a constant pointer: a, a represents an address (the address of the first element of the array), the value is 0xA, the type is int* , that is, the length is 4.
  • When the pointer points to an array element, pointer arithmetic (pointer movement) can be performed

    int a[] = {1, 2, 3, 4, 5};
    int* p = a;
    p = p + 1;

Note: The array name can only be regarded as a pointer, representing the address of element 0.

The equivalent usage of pointers and arrays:

int a = {1, 2, 3, 4, 5};
int* p = a;

a[i] <--> *(a + i)
     <--> *(p + i) <--> p[i]

2.2 Pointers and strings

String Supplements

  • Question: What is the type of string constant in C language?
  • Answer: char* type, a pointer type

    printf("%p\n", "GrandSoft");

Pointer movement combination punch: int v = *p++;

  • The pointer access operator (*) and the increment operator (++) have the same precedence
  • So, first get the value from the memory pointed to by p, and then move p
  • Equivalent to: int v = *p; p++;

3. Pointers and functions

Question: When a function is called, it will jump to the code corresponding to the function body for execution. Then, how do you know the specific location of the function body code?

In-depth function tour:

  • function is essentially a piece of code in memory (occupies a piece of continuous memory)
  • Function has a type, function type is composed of return type and parameter type list

    Function declarationTypes of
    int sum(int n)int(int)
    void g(void)void(void)

Function pointer: type func(type1 a, type2 b)

  • The function name is the function entry address, and the type is type (*)(type1, type2)
  • For func functions, func and &func same value, and has the same meaning
  • Pointer to function: type (*pFunc)(type1, type2) = func;

    int (*pFunc)(int a, int b) = nullptr;
    pFunc = add;
    printf("%d\n", pFunc(1, 2));    // 1)
    printf("%d\n", (*pFunc)(1, 2)); // 2)

    Understanding of the two calling methods:
    1) The function pointer saves the entry address of the function, and the function name also saves the entry address of the function. The function name can directly call the function, so it is reasonable to use pFunc to directly call the function.
    2) pFunc is an address, the code of the function stored in it, the function body is obtained by using *pFunc, and it is reasonable to call the function directly.

Question: Since a function can be called directly by its name, why do we need to use a function pointer?
Answer: In this way, you can use the function pointer as a function parameter.

  • The essence of function pointer is pointer (variable, save address)
  • Function pointer parameters can be defined, uses the same code to achieve different functions

    int calculate(int a[], int len, int(*cal)(int, int))
    {
      int ret = a[0];
      int i = 0;
      for(i=1; i<len; i++)
      {
          ret = cal(ret, a[i]);
      }
    
      return ret;
    }

    According to the different cal functions that are passed in, it is possible to realize, for example, array multiplication, addition, division and so on. In calculate, only knows the prototype of the function to be called, but specifically calls and what function is executed, only knows when cal is executed.

4. Pointers and heap space

Discuss the memory space again: different memory areas have different uses

  • Global data area: store global variables, static variables
  • Stack space: store function parameters, local variables
  • Heap space: used to dynamically create variables (arrays)

The nature of heap space:

  • spare "memory warehouse", available memory reserved in bytes
  • The program can apply for the use of memory from the "warehouse" when needed ( dynamically borrowed)
  • When the requested memory is no longer needed, it needs to be returned in time ( dynamic return)

Preliminary knowledge-void*

  • The void type is the basic type, and the corresponding pointer type is void*
  • void* is a pointer type, its pointer variable can save the address
  • The data in the memory cannot be obtained through the void* pointer (no length information)

Use of heap space:

  • Toolkit: stdlib.h
  • Application: void* malloc(unsigned bytes)
  • Return: void free(void* p), p must be an address in the heap space

Principles for the use of heap space:

  • It’s not difficult to pick up
  • After malloc applies for memory, it should be determine whether the application is successful
  • free can only apply for the released memory, and cannot be released multiple times

5. Analysis of the pointer problem

5.1 Multi-level pointers

You can define the pointer of the pointer to save the address of other pointer variables

type v;
type* pv = &v;
type** ppv = &pv;
type*** ppv = &ppv;
...

You can get the address of the pointer by using the pointer, then you can change the value stored in the pointer inside the function.
Call by pointer to modify the value of the pointer outside the function:

int getDouble(double** pp, unsigned int n)
{
    int ret = 0;
    double* pd = (double*)malloc(sizeof(double) * n);

    if(pd != NULL)
    {
        *pp = pd;

        ret = 1;
    }

    return ret;
}

5.2 Two-dimensional array

Question: The type of the one-dimensional array name is type , so is the type of the two-dimensional array name type *?

Discuss the two-dimensional array again:

  • The essence of a two-dimensional array is a one-dimensional array, that is: the elements in the array are a one-dimensional array
  • Therefore: a two-dimensional array a[][], a represents a[0], the first element is a one-dimensional array

    int b[][2] = {1, 2, 3, 4};
    int(*pnb)[2] = b;

This article is summarized from "Introduction to C Language Course" by Tang Zuolin from "Ditai Software Academy".
If there are any errors or omissions, please correct me.


bryson
169 声望12 粉丝