C language learning -- pointer

Posted by francoisp on Thu, 20 Jan 2022 11:27:34 +0100

Definition of pointer:

  • The need to use pointers to save an address
  • Scene transfer and offset used by pointer

Is to save the address and pass the parameters

#include <stdio.h>

int main()
{
   int i=5;
   int* i_pointer=&i;
}
                                                                     

Pointer variables of type int can only correspond to int variables (what model corresponds to what)

Pointer variable is used to save address and get variable address

 

The definition format of pointer is as follows


Base type   *   Pointer variable name
The type is preceded by the variable name

 

 

 

 

 

 

Basically, you can pass it like this, and then * value

 

Some questions about * and &?

If it has been implemented

pointer_ 1 = & A, here's the address

So & * pointer_ What does 1 mean?

&The priority is the same as * but in order from right to left

First * pointer_1 value, equivalent to * & A

Take out the value of variable a (5), so follow & A (5)

&* pointer_ 1 equivalence and &a# are addresses

So what does * & a mean?

First &a take out the address, that is, the pointer_1 same

In the * value operation, take out the variable a(5)

*&A is equivalent to a, both of which are values

  • Summary: * value (dereference) & Address (Reference)

 

 

For array pointers

such as

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

int main()
{
    int a[5]={1,2,3,4,5};
    int* p;//Value a pointer variable, and the result is also its base type (here is int)
    
    p=a; //First address

    
    printf("%d\n",*p);

    getchar();
    system("pause");
    return 0;
}

This situation

 

 

 

In this case, the single pointer refers to the starting position of the array, which is a[0]

How do you want to print, use a loop

for (int i = 0; i < 5; i++)
    {
            printf("%d\n",*(p+i));
    }

 

Pay attention to ensure that the two side types are the same: a [] array {p=a} A is also the initial position of the array

If & A is the initial address a[1] of the a array, take the address again

So you can't use p = & A

 

The pointer increases and decreases automatically

i + + and + + i have been seen before

What about * p + +, * p -- * + + p

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

int main()
{
    int a[3]={2,7,8};
    int *p;
    int j;
    p=a;//Let pointer variable p Point to the beginning of the array
    j=(*p)++;//

    printf("a[0]=%d,j=%d,*p=%d\n",a[0],j,*p);
    getchar();
    system("pause");
    return 0;
}

Try to say the values of a[0] *p and j

 

Answer: first (* p) access the space at the beginning of the 2 array

The overall j (* p) + + change points to the next spatial value, that is, the space with the numerical value of 3

At this time, the initial position address of the array remains unchanged, and the value in it becomes 3

So a[0] is 3 * p and the whole becomes 3

 

At this time, let's talk about the value of J. first, let's look at if j=i + +; i=1; What is j equal to after the end?

1. First of all, take it out separately and say + + i and i + +, which mean the same, that is, i=i+1.

2. As an operator, it is a=i + + or a=++i. The situation is different.

First say a=i + +. This operation means to assign the value of i to a first, and then execute i=i+1;

And a = + i, which means that i=i+1 is executed first, and then the value of i is given to a;

For example, if i=4 at first.

Then, after executing the statement a=i + +, a=4, i=5;

Then, after executing the statement a=++i, i=5, a=5;

Similarly, i -- and -- i are used the same way.

Author: let nature take its course
Link: https://www.zhihu.com/question/19811087/answer/207494860

If you pull it out alone, it will be + 1, and the operator will be transformed

j=i++; Assign value first, j=1; Then i++=2; i=2;

j=++i; First i+1; i=2; Then assign value, j=2;

 

 

So the j value of the above code

j=(*p)++;

(* p) + + value 3 initial position of address array

But j = assign value first, j = (* P) = assign value at the beginning, so * p =2

Later operation + +

*p is 3

Replace the value of the address of array a[0]

 

Pointers and one-dimensional arrays

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

void change(char d[])
{
    d[0];
}

int main()
{
    char c[10]="hello";
    change(c);
getchar(); system(
"pause"); return 0; }

 

For example, this function call is

d [] is actually an i pointer array like * d

But this d[] is not done, so arrays should not be placed in the formal parameters of the function

Just put a pointer variable

void change (char *d)

Cannot get array length

 

 void change(char *d)

{
*d='H';
d[1]='E';
*(d+2)='L'

}

This can change the value

d[1] is passed to the function by c[1]

 

Pass the address of c directly to the function parameter pointer d

Equal to d=c, same address

 

Dynamic memory request malloc

Request 5*sizeof(int)=20 bytes

The array is defined at the beginning, and the data is placed in the stack space

 

 

Process address space: stack

explain : the size of stack space is determined at compile time. If the size of space used is uncertain, heap space should be used.

 

 

 

 

 

    int i; //How much space to apply for
    scanf("%d",&i);
    char* p;
    p=(char*) malloc(i); //malloc Dynamic application space
    //malloc The unit of space requested is bytes
    //malloc Returned is void*Type pointer
    //(char*) Strong rotation
    
    int *p1;
    p1=(int*)malloc(20);//malloc The request is bytes. Here, 20 bytes are requested
    //1 individual int It takes 4 bytes, so it is equal to 5 bytes applied int,be equal to a[0]-a[4]

Total application code:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
    int i; //How much space to apply for
    scanf("%d",&i);
    char* p;
    p=(char*) malloc(i); //malloc Dynamic application space
    //malloc The unit of space requested is bytes
    //malloc Returned is void*Type pointer
    //(char*) Strong rotation
    
    strcpy(p,"malloc success");
    puts(p);


    getchar();
    system("pause");
    return 0;
}

 

 

 

Apply for 100 bytes for "malloc success", as shown in the figure:

 

 

But also free memory

The pointer p offset error is recorded here

    int i; //How much space to apply for
    scanf("%d",&i);
    char* p;
    p=(char*) malloc(i); //malloc Dynamic application space
    p++;
    strcpy(p,"malloc success");
puts(p);

Here, p + + only wants to print the following "alloc success", but free(p) will report an error

 

 

You can write a * p1

char* p;
    char *p1;
    p=(char*) malloc(i); //malloc Dynamic application space
    //malloc The unit of space requested is bytes
    //malloc Returned is void*Type pointer
    //(char*) Strong rotation
    p1++;
    strcpy(p,"malloc success");
    strcpy(p1,p);
    puts(p);
    free(p);

 

 

last

 free(p) ; p=NULL ; Release operation

After release, p is a wild pointer, so there is no point

So p=NULL;

If the p value is not NULL, it is called a wild pointer

 

Note: the heap space will not be released with the end of the sub function, but must be free by itself

 

 

Stack space and heap space difference

Stack space:

Take an example:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>


char* printf_stack() //char* return char* type
{
char c[17]="i am print_stack";
puts(c); //Can print normally
return c;  //return char* c
}

int main()
{
   char* p;
   p=printf_stack();//p=c;
   puts(p);
    
    getchar();
    system("pause");
    return 0;
}

 

 

 

Function inside the normal printing, the following main function inside the normal printing

The reason is that the stack (automatic space allocation) function will be released automatically after it is completed

Abnormal printing

Because puts(p) takes up stack space at this time

 

Heap space:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char* printf_stack() //char* return char* type
{
char c[17]="i am print_stack";
puts(c); //Can print normally
return c;  //return char* c
}

char* printf_malloc() //char* return char* type
{
       char* p=(char*)malloc(30);//Request heap space memory
       strcpy(p,"I  am print_malloc");
       puts(p);
       return p;  //return char* p
}

int main()
{
   char* p;
   p=printf_stack();
   //puts(p);
   p=printf_malloc();
   puts(p);
   
    getchar();
    system("pause");
    return 0;
}

 

 

This is because: the application heap space will not end because of the end of the function, and will always be available unless free

 

Let's take an example:

Input an integer number, then apply for the memory of the corresponding size space, and then read a string. The input length of the string is less than the size of the initial input integer number, and finally output the input string (it is unnecessary to consider that the input string is too long and exceeds the memory size);

 

 

 

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
    int n; //How much space to apply for
    scanf("%d",&n);
    char* p;
    p=(char*)malloc(n);
    char c;
    scanf("%c",&c);
    gets(p);
    puts(p);
    
 
    getchar();
    system("pause");
    return 0;
}

 

Let's mainly talk about char c here;    scanf("%c",&c);’

Both puts and gets use buffers

Because there is scanf("%d",i) in front, scanf enters a number in the buffer

For example, 10\n \ n is the terminator

The buffer is

 

 

scanf is still in the buffer after reading \ n

 

So, char c;    scanf("%c",&c); To remove the \ n

 

 

Initialization of character pointer and character array

#include <string.h>

int main()
{
    char* p="hello";//String constant"hello"First address assigned to p
    char c[10]="hello";//Equivalence and strcpy(c,"hello");
    //c[0]='H';
    printf("c[0]=&c\n",c[0]);
    printf("p[0]=&c\n",p[0]);
    //p[0]='H'; //The constant area data cannot be modified
    //p="world";//String world Address assigned to p
    //c="world";//illegal

    getchar();
    system("pause");
    return 0;
}
 //p[0]='H'; // The constant area data cannot be modified

Memory has permissions: r (read), w (write), rw

At this time, the memory in the address of p[0] is not writable

 

 

The string constant exists in the data area, which is neither heap nor stack. It needs memory to apply for reading and writing

 

 

 char c[10] ="hello world"

Take the string variable hello world from the data area to the stack

So it's readable and writable

So c[0] you can get 'H' from the data area

And pointer p[0]:

 p[0]='H'; // The constant area data cannot be modified

At this time, 'H', in the data area, you cannot read variables or get the starting address,

 

Look again

p="world";// Assign the address of the string world to P

”"world" is a string data area. The starting address is

In this way, we can assign its starting address to p

 

//c="world";// illegal

c is an array. The address in it will not be changed and cannot be assigned directly

 

Secondary pointer

  • The secondary pointer only serves the transfer and offset of the primary pointer

  • To change the value of a variable in a subfunction, you must pass in the address of the variable

  • To change the value of a pointer variable in a sub function, you must pass in the address of the pointer variable

 

Like this, the second level pointer is that p is a pointer, * * p2 = & p; Get the original address of p

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void change(int** p,int *pj)
{
    *p=pj; //*p Equivalent to pi
}

int main()
{
    int i=10;
    int j=5;
    int* pi;
    int* pj;
    pi=&i;
    pj=&j;
    printf("i=%d,*pi=%d,*pj=%d\n",i,*pi,*pj);//Equal to 10, 10, 5 
    
    change(&pi,pj);
    printf("after change i=%d,*pi=%d,*pj=%d\n",i,*pi,*pj);
    //The goal is to make*pi The value of is 5
 
    getchar();
    system("pause");
    return 0;
}

 

 

Topics: C