Function parameter passing, pointer, structure and review of cin and cout

Posted by deerly on Tue, 08 Feb 2022 07:16:25 +0100

Function parameter transfer

When an array is used as a function parameter, the length of the first dimension of the array in the parameter does not need to be filled in, such as

void a(int a[])
{
    a[1]=1;
    a[2]=2;
}

However, if it exceeds one dimension, such as a two-dimensional array, the length must be written at the beginning of the second dimension, such as

void b(int c[][5])
{
    c[0][0]=1;
}

be careful:
When the array is used as a parameter, the modification of the array element in the function is the same as the modification of the original array element
An array cannot appear as a return type

Pointer

Pay attention to the details of pointer variable definition

int *a; int* a;//No difference
int* p1,p2;//Note that only p1 is int * and p2 is int
int b;int *p3=&b;//Pointer variable initialization, but note that the address of b is assigned to p3 instead of * p3, because int * is a data type

A novel method of scanf input array

for(int i=1;i<=n;i++)
scanf("%d",a+i);//Equivalent to scanf ('% d', &a[i]);

A new method of enumerating array elements

for(int* p=a;p<=a+n-1;p++)
printf("%d ",*p);

Pointer subtraction

#include<cstdio>
#include<iostream> 
int main()
{
    int a[10]={0,1,2,3,4,5,6,7,8,9};
    int *p1=a+5;
    int *p2=a+7;
    printf("p1 = %d p2 = %d\n",p1,p2);
    std::cout<<"p2-p1 = "<<p2-p1<<std::endl;
}

It is not difficult to find that the specific values of P1 and P2 differ by 8 (one int takes up 4 bytes, 2 * 4 = 8 bytes)
p2-p1 is equal to 2 (the subtraction of two pointers represents the distance between two addresses, and the distance is in the unit of base address. a[7] and a[5] differ by 2 ints, so it is 2)

Pointer parameter passing to realize swap

#include<cstdio>
#include<iostream> 
/*The first swap method*/
void swap(int *p1,int *p2)
{
	int temp=*p1;
	*p1=*p2;
	*p2=temp;
}
int main()
{
	int a=5,b=233;
	std::cout<<"a = "<<a<<" b = "<<b;
	printf("\n"); 
	int *p1=&a,*p2=&b;
	swap(p1,p2);
	std::cout<<"a = "<<a<<" b = "<<b; 
	return 0;
}

Note that temp may also be defined as an int * variable. In this case, since the pointer variable is not initialized, an address will be stored randomly, which is prone to error. Therefore, if you want to use int *temp; You need to initialize the pointer variable temp first, that is

/*Deformation of the first swap method*/
void swap(int *p1,int *p2)
{
    int x;
    int *temp=&x;
    *temp=*p1;
    *p1=*p2;
    *p2=*temp;
}

Note that all the previous parameters are passed in a copy to the function and cannot change the original variable itself (including the exchange in swap is also the modification of the data pointed to by the incoming address copy, but not the address itself). Therefore, in order to modify the original variable without using a pointer, reference is used.

A reference simply means that it does not produce a copy, but gives an alias to the original variable. In this way, the operation on the referenced variable is the operation on the original variable

/*The second swap method*/
#include<cstdio>
#include<iostream> 
void swap(int &p1,int &p2)
{
	int temp=p1;
	p1=p2;
	p2=temp;
}
int main()
{
	int a=5,b=233;
	std::cout<<"a = "<<a<<" b = "<<b;
	printf("\n"); 
	swap(a,b);
	std::cout<<"a = "<<a<<" b = "<<b; 
	return 0;
}

Pay attention to the distinction between address character and address character

Summarizing the two methods of passing pointer parameters and reference, the third swap method can be realized

/*The third swap method*/
#include<cstdio>
#include<iostream> 
void swap(int* &p1,int* &p2)//Note that * should precede & because the data type int * is a whole 
{
	int* temp=p1;//Cannot int temp=p1, data type is different 
	p1=p2;
	p2=temp;
}
int main()
{
	int a=5,b=233;
	std::cout<<"a = "<<a<<" b = "<<b;
	printf("\n"); 
	int *p1=&a,*p2=&b;
	swap(p1,p2);
	std::cout<<"a = "<<*p1<<" b = "<<*p2;     
    /*Note that it is easy to write cout < < a < < b here. Since we exchange the addresses of a and b here, a and b do not change
    (Unlike the first method, which actually exchanges values), a and b cannot be output
    It can be understood that the first and second methods change the contents of rooms a and b
    The third method changes the address of rooms a and b. the original address p1 of a becomes the address of b*/
	return 0;
}

structural morphology

Structure can define all data types except itself (pointer variables of its own type can be defined)

struct student
{
    int age;
    int index;
    student* next;
}zcy,zfq,*zss;

There are two ways to access elements in a structure

(1)"." operation

zcy.age;
zcy.index;
zcy.next;
(*zzs).age;
(*zzs).index;
(*zzs).next;

(2)"->"

Because the pointer variable (* variable name) is not concise and beautiful, there is the following representation (the two methods are completely equivalent)

zzs->index;
zzs->age;
zzs->next;

Initialization of structure

(1) Manual initialization is troublesome

(2) Constructor initialization

Constructor is a function used to initialize the structure. Its characteristics are as follows:
1. There is no need to write the return type
2. The function name is consistent with the structure
3. A default constructor (but not visible) will be generated inside a commonly defined structure

struct student
{
    int age;
    int index;
    student* next;
    student(){}
/*It is precisely because this constructor does not require the user to provide any initialization parameters,
You can directly define the student type without initialization*/
}zcy,zfq,*zss;

An example of initializing a structure using a constructor

struct student
{
    int age;
    int index;
    student* next;
    student(){}//default
    student(int _age,int _index){age=_age;index=_index;}
    /*It can also be written as the following*/
    student(int _age,int _index):age(_age),index(_index) {}
}zcy,zfq,*zss;

Note: multiple constructors can be written to adapt to various situations, and the default parameterless constructor will be overwritten by its own definition. Generally, a default constructor should be added manually to realize the definition of structure variables without initialization

struct student
{
    int age;
    int index;
    student* next;
    student(){}//default
    student(int _age,int _index):age(_age),index(_index) {}
    student(int _age):age(_age) {}
}zcy,zfq,*zss;

cin,cout

If you want to read a whole line, you need to use the getline function (you can read spaces, tab s, and end the line feed), as follows

char str[100];
cin.getline(str,100);

If it is a string class container, you need to

string str;
getline(cin,str);

cout can control the accuracy of output and other characteristics, but it is too troublesome. It mainly uses scanf and printf, and uses less stream input and output (string uses cin input)

Topics: C C++