Deep study of C language 2. Pointer

Keywords: C Back-end

catalogue

How to put it? I think if you don't write this thing again, you may be busy in the future. Moreover, the pointer is also an important part of the C language. Besides, many students will be tossed by the pointer. Can't we help each other?

1, Some simple analysis of the pointer

  1, Function of pointer

1. Processing complex data,

2. Be able to control the memory allocation of the computer

***3. Return multiple parameter values in function call

2, Pointer and pointer variable

1. What is the pointer?

In order to operate the data in the memory unit, the computer usually accesses by address. That is, the memory unit is identified and numbered.

2. Method of using variables

3. The difference between the two

3, Some analysis of the pointer

1. Pointer variable name must be a legal identifier.

4, Application of pointer

1. Pointer operation

2. Pointer - pointer

3. Pointer inequality

4.*p + + means to use the value of * p first and then + +; It's the same as before

2. Pointer transfer parameter

OK, now let me talk about the principle of pointer parameter transmission

5, String handler

  1.strlen function

2.strcmp function

3.strcpy function

4.strcat function

6, String and character pointers

The storage location of string constants in memory is automatically arranged by the system. String storage is actually a special one-dimensional array. Similar to arrays, all characters in string constants are stored continuously in memory. The value of the string constant is the address of the storage unit where the first character of the string constant is stored.

How to put it? I think if you don't write this thing again, you may be busy in the future. Moreover, the pointer is also an important part of the C language. Besides, many students will be tossed by the pointer. Can't we help each other?

1, Some simple analysis of the pointer

  1, Function of pointer

1. Processing complex data,

2. Be able to control the memory allocation of the computer

***3. Return multiple parameter values in function call

2, Pointer and pointer variable

1. What is the pointer?

In order to operate the data in the memory unit, the computer usually accesses by address. That is, the memory unit is identified and numbered.

For example, a computer is like a hotel, and the elements that need to be stored in the computer are like people who want to stay in the hotel. If people want to stay in the hotel, they need to open a room. The room they open is the address to store data, and the room number is the address name. We can find the person according to the room number, and we can also find the stored element value according to the address.

When the program executes, it translates the variable into its memory address for operation.

2. Method of using variables

1. Direct access to variables

int x=89;
printf("%d",x);

Is to go directly to the door and access and use it

Read the content directly through the variable address

2. Indirect access variables

Indirectly, the content in the pointer variable (that is, the address of a variable) is further read by accessing this address.

#include<stdio.h>
int main(){
	int a=3,*p;
	p=&a;
	printf("a=%d,p=%d\n",a,*p);
	*p=10;
	printf("a=%d,p=%d\n",a,*p);
	printf("Enter a:");
	scanf("%d",&a);
	printf("a=%d,p=%d\n",a,*p);
	(*p)++;
	printf("a=%d,p=%d\n",a,*p);
	return 0;
} 

3. The difference between the two

C language uses pointers to operate on the address of variables. Pointers are variables used to store memory addresses.

If the value of a pointer variable is the address of another variable, it is called the pointer variable     point     That variable.

In C language, pointer is regarded as a concept and one of the pronouns of computer memory address. The pointer variable itself is a variable. Different from the general variable, it stores the address. In most cases, the differences between them are not particularly emphasized.

It is generally understood as a pointer variable that stores a memory address.

3, Some analysis of the pointer

We won't talk about how to define and so on. It's too simple. Now, we still need to understand these basic things.

1. Pointer variable name must be a legal identifier.

2. The pointer value can be a special address 0 or a positive integer representing the machine address.

3. The best habit of using data is to initialize immediately after definition. When using a pointer, we first need to initialize it as a null pointer, that is, point to 0;

#include<stdio.h>
int main(){
	int x=5342;
	int *p=NULL;//In order to improve the readability of the program, it is null during initialization, and its ASCL code value is 0; 
	p=&x;
	printf("if i know the name of the variable,i can get it'svalue by name:%d\n",x);
	printf("if i know the address of the variable is:%x,then i also can get it is value by address:%d\n ",p,*p);
	return 0;
} 
*p=NULL;

4. The array name is different from the pointer. After reading the previous array article, you should know that the array name is the address of the first element of the array, and the pointer is also the address of an element, but the essence of the pointer is a variable pointing to the address. However, the array name is an address constant and cannot be changed. Therefore, operations similar to array name + + are illegal.

*****5. Pointer type question (I don't mark this thing red or take the title. I just play it. I just don't like those who don't seriously read what I write. It takes me two or three hours to write a blog. It takes me a few minutes to read it. What do I think? No one commented and asked questions. Have I made it clear? Have I understood it?)

Such an important thing, seriously understand.

The type of a pointer variable does not refer to the type of the pointer variable itself, but the data type of the variable it points to.

No matter what type of pointer variables, they are used to store addresses. Therefore, the memory space occupied by the pointer variable itself has nothing to do with the variable data type it points to. Although the memory space occupied by different types of variables is different, the memory space occupied by different types of pointer variables is the same. Depending on your computer, it is 4 or 8 bytes.

***Dereference: find the corresponding memory and data in memory through the pointer.

Generally speaking, once the type of pointer variable is determined, it can only point to variables of the same type.

Only pointers of the same type can be assigned. All data types are the same. The types are different. How to assign? It will cause data loss.

**The pointer type directly determines the permission of pointer dereference (several bytes) and how far the pointer can go in one step, that is, how far the pointer plus one can go (several bytes).

The pointer dereference space of different data types is different. Go to the computer and practice it yourself,

You may think it's nothing, but this is an application scenario that runs through all pointers. Be sure to find out.

6. Field pointer: the pointing position is unknown (random / incorrect / no explicit limit)

1) Uninitialized: the pointer variable will get a random address, and it is impossible to determine who the address belongs to. It's not sure if this address exists.

2) Pointer out of bounds: (mainly used in arrays) C language stipulates that arrays can cross the bounds backward, but not forward. I don't know why...

3) Space release pointed to by pointer: common in custom functions

#include<stdio.h>
int *test(){
	int a=10;
	return &a;//After the test function ends, the storage unit of a is released, the data is lost, and the address of a is returned, but there is no value in the address
}
int main(){
	int *p=test();
	*p=20;
	return 0;
}

Therefore, p is the wild pointer.

4, Application of pointer

1. Pointer operation

1. Pointer addition and subtraction constant: represents the addition and subtraction of pointer address

  int type data takes up four bytes, and then calculate the difference between the above three addresses.

2. Pointer - pointer

  Why should I show you this? Because this is a wrong demonstration, the operation of pointer minus pointer can only be used in the same space. Like array, the value obtained by pointer minus pointer is the number of elements between two pointers.

#include<stdio.h>
int main(){
	double a[2],*p,*q;
	p=a;
	q=p+1;
	
	printf("%d\n",q-p);
	printf("%d\n",(int)q-(int)p);

	return 0;
} 

Pointer plus pointer makes no sense. Address plus address makes no sense.

3. Pointer inequality

The comparison is about the same space. Take the above example, P2 > P1;

This one is used less.

4.*p + + means to use the value of * p first and then + +; It's the same as before

2. Pointer transfer parameter

The return value of a user-defined function can only return one value through the return statement. What should I do if I want to return multiple values?

Pointer is a good method. The structure to be learned later can also do it, but the essence is to do it through the pointer method.

#include<stdio.h>
void swap1(int x,int y),swap2(int *px,int *py),swap3(int *px,int *py);
int main(){
	int a=1,b=2;
	int *pa=&a,*pb=&b;//Remember to initialize any data before using it, and so is the pointer.
	swap1(a,b);
	printf("After calling swap1:a=%d b=%d\n",a,b);
	
	a=1,b=2;//Each time you use the values of a and b, initialize them first to avoid the change of the values of a and b.
	swap2(pa,pb);
	printf("After calling swap2:a=%d b=%d\n",a,b);//Only swap2 can realize the exchange of variable values 
	
	a=1,b=2;
	swap3(pa,pb);
	printf("After calling swap2:a=%d b=%d\n",a,b);
	
	return 0;
}
void swap1(int x,int y){
	int t;
	t=x;
	x=y;
	y=t;//The formal parameter cannot change the argument, and the value is changed from the argument to the formal parameter. When the function call ends, the storage space borrowed by the variable is recovered and the data is cleared. 
}
void swap2(int *px,int *py){
	int t;
	t=*px;
	*px=*py;
	*py=t;//The exchange of variables returns the address. The addresses of px and py have not changed. 
}
void swap3(int *px,int *py){
	int *pt;
	pt=px;
	px=py;
	py=pt;//In this way, the value cannot be changed, and the formal parameter cannot change the argument 
}

The following example is more difficult, that is, the problem of weekdays and leap years. To be honest, many things are difficult for beginners to think of. If you really do it seriously  , I don't think I can be so concise, which also tells us that we should read more excellent code, learn slowly and accumulate gradually. These codes in front of us are usually the methods summarized by predecessors, which can benefit us a lot.

#include<stdio.h>
void month_day(int year,int yearday,int *pmonth,int *pday);

int main(){
    int day,month,year,yearday;
		
	printf("input year and yearday:");
	scanf("%d%d",&year,&yearday);
	//The function declaration is passed to the user-defined function, and the part corresponding to the pointer is the address. 
	month_day(year,yearday,&month,&day);
	
	printf("%d-%d-%d",year,month,day);

	return 0;
} 

void month_day(int year,int yearday,int *pmonth,int *pday){
	int k,leap;
	int tab[2][13]={//The column subscript is defined as 13, and the first column is 0. Align the subscript with the month. 
	{0,31,28,31,30,31,30,31,31,30,31,30,31}, 
	{0,31,29,31,30,31,30,31,31,30,31,30,31}
	};
	//Make rational use of priority relationships. Array row subscript is 0 or 1; 
	leap=(year%4==0 && year%100!=0)||year%400==0;
	
	for(k=1;yearday>tab[leap][k];k++){
		yearday-=tab[leap][k];
	}
	//Finally, replace the obtained multiple values with pointer variables, and output the replaced values by returning the address, so as to achieve the function to return multiple values. 
	*pmonth=k;
	*pday=yearday;
}

If you want to traverse an array with a pointer, you must learn the loop well and the loop conditions should be familiar, otherwise it will be troublesome to correct the program,

So I say, no matter what you learn, the foundation is very important. This is also the lesson of my blood.  

#include<stdio.h>
int main(){
	int i,n,a[10],*p;
	long sum=0;
	
	printf("Enter n(n<=10):");
	scanf("%d",&n);
	printf("Enter %d integers:",n);
	
	for(i=0;i<n;i++)
	scanf("%d",&a[i]);
	for(i=0;i<n;i++)
	sum+=*(a+i);//Or sum+=a[i]; 
	printf("sum=%ld",sum);
	
	sum=0;
	for(p=a;p<a+n;p++)/*Using the pointer p as the loop condition,
	p=a Represents the same initial address,
	p<a+n The address represented by the p pointer will not exceed the length of n units from the first address of a */ 
	sum+=*p;
	printf("sum=%ld",sum);
	
	return 0;
} 
#include<stdio.h>
#define MAXN 10
void swap(int *px,int *py);
void bubble(int a[],int n);

int main(){
	int n,a[MAXN],i;	
	
	printf("Enter n(n<=10):");
	scanf("%d",&n);
	printf("Enter %d integers:",n);
	
	for(i=0;i<n;i++)
	scanf("&d",&a[i]);
	
	bubble(a,n);//Just use the array name. 
	printf("After sorted:");
	for(i=0;i<n;i++)
	printf("%3d",a[i]);
	
	return 0;
}
void bubble(int a[],int n){
	int i,j,t;
	for(i=1;i<n;i++){
		for(j=0;j<n-i;j++){
			if(a[j]>a[j+1])
			swap(&a[j],&a[j+1]);
		}
	}
}
void swap(int *px,int *py){
	int t;
	t=*px;
	*px=*py;
	*py=t;
}

Here, I'll mainly talk about it. When passing a pointer as a parameter, you generally have to pass the length, because arrays generally have to be traversed (more about it later)  

#include<stdio.h>
#define N 20
void p_sort(int *p,int n){
	int i,j;
	for(i=0;i<n;i++){
		for(j=1;j<n-i;j++){
			if(a[j]<a[j+1]){
				temp=a[j];
				a[j]=a[j+1]; 
				a[j+1]=a[j]; 
			}
		}
	}
	
}
void p_output(int *p,int n){
	for(int i=0;i<n;i++)
	printf("%d",p++);
}
int main(){
	int a[N],n;
	scanf("%d",&n);
	for(int i=0;i<n;i++)
	scanf("%d",&a[i]);
	p_sort(a,n);
	p_output(a,n);
	
	return 0;
}

 

In that sentence, the examples I give are very helpful for you to understand these things. Don't ask me why I don't give questions and learn programming. I think it's better to learn thinking. Even if you don't know what the above examples say, it doesn't matter, but you should understand thinking. Another reason why I don't want to give you questions is that if you get through these examples, you will know what they are. The premise is to seriously figure out that learning is lonely and boring. I hope you will remember!!!

OK, now let me talk about the principle of pointer parameter transmission

The meaning of pointer parameter passing is to take the pointer as the parameter of the function. What are our arguments? Because the essence of a pointer is an address, the argument part must also be an address.

Then why can the content of the custom function change the value in the main function?

First of all, we need to find out why the formal parameters cannot change the arguments, because the system will release the variable space in the user-defined function after the user-defined function is completed, so whatever you do is useless.

But now, I passed the address. You can release the variable space storing this address, but you can't release the space in this address. Instead, variables can be accessed indirectly through this address. After the user-defined function is completed, the variable value in this address cannot be affected.

5, String handler

I originally came up with a topic. It's too lazy. Write these first. If someone needs it, I'll see when to devote an extracurricular expansion.

Why do we talk about string processing functions here rather than in functions?

Because what we mainly want to understand is its simulation implementation, so as to learn some thinking and operation.

  1.strlen function

Three methods are given
#define _CRT_SECURE_NO_WARNINGS 1
//Counter
#include<stdio.h>
#include<assert.h>
int my_strlen(const char* dest) {
	int count = 0;
	assert(dest);
	while (*dest++) {
		count++;
	}
	return count;

}
int main() {
	char arr[] = "hello";

	printf("%d",my_strlen(arr));


	return 0;
}
#define _CRT_SECURE_NO_WARNINGS 1
//recursion
#include<stdio.h>
#include<assert.h>
int my_strlen(const char* dest) {
	assert(dest);
	if (!* dest)
		return 0;
	return 1 + my_strlen( dest + 1);
}
int main() {
	char arr[] = "hello";

	printf("%d", my_strlen(arr));


	return 0;
}
#define _CRT_SECURE_NO_WARNINGS 1
//Pointer pointer
#include<stdio.h>
#include<assert.h>
int my_strlen(const char* dest) {
	assert(dest);
	const char* p = dest;
	while (*p) {
		p++;
	}
	return p - dest;

}
int main() {
	char arr[] = "hello";

	printf("%d", my_strlen(arr));


	return 0;
}

When we look at these codes, we may not understand one thing. What does assert mean? It means assertion. That is, we assure the system that it must be what we said. The expression in the parentheses behind it must be true. If it is false, the system will output the cause of the error. You can understand it on the computer. This is very simple, Another is to reference a header file of assert.h.

Let's talk about the const;

const is used to modify variables. The modified variables are called constant variables. What is a constant variable?

It has the property of a constant and cannot be modified, but it is essentially a variable.

2.strcmp function

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
int my_strcmp(const char* p1, const char* p2) {
	assert(p1 && p2);
	while (*p1++ == *p2++ && *p2) {
		return 0;
	}
	return *p1 - *p2;
}

int main() {

	char arr1[20] = "hello ";
	char arr2[] = "world";
	int ret=my_strcmp(arr1, arr2);
	if (ret == 0) {
		printf("arr1=arr2");
	}
	if (ret < 0) {
		printf("arr1<arr2");
	}
	if (ret > 0) {
		printf("arr1>arr2");
	}

	return 0;
}

3.strcpy function

#include<stdio.h>
#include<assert.h>
void my_strcpy(char *dest,const char* src){//Ensure that the src does not change 
	assert(src);//Assert 
	assert(dest); 
	while(*dest++=*src++){//Here, you need to perform + + operations on the two pointers respectively, so the two pointers cannot be NULL 
		;//When src ends (src=0), the expression is false and the loop ends. 
	}
}
int main(){
	char arr1[10]="xxxxxxxxx";
	char arr2[10]="hello";
	my_strcpy(arr1,arr2);
	printf("%s",arr1);
	return 0;
}
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
char* my_strcpy(char* dest,char * src) {
	assert(dest && src);
	char* p = dest;
	while (*dest++ = *src++);
	return p;
}
int main() {
	char arr1[20] = "hello ";
	char arr2[] = "world";
	
	printf("%s\n",my_strcpy(arr1, arr2) );

	return 0;
}

Although it is OK to say that there is no return value, in fact, there are return values,  

4.strcat function

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
char* my_strcat(char* dest, const char* res) {
	assert(dest && res);
	char* p = dest;
	while (*dest) {
		dest++;
	}
	while (*dest++=*res++) {
		;
	}

	return p;
}

int main() {
	char arr1[20] = "hello ";
	char arr2[] = "world ";

	printf("%s\n", my_strcat(arr1, arr2));

	return 0;
}

Let's talk about this. At that time, this example also confused me a little, that is, the while part.

  The meanings of the two while are different. Even if the first while is false, it will perform + + operation, but the following one will not. Does anyone know why there is a difference between the two addresses? This is the dereference mentioned above. The pointer of char type takes up one byte.

Tell me some details.

First of all, string processing functions usually start with '\ 0'.

Another, the processed string must be long enough and have enough space to avoid crossing the boundary.

Another important thing is that '\ 0' is very important. If the string does not have '\ 0', it cannot be called a string.

Otherwise, the back will suffer a loss because of this. It's all right. It's a blessing to suffer a loss. I like to see you suffer a loss.

 

strcmp is to compare the size of strings. It doesn't mean to compare the characters in a string. It doesn't mean that the longer one is the bigger one. The first one is compared first. It depends on who is bigger and who is bigger. If the first character is equal, it's bigger than the second one. Just like the first one, the bigger one is.

#include<stdio.h>
#define N 20
#include<string.h>
int main(){
	int i,n;
	char s[N][N];
	printf("Please enter n: ");
	scanf("%d",&n);
	getchar();//scanf there is a carriage return!!! 
	printf("Please enter%d String (s):\n",n);
	
	for(i=0;i<n;i++){
		gets(s[i]);
	}//The input of two-dimensional array only needs to cycle the number of rows, but the number of columns should be defined large enough 
	
	int max=0;
	for(i=1;i<n;i++){
	    
		if(strcmp(s[max],s[i])<0)
           	max=i;
	}
	
	printf("The maximum string is:%s",s[max]);
	//You can also use puts (s[max]) 
	
	return 0;
} 

Give me another question about compressed string. This is very difficult. Choose to do...

#include<stdio.h>
#define MAXN 80
void zip(char *p);

int main(){
	char line[MAXN];	
	printf("Input the string:");
	
	gets(line);
	zip(line);
	puts(line);
	
	return 0;
}
void zip(char *p){
	char *q=p; 
	int n;
	while(*p!='\0'){
		n=1;
		while(*p==*(p+n)){
			n++;
		}
		if(n>=10){
			*q++=(n/10)+'\0';
			*q++=(n%10)+'\0';
		}
		else if(n>=2){
			*q++=n+'\0';
		}
		*q++=*(p+n-1);
		p+=n;
	}
	*q='\0';
	
}

6, String and character pointers

I'll talk about it casually. Although it's important, it's not difficult.

The storage location of string constants in memory is automatically arranged by the system. String storage is actually a special one-dimensional array. Similar to arrays, all characters in string constants are continuously stored in memory. The value of string constants is the address of the storage unit where the first character of string constants is stored.

A string constant is essentially a pointer constant pointing to the first element of the string. Is it a little familiar? Hey, hey, it's the array name.

If you define a character pointer to receive the value of a string constant, the pointer points to the first character of the string, so that both the character array and the character pointer can be used to process the string.

That's all this time. There will be a deeper pointer later.

I hope you can learn something from it and wait for your correction and advice.

Posted by richinsc on Sun, 05 Dec 2021 03:56:20 -0800