<Data structure> Sequence table

content

1. Introduction to the sequence table

2. Preparations

       1. Create a sequence table

       2. Initialization sequence table

       3. Check whether expansion is required

       4. Destruction sequence table

       5. Print order table

Three, four functions

       1. Add data

                    head plug

                    tail plug

                    Specify subscript insertion

       2. Delete data

                    header deletion

                    tail deletion

                    Specify subscript delete

       3. Find data

       4. Modify data

Fourth, the total code

       1 、 SeqList.h

       2 、 SeqList.c

       3、Test.c


1. Introduction to the sequence table

  • concept and structure

The sequence table is a linear structure in which data elements are sequentially stored in a segment of storage units with consecutive physical addresses, generally using array storage. Complete data addition, deletion, search and modification on the array.

The sequence table can generally be divided into:

1. Static order table: use a fixed-length array to store elements.

2. Dynamic sequence table: use dynamically developed array storage.

  • Require:

The sequence table requires that the data to be stored starts from 0 and is continuously stored in sequence, and there can be no space in the middle.

  • interface implementation

A static sequence table is only useful if you know how much data you need to store. The fixed-length array of the static sequence table causes N to be large, and the space is too wasteful, and the less is not enough . Therefore, in reality, the dynamic sequence table is basically used , and the space size is dynamically allocated according to the needs, so we will implement the dynamic sequence table below.

  • Note:

This article will create three folders, SeqList.h, SeqList.c, and Test.c, which are used to declare, define, and implement respectively.

The text begins:

2. Preparations

1. Create a sequence table

  • SeqList.h file:
//创建顺序表
typedef int SLDataType; //确保以后想存其它类型的时候方便改动,本文以存放整型数据为例
typedef struct SeqList
{
	SLDataType* a; //动态开辟数组
	int size;    //存储顺序表中有效数据个数
	int capacity;//存储空间个数-->记录最大容量 
}SeqList; 

2. Initialization sequence table

  • SeqList.h file:
//初始化顺序表
void SeqListInit(SeqList* psl);
  • SeqList.c file:
//初始化通讯录
void SeqListInit(SeqList* psl)
{
	assert(psl);
	psl->a = NULL;
	psl->size = 0;
	psl->capacity = 0;
}

3. Check whether expansion is required

  • SeqList.h file:
//检测是否需要扩容
void SeqListCheckCapacity(SeqList* psl);
  • SeqList.c file:
//检测是否需要扩容
void SeqListCheckCapacity(SeqList* psl)
{
	assert(psl);
	//如果满了,就要扩容
	if (psl->size == psl->capacity)
	{
		size_t newCapacity = psl->capacity == 0 ? 4 : psl->capacity * 2; //防止原始capacity的容量本身为0,导致后续扩容仍为0
		SLDataType* tmp = realloc(psl->a, sizeof(SLDataType) * newCapacity);
		if (tmp == NULL)
		{
			printf("realloc fail\n");
			exit(-1);
		}
		else
		{
			psl->a = tmp;
			psl->capacity = (int)newCapacity;
		}
	}
}
  • Notice:

When the pointer of realloc is empty, realloc is equivalent to malloc

4. Destruction sequence table

  • SeqList.h file:
//销毁顺序表
void SeqListDestroy(SeqList* psl);
  • SeqList.c file:
//销毁顺序表
void SeqListDestroy(SeqList* psl)
{
	assert(psl);
	free(psl->a);
	psl->a = NULL;
	psl->capacity = psl->size = 0;
}

5. Print order table

  • Thought:

Just print the for loop sequentially

  • SeqList.h file:
//打印顺序表
void SeqListPrint(SeqList* psl);
  • SeqList.c file:
//打印顺序表
void SeqListPrint(SeqList* psl)
{
	assert(psl);
	for (int i = 0; i < psl->size; i++)
	{
		printf("%d ",psl->a[i]);
	}
	printf("\n");
}

Three, four functions

1. Add data

head plug

  • Thought:

It is a little more complicated than the tail plug. The head plug is to move the last number back, and then move the previous number back, and so on, until the first position is vacated, but the premise is to ensure that there is enough space. Not enough to expand

  • SeqList.h file:
//头插
void SeqListPushFront(SeqList* psl, SLDataType x);
  • SeqList.c file:
//头插
void SeqListPushFront(SeqList* psl, SLDataType x)
{
	assert(psl);
	SeqListCheckCapacity(psl); //检测容量
	int end = psl->size - 1;
	while (end >= 0)
	{
		psl->a[end + 1] = psl->a[end];
		end--;
	}
	psl->a[0] = x;
	psl->size++;
}
  • Test.c file:
int main()
{
	SeqList s;
	SeqListInit(&s); //一定要加上&,因为形参的改变不会影响实参,要传地址
	//先尾插4个数字
	SeqListPushBack(&s, 1);
	SeqListPushBack(&s, 2);
	SeqListPushBack(&s, 3);
	SeqListPushBack(&s, 4);
	SeqListPrint(&s); //尾插4次后打印
	//头插2个数字
	SeqListPushFront(&s, 0);
	SeqListPushFront(&s, -1);
	SeqListPrint(&s); //头插2次后打印
	return 0;
}
  • The effect is as follows:

tail plug

  • Thought:

In fact, the subscript size of the array a is the next position of the last data. Tail insertion only needs to insert a data at ps->size, but the premise is to check whether the capacity is full first.

  • SeqList.h file:
//尾插
void SeqListPushBack(SeqList* psl, SLDataType x);
  • SeqList.c file:
//尾插
void SeqListPushBack(SeqList* psl, SLDataType x)
{
	assert(psl);
	SeqListCheckCapacity(psl); //检测容量
	psl->a[psl->size] = x;
	psl->size++;
}
  • Test.c file:
int main()
{
	SeqList s;
	SeqListInit(&s); //一定要加上&,因为形参的改变不会影响实参,要传地址
	//尾插5个数字
	SeqListPushBack(&s, 1);
	SeqListPushBack(&s, 2);
	SeqListPushBack(&s, 3);
	SeqListPushBack(&s, 4);
	SeqListPushBack(&s, 5);
	SeqListPrint(&s); //打印
	return 0;
}
  • The effect is as follows:

Specify subscript insertion

  • Thought:

In fact, the idea of ​​inserting at a specified position is very similar to the tail insertion above, but it is necessary to ensure that the specified insertion position is within the range of valid data size, otherwise it will cross the boundary, and it will not be a sequence table.

  • SeqList.h file:
//在pos位置插入x
void SeqListInsert(SeqList* psl, size_t pos, SLDataType x);
  • SeqList.c file:
//在pos位置插入x
void SeqListInsert(SeqList* psl, size_t pos, SLDataType x)
{
	assert(psl);
	//暴力检查
	/*assert(pos <= psl->size && psl);*/
	//温和检查
	if (pos > psl->size)
	{
		printf("pos 越界:%d\n", (int)pos);
		return;
	}
	SeqListCheckCapacity(psl); //检测容量
	int end = psl->size - 1;
	while (end >= (int)pos)
	{
		psl->a[end + 1] = psl->a[end];
		end--;
	}
	psl->a[pos] = x;
	psl->size++;
}
  • Test.c file:
int main()
{
	SeqList s;
	SeqListInit(&s);
	//先尾插4个数字
	SeqListPushBack(&s, 1);
	SeqListPushBack(&s, 2);
	SeqListPushBack(&s, 3);
	SeqListPushBack(&s, 4);
	SeqListPrint(&s); //尾插4次后打印
	//指定下标插入2个数字
	SeqListInsert(&s, 10, 100);
	SeqListInsert(&s, 1, 20);
	SeqListPrint(&s); //插入成功后打印
	SeqListDestroy(&s);
	return 0;
}
  • The effect is as follows:

  • Notice:

When we implement the specified subscript insertion, we find that when pos=size, the implementation is tail insertion

//尾插
void SeqListPushBack(SeqList* psl, SLDataType x)
{
	assert(psl);
//法一:
	/*SeqListCheckCapacity(psl); //检测容量
	psl->a[psl->size] = x;
	psl->size++;*/
//法二:
	SeqListInsert(psl, psl->size, x);
}

Similarly, when pos=0, the header is implemented, as follows:

//头插
void SeqListPushFront(SeqList* psl, SLDataType x)
{
	assert(psl);
//法一:
	/*SeqListCheckCapacity(psl); //检测容量
	int end = psl->size - 1;
	while (end >= 0)
	{
		psl->a[end + 1] = psl->a[end];
		end--;
	}
	psl->a[0] = x;
	psl->size++;*/
//法二:
	SeqListInsert(psl, 0, x);
}

2. Delete data

header deletion

  • Thought:

Head deletion does not need to consider expansion. Head deletion needs to move the second number forward, and then move the next number forward, and so on. Note that when deleting data, ensure that the valid data size is constant >=0 to ensure that Subsequent data can be added normally.

  • SeqList.h file:
//头删
void SeqListPopFront(SeqList* psl);
  • SeqList.c file:
//头删
void SeqListPopFront(SeqList* psl)
{
	assert(psl);
	if (psl->size > 0)
	{
		int begin = 1;
		while (begin < psl->size)
		{
			psl->a[begin - 1] = psl->a[begin];
			begin++;
		}
		psl->size--;
	}
}
  • Test.c file:
int main()
{
	SeqList s;
	SeqListInit(&s);
	//尾插10个数字
	for (int i = 1; i <= 10; i++)
	{
		SeqListPushBack(&s, i);
	}
	SeqListPrint(&s); //尾插10个数字后打印
	//头删12次数据
	for (int i = 1; i <= 12; i++)
	{
		SeqListPopFront(&s);
	}
	SeqListPrint(&s); //头删12次后打印
	//头插5个数字
	for (int i = -5; i <= -1; i++)
	{
		SeqListPushFront(&s, i);
	}
	SeqListPrint(&s); //头插5次后打印
	return 0;
}
  • The effect is as follows:

tail deletion

  • Thought:

Here size is the number of valid data in the created array. You only need to set the number of valid data to -1. When printing, the original last data will naturally be deleted, but it should be noted that if the number of deletions is too many, it will be effective. The data size may become negative. In order to avoid this phenomenon, it is only necessary to ensure that it is decremented when size>0. Similarly, in order to prevent a null pointer from being passed in, only the assert assertion is required.

  • SeqList.h file:
//尾删
void SeqListPopBack(SeqList* psl);
  • SeqList.c file:
//尾删
void SeqListPopBack(SeqList* psl)
{
	assert(psl);
	if (psl->size > 0)
	{
		psl->size--;
	}
}
  • Test.c file:
int main()
{
	SeqList s;
	SeqListInit(&s); //一定要加上&,因为形参的改变不会影响实参,要传地址
	//尾插5个数字
	SeqListPushBack(&s, 1);
	SeqListPushBack(&s, 2);
	SeqListPushBack(&s, 3);
	SeqListPushBack(&s, 4);
	SeqListPushBack(&s, 5);
	SeqListPrint(&s); //尾插5次后打印

	//尾删6个数字
	SeqListPopBack(&s);
	SeqListPopBack(&s);
	SeqListPopBack(&s);
	SeqListPopBack(&s);
	SeqListPopBack(&s);
	SeqListPopBack(&s);
	SeqListPopBack(&s);
	SeqListPrint(&s); //尾删6次后打印

	//再尾插2个数字
	SeqListPushBack(&s, 6);
	SeqListPushBack(&s, 7);
	SeqListPrint(&s); //再尾插2次打印
	return 0;
}
  • The effect is as follows:

Specify subscript delete

  • Thought:

In fact, the idea is not complicated. First of all, it is necessary to assert that it is not a null pointer, and secondly, to ensure that the subscript pos<size, cannot be =size, because the value of the subscript size is empty, not valid data, if =size, delete a meaningless number , the next step is similar to the head deletion, move the last position of pos to the previous one, and then replace it with the next one, and so on.

  • SeqList.h file:
//删除pos位置的数据
void SeqListErase(SeqList* psl, size_t pos);
  • SeqList.c file:
//删除pos位置的数据
void SeqListErase(SeqList* psl, size_t pos)
{
	assert(psl);
	assert(pos < psl->size);
	size_t begin = pos + 1;
	while (begin < psl->size)
	{
		psl->a[begin - 1] = psl->a[begin];
		++begin;
	}
	psl->size--;
}
  • Test.c file:
int main()
{
	SeqList s;
	SeqListInit(&s);
	//先尾插4个数字
	SeqListPushBack(&s, 1);
	SeqListPushBack(&s, 2);
	SeqListPushBack(&s, 3);
	SeqListPushBack(&s, 4);
	SeqListPrint(&s); //尾插4次后打印
	//删除2个指定下标的数字
	SeqListErase(&s, 3);//下标3
	SeqListErase(&s, 1);//下标1
	SeqListPrint(&s); //删除后打印
	return 0;
}
  • The effect is as follows:

  •  Notice:

When pos=size-1, the last number is deleted, and tail deletion is implemented, so tail deletion can be written as follows:

//尾删
void SeqListPopBack(SeqList* psl)
{
	assert(psl);
	/*if (psl->size > 0)
	{
		psl->size--;
	}*/
	SeqListErase(psl, psl->size - 1);
}

When pos=0, the first number is deleted, and the header is deleted, so the header deletion can also be solved in this way.

//头删
void SeqListPopFront(SeqList* psl)
{
	assert(psl);
//法一:
	/*if (psl->size > 0)
	{
		int begin = 1;
		while (begin < psl->size)
		{
			psl->a[begin - 1] = psl->a[begin];
			begin++;
		}
		psl->size--;
	}*/
//法二:指定下标删除法
	SeqListErase(psl, 0);
}

3. Find data

  • Thought:

Iterate over the array.

  • SeqList.h file:
//查找指定数字
int SeqListFind(SeqList* psl, SLDataType x);
  • SeqList.c file:
//查找指定数字
int SeqListFind(SeqList* psl, SLDataType x)
{
	assert(psl);
	for (int i = 0; i < psl->size; i++)
	{
		if (psl->a[i] == x)
		{
			return i;
		}
	}
	return -1;
}
  • Test.c file:
int main()
{
	SeqList s;
	SeqListInit(&s);
	//先尾插4个数字
	SeqListPushBack(&s, 1);
	SeqListPushBack(&s, 2);
	SeqListPushBack(&s, 3);
	SeqListPushBack(&s, 4);
	SeqListPrint(&s); //尾插4次后打印
	int pos = SeqListFind(&s, 3);
	if (pos != -1)
		printf("找到了,下标是:%d", pos);
	else
		printf("找不到\n");
	return 0;
}
  • The effect is as follows:

4. Modify data

  • Thought:

You only need to modify the number of the specified subscript, provided that the modified number is valid data

  • SeqList.h file:
//修改指定下标数字
void SeqListModify(SeqList* psl, size_t pos, SLDataType x);
  • SeqList.c file:
//修改指定下标数字
void SeqListModify(SeqList* psl, size_t pos, SLDataType x)
{
	assert(psl);
	assert(pos < psl->size);
	psl->a[pos] = x;
}
  • Test.c file:
int main()
{
	SeqList s;
	SeqListInit(&s);
	//先尾插4个数字
	SeqListPushBack(&s, 1);
	SeqListPushBack(&s, 2);
	SeqListPushBack(&s, 3);
	SeqListPushBack(&s, 4);
	SeqListPrint(&s); //尾插4次后打印
	SeqListModify(&s, 1, 5);
	SeqListPrint(&s); //修改后打印
	int pos = SeqListFind(&s, 3);
	if (pos != -1)
	{
		SeqListModify(&s, pos, 5000);
		SeqListPrint(&s); //查找再修改后打印
	}
	return 0;
}
  • The effect is as follows:

Fourth, the total code

1 、 SeqList.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
//创建顺序表
typedef int SLDataType; //确保以后想存其它类型的时候方便改动,本文以存放整型数据为例
typedef struct SeqList
{
	SLDataType* a; //动态开辟数组
	int size;    //存储顺序表中有效数据个数
	int capacity;//存储空间个数-->记录最大容量 
}SeqList;

//初始化顺序表
void SeqListInit(SeqList* psl);
//检测是否需要扩容
void SeqListCheckCapacity(SeqList* psl);
//打印顺序表
void SeqListPrint(SeqList* psl);
//销毁顺序表
void SeqListDestroy(SeqList* psl);

//尾插
void SeqListPushBack(SeqList* psl, SLDataType x);
//尾删
void SeqListPopBack(SeqList* psl);
//头插
void SeqListPushFront(SeqList* psl, SLDataType x);
//头删
void SeqListPopFront(SeqList* psl);
//在pos位置插入x
void SeqListInsert(SeqList* psl, size_t pos, SLDataType x);
//删除pos位置的数据
void SeqListErase(SeqList* psl, size_t pos);

//查找指定数字
int SeqListFind(SeqList* psl, SLDataType x);
//修改指定下标数字
void SeqListModify(SeqList* psl, size_t pos, SLDataType x);

2 、 SeqList.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"SeqList.h"
//初始化通讯录
void SeqListInit(SeqList* psl)
{
	assert(psl);
	psl->a = NULL;
	psl->size = 0;
	psl->capacity = 0;
}

//检测是否需要扩容
void SeqListCheckCapacity(SeqList* psl)
{
	assert(psl);
	//如果满了,就要扩容
	if (psl->size == psl->capacity)
	{
		size_t newCapacity = psl->capacity == 0 ? 4 : psl->capacity * 2; //防止原始capacity的容量本身为0,导致后续扩容仍为0
		SLDataType* tmp = realloc(psl->a, sizeof(SLDataType) * newCapacity);
		if (tmp == NULL)
		{
			printf("realloc fail\n");
			exit(-1);
		}
		else
		{
			psl->a = tmp;
			psl->capacity = (int)newCapacity;
		}
	}
}

//打印顺序表
void SeqListPrint(SeqList* psl)
{
	assert(psl);
	for (int i = 0; i < psl->size; i++)
	{
		printf("%d ", psl->a[i]);
	}
	printf("\n");
}
//销毁顺序表
void SeqListDestroy(SeqList* psl)
{
	assert(psl);
	free(psl->a);
	psl->a = NULL;
	psl->capacity = psl->size = 0;
}

//尾插
void SeqListPushBack(SeqList* psl, SLDataType x)
{
	assert(psl);
	//法一:
		/*SeqListCheckCapacity(psl); //检测容量
		psl->a[psl->size] = x;
		psl->size++;*/
	//法二:指定下标插入
	SeqListInsert(psl, psl->size, x);
}
//尾删
void SeqListPopBack(SeqList* psl)
{
	assert(psl);
	/*if (psl->size > 0)
	{
		psl->size--;
	}*/
	SeqListErase(psl, psl->size - 1);
}

//头插
void SeqListPushFront(SeqList* psl, SLDataType x)
{
	assert(psl);
//法一:
	/*SeqListCheckCapacity(psl); //检测容量
	int end = psl->size - 1;
	while (end >= 0)
	{
		psl->a[end + 1] = psl->a[end];
		end--;
	}
	psl->a[0] = x;
	psl->size++;*/
//法二:指定下标插入法
	SeqListInsert(psl, 0, x);
}
//头删
void SeqListPopFront(SeqList* psl)
{
	assert(psl);
//法一:
	/*if (psl->size > 0)
	{
		int begin = 1;
		while (begin < psl->size)
		{
			psl->a[begin - 1] = psl->a[begin];
			begin++;
		}
		psl->size--;
	}*/
//法二:指定下标删除法
	SeqListErase(psl, 0);
}

//在pos位置插入x
void SeqListInsert(SeqList* psl, size_t pos, SLDataType x)
{
	assert(psl);
	//暴力检查
	/*assert(pos <= psl->size && psl);*/
	//温和检查
	if (pos > psl->size)
	{
		printf("pos 越界:%d\n", (int)pos);
		return;
	}
	SeqListCheckCapacity(psl); //检测容量
	int end = psl->size - 1;
	while (end >= (int)pos)
	{
		psl->a[end + 1] = psl->a[end];
		end--;
	}
	psl->a[pos] = x;
	psl->size++;
}
//删除pos位置的数据
void SeqListErase(SeqList* psl, size_t pos)
{
	assert(psl);
	assert(pos < psl->size);
	size_t begin = pos + 1;
	while (begin < psl->size)
	{
		psl->a[begin - 1] = psl->a[begin];
		++begin;
	}
	psl->size--;
}

//查找指定数字
int SeqListFind(SeqList* psl, SLDataType x)
{
	assert(psl);
	for (int i = 0; i < psl->size; i++)
	{
		if (psl->a[i] == x)
		{
			return i;
		}
	}
	return -1;
}

//修改指定下标数字
void SeqListModify(SeqList* psl, size_t pos, SLDataType x)
{
	assert(psl);
	assert(pos < psl->size);
	psl->a[pos] = x;
}

3、Test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"SeqList.h"
void test1()
{
	SeqList s;
	SeqListInit(&s); //一定要加上&,因为形参的改变不会影响实参,要传地址
	//尾插5个数字
	SeqListPushBack(&s, 1);
	SeqListPushBack(&s, 2);
	SeqListPushBack(&s, 3);
	SeqListPushBack(&s, 4);
	SeqListPushBack(&s, 5);
	SeqListPrint(&s); //尾插5次后打印

	//尾删6个数字
	SeqListPopBack(&s);
	SeqListPopBack(&s);
	SeqListPopBack(&s);
	SeqListPopBack(&s);
	SeqListPopBack(&s);
	SeqListPopBack(&s);
	SeqListPopBack(&s);
	SeqListPrint(&s); //尾删6次后打印

	//再尾插2个数字
	SeqListPushBack(&s, 6);
	SeqListPushBack(&s, 7);
	SeqListPrint(&s); //再尾插2次打印
}
void TestSeqList2()
{
	SeqList s;
	SeqListInit(&s); //一定要加上&,因为形参的改变不会影响实参,要传地址
	//先尾插4个数字
	SeqListPushBack(&s, 1);
	SeqListPushBack(&s, 2);
	SeqListPushBack(&s, 3);
	SeqListPushBack(&s, 4);
	SeqListPrint(&s); //尾插4次后打印
	//头插2个数字
	SeqListPushFront(&s, 0);
	SeqListPushFront(&s, -1);
	SeqListPrint(&s); //头插2次后打印
}
void TestSeqList3()
{
	SeqList s;
	SeqListInit(&s);
	//先尾插4个数字
	SeqListPushBack(&s, 1);
	SeqListPushBack(&s, 2);
	SeqListPushBack(&s, 3);
	SeqListPushBack(&s, 4);
	SeqListPrint(&s); //尾插4次后打印
	//头删
	SeqListPopFront(&s);
	SeqListPopFront(&s);
	SeqListPopFront(&s);
	SeqListPopFront(&s);
	SeqListPopFront(&s);
	SeqListPopFront(&s);
	SeqListPrint(&s); //头删6次后打印
	//头插2个数字
	SeqListPushFront(&s, 0);
	SeqListPushFront(&s, -1);
	SeqListPrint(&s); //头插2次后打印
}
void TestSeqList4()
{
	SeqList s;
	SeqListInit(&s);
	//尾插10个数字
	for (int i = 1; i <= 10; i++)
	{
		SeqListPushBack(&s, i);
	}
	SeqListPrint(&s); //尾插10个数字后打印
	//头删12次数据
	for (int i = 1; i <= 12; i++)
	{
		SeqListPopFront(&s);
	}
	SeqListPrint(&s); //头删12次后打印
	//头插5个数字
	for (int i = -5; i <= -1; i++)
	{
		SeqListPushFront(&s, i);
	}
	SeqListPrint(&s); //头插5次后打印
}
void TestSeqList5()
{
	SeqList s;
	SeqListInit(&s);
	//先尾插4个数字
	SeqListPushBack(&s, 1);
	SeqListPushBack(&s, 2);
	SeqListPushBack(&s, 3);
	SeqListPushBack(&s, 4);
	SeqListPrint(&s); //尾插4次后打印
	//指定下标插入2个数字
	SeqListInsert(&s, 10, 100);
	SeqListInsert(&s, 1, 20);
	SeqListInsert(&s, 5, 50);
	SeqListPrint(&s); //指定插入2次后打印
	SeqListDestroy(&s);
}
int main()
{
	SeqList s;
	SeqListInit(&s);
	//先尾插4个数字
	SeqListPushBack(&s, 1);
	SeqListPushBack(&s, 2);
	SeqListPushBack(&s, 3);
	SeqListPushBack(&s, 4);
	SeqListPrint(&s); //尾插4次后打印
	SeqListModify(&s, 1, 5);
	SeqListPrint(&s); //修改后打印
	int pos = SeqListFind(&s, 3);
	if (pos != -1)
	{
		SeqListModify(&s, pos, 5000);
		SeqListPrint(&s); //查找再修改后打印
	}
	return 0;
}

Guess you like

Origin blog.csdn.net/bit_zyx/article/details/123391165