A Review of Some C Language Knowledge Points Learned in Student Age

Posted by sinter4911 on Tue, 10 Sep 2019 12:48:20 +0200

Articles Catalogue

Pointer

A Preface

Following the previous article, the pointer in C language is reviewed and summarized. The examples in this paper are all my pure manual input, compiled and practiced in Linux environment. Because Linux is used most of the time in daily work, many in-depth knowledge of Linux system needs to master C language in order to understand deeply, so a review of C language is made. After many years of work, I found that all the knowledge I had learned was not worthless, but that I was too shallow, too eager for quick success and instant benefit. Like C language, it can still play an important role in the current work, often with twice the result with half the effort. As for this, it will be perfectly presented in my share in the future. Please pay attention to it.

Two examples

# include<stdio.h>

int main(int argc,char *argv){
  int i = 10, j, *p, *q, *x = &i;
  p = &i;
  q = p;
  j = *&i;
  printf("p = %d\n",*p);
  printf("q = %d\n",*q);
  printf("x = %d\n",*x);
  printf("j = %d\n",j);
  scanf("%d",&i);
  printf("p = %d\n",*p);
  printf("q = %d\n",*q);
  printf("x = %d\n",*x);
  printf("j = %d\n",j);
  return 0;
}
/*
p = 10
q = 10
x = 10
j = 10
98
p = 98
q = 98
x = 98
j = 10
*/

In this example, the pointer variable x is initialized at the same time as it is declared. This operation is legal. Initialization after declaration needs to be initialized in a way similar to pointer variable p, which still cannot be compiled by using * P = &i.

Using pointer values in * p is called indirect addressing. The * here is called the indirect addressing operator.

When multiple pointer variables point to the same variable, the value of the pointer variable changes with the change of the value of the variable.

*& i uses the & operator to generate a pointer to the pointer variable, and the * operator to the pointer can return to the original variable.

# include<stdio.h>

int main(int argc,char *argv){
  int *p, *q, i = 989, j = 2019;
  p = &i;
  q = &j;
  q = p;
  printf("p = %d\n",*p);
  printf("p : %p\n",p);
  printf("j = %d\n",j);
  printf("q = %d\n",*q);
  printf("q : %p\n",q);
  return 0;
}
/*
p = 989
p : 0x7fff51751e5c
j = 2019
q = 989
q : 0x7fff51751e5c
*/

//The pointer variables of the same type can be copied with each other and then point to the same variable.

```c
# include<stdio.h>

int main(int argc,char *argv){
  int *p, *q, i = 989, j = 2019;
  p = &i;
  q = &j;
  *q = *p;
  printf("p = %d\n",*p);
  printf("p : %p\n",p);
  printf("j = %d\n",j);
  printf("q = %d\n",*q);
  printf("q : %p\n",q);
  return 0;
}
/*
p = 989
p : 0x7ffc00d359ac
j = 989
q = 989
q : 0x7ffc00d359a8
*/

This code looks very similar to the previous one, but the results are quite different. The assignment statement * q = P copies the value of the pointer variable p into the object to which Q points, that is, j, but the addresses of P and Q are different.

# include<stdio.h>

int main(int argc,char *argv){
  char i, *p;
  p = &i;
  scanf("%c",p);
  printf("p = %c\n",*p);
  printf("i = %c\n",i);
  return 0;
}
/*
e
p = e
i = e
*/

In this code, if the sentence "p = i;" is deleted, the code can not be compiled smoothly. The variable p in function scanf() is equivalent to the character read in & i, scanf() and stored in I. At this point, the operator &can no longer be used in scanf().

# include<stdio.h>

int main(int argc,char *argv){
  int a, b;
  int *max(int *,int *);
  scanf("%d%d",&a,&b);
  printf("The max number is: %d\n",*max(&a,&b));
  return 0;
}

int *max(int *a, int *b){
  *a = *a + 5;
  if (*a > *b)
    return a;
  else
    return b;
}
/*
1 4
The max number is: 6
*/

Pointer variables are passed and calculated as formal parameters, and the return value type of parallel function is pointer. Let's move on to the next piece of code:

# include<stdio.h>

int main(int argc,char *argv){
  int a, b;
  int max(int *,int *);
  scanf("%d%d",&a,&b);
  printf("The max number is: %d\n",max(&a,&b));
  return 0;
}

int max(int *a, int *b){
  *a = *a + 5;
  if (*a > *b)
    return *a;
  else
    return *b;
}
/*
1 4
The max number is: 6
*/

The same input, the same output, the form is different, in fact, the implementation principle is the same, all return pointers, can be understood by analogy.

# include<stdio.h>

int main(int argc,char *argv){
  int x = 2019, y=2023;
  int *a = &x, *b = &y, c;
  c = (*a + *b) * 2 + 20;
  printf("Sum: %d\n",c);
  return 0;
}
// Sum: 8104

The fourth and fifth lines of the above code interchange and will not be compiled. C language strictly follows the principle of declaration before use, pointer is no exception. Indirect addressing can be used directly in expressions. It should be noted that * in this line is not an indirect addressing operator. Its function is to inform the compiler A and B that they are two pointers to int-type variables. "C = (* a + b) * 2 + 20;" The first two * in this line are indirect addressing operators and the third * is multiplication operators.

# include<stdio.h>

int main(int argc,char *argv){
  int p;
  int example(int *);
  scanf("%d",&p);
  printf("%d\n",example(&p));
  return 0;
}

int example(int *p){
  int a = 10086;
  printf("The original value is: %d\n",*p);
  p = &a;
  return *p;
}
# include<stdio.h>

int main(int argc,char *argv){
  int p;
  int example(int *);
  scanf("%d",&p);
  printf("%d\n",example(&p));
  return 0;
}

int example(int *p){
  printf("The original value is: %d\n",*p);
  *p = 10086;
  return *p;
}
# include<stdio.h>

int main(int argc,char *argv){
  int p;
  int example(const int *);
  scanf("%d",&p);
  printf("%d\n",example(&p));
  return 0;
}

int example(const int *p){
  int x = 10086;
  printf("The original value is: %d\n",*p);
  p = &x;
  return *p;
}
/*
98
The original value is: 98
10086
*/

The above three pieces of code can achieve consistent results after compilation and execution, but the following code can not be compiled:

# include<stdio.h>

int main(int argc,char *argv){
  int p;
  int example(const int *);
  scanf("%d",&p);
  printf("%d\n",example(&p));
  return 0;
}

int example(const int *p){
  printf("The original value is: %d\n",*p);
  *p = 10086;
  return *p;
}

This shows that when const keyword is used, the integer pointed by the pointer cannot be changed, but the pointer itself can be changed. Because arguments are passed by value, assigning new values to p through pointer pointing elsewhere will not have any effect on the outside of the function. The keyword const cannot be omitted when declaring. Continue with the code below.

# include<stdio.h>

int main(int argc,char *argv){
  int p;
  int example(int * const);
  scanf("%d",&p);
  printf("%d\n",example(&p));
  return 0;
}

int example(int * const p){
  printf("The original value is: %d\n",*p);
  *p = 10086;
  // int x = 10086;
  // p = &x;
  return *p;
}
/*
98
The original value is: 98
10086
*/

In this code, if you cancel the comment section, you can't compile it. Here, you can change the integer pointed by the pointer, but not the pointer itself. Further attempts:

# include<stdio.h>

int main(int argc,char *argv){
  int p;
  int example(const int * const);
  scanf("%d",&p);
  printf("%d\n",example(&p));
  return 0;
}

int example(const int * const p){
  printf("The original value is: %d\n",*p);
  // *p = 10086;
  // int x = 10086;
  // p = &x;
  return *p;
}
/*
98
The original value is: 98
98
*/

Two const keywords appear in this code. Cancellation of any part of the three lines commented in the code cannot be compiled. This situation shows that after this declaration, neither the integer pointed by the pointer can be changed nor the pointer itself can be changed. However, this situation is relatively rare.

Three Summaries

This part mainly reviews the pointer, uses a longer space to verify the const keyword, there may be more misunderstandings, I hope you will give more advice, communicate and communicate, and make progress with each other.

Topics: C Linux