Lab2:数据组织基础方法及创新应用(创新)

1.数组指针

(1)定义 int (*)[ ]数组指向二维 int 数组
(2)定义 int 指针指向二维数组的第一个元素
指针的写法较多,从我个人的尝试中选择几种写法分析。

代码1:

#include<bits/stdc++.h>
using namespace std;
int* p[12]; //数组的每一个元素都是指针 
int a[12][12];
void init()
{
	for(int i=1;i<=10;i++) 
		for(int j=1;j<=10;j++) a[i][j]=i+j;
}
int main()
{
	for(int i=1;i<=10;i++) p[i]=a[i]; //每个指针指向数组的a[i][0]元素 
	init();
	//int b[12];
	//int (*q)=b; *q=&b[0];
	//int (*q)[12]=a+1; //q[i][j]=xxx;
	for(int i=1;i<=10;i++) 
	{
		for(int j=1;j<=10;j++)	
			printf("%d ",p[i][j]); //直接调用指针的值 
		puts("");
	}
	return 0;
}

输出结果正常。

代码2

image
输出的最后一行居然为 0 ,这是为什么呢?
因为 \(q\) 指针初始指向了 \(a+1\) 的位置,相当于比 \(a\) 走的快了一步,导致最后一行没有成功赋值。(我原本以为 \(a\) 下标从 1 开始,那么 \(q\) 也应该从 \(a+1\) 开始,但是事实证明这么写是不对的)

正确代码:

#include<bits/stdc++.h>
using namespace std;
int a[12][12];
void init()
{
	for(int i=1;i<=10;i++) 
		for(int j=1;j<=10;j++) a[i][j]=i+j;
}
int main()
{
	init();
	int (*q)[12]=a; //q[i][j]=xxx;
	//int (*r)[12]=&a[1]; 
	//(*q[i]+j) 
		
	for(int i=1;i<=10;i++) 
	{
		for(int j=1;j<=10;j++)	
			printf("%d ",q[i][j]); //直接调用指针的值 
		puts("");
	}
	return 0;
}

代码3 (2)

#include<bits/stdc++.h>
using namespace std;
int a[6][6]; //要注意数组大小和初始化范围一致,因为单个指针遍历数组只能挨着遍历 
void init()
{
	for(int i=0;i<=5;i++) 
		for(int j=0;j<=5;j++) a[i][j]=i+j;
}
int main()
{
	init();
	int *q=&a[0][0]; 
		
	for(int i=0;i<=35;i++) 
	{
		printf("%d ",*(q+i)); //直接调用指针的值 
		puts("");
	}
	return 0;
}

要注意数组大小和初始化范围一致,因为单个指针遍历数组只能挨着遍历(肯定是因为我在这里错了才知道)
输出如下:(符合预期)
image

2.指针数组

定义并初始化 \(int*\) 数组,并用数组形式和数组指针形式两种方法输出

这个一开始真没搞懂,初始化和输出都搞错了,主要就在加不加 * 的问题上纠结。

注意几点:

  • int *r=&b 时,实际上等效于 int* r; r=&b; (这里一直理解错误了!!)
  • 输出参考普通指针的 \(*\) 写法,对应增加即可,自己想真的很容易错!

代码

#include<bits/stdc++.h>
using namespace std;
int a[6];
void init(){ for(int i=0;i<6;i++) a[i]=i;} 
int main()
{
	init();
	int *q[6];
	for(int i=0;i<6;i++) q[i]=&a[i];	
	//int* r=&b; cout<<*r; 
	//这里我们参考普通指针的写法,从而推出指针数组该怎么输出(仍然要多加*) 
	for(int i=0;i<=5;i++) printf("%d ",*q[i]);
	puts("");
	for(int i=0;i<=5;i++) printf("%d ",*(*(q+i))); 
	return 0;
}

输出如下:

image

3.字符串

image
对于任务一,指针写法和前面大同小异。无论有无串尾终止符 '\0',输出的时候都不会输出'\0',这是因为就算不手动加上这个终止符,编译器内部也会自动把它补上,而这个符号是不输出的。

代码

#include<bits/stdc++.h>
using namespace std;
char c[10]; 
int main()
{
	scanf("%s",c);
	int len=strlen(c);
	char* p=c;
	for(int i=0;i<len;i++)	cout<<*(p+i);
	puts("");
	c[len]='\0';
	for(int i=0;i<=len;i++)	cout<<*(p+i);
	return 0;
}

输出如下

image
任务二感觉比较简单

代码

#include<bits/stdc++.h>
using namespace std;
char c[30]="ATS\n012\123\x15\\"; 
int main()
{
	
	char* p=c;
	int len=strlen(c);
	for(int i=0;i<len;i++)	cout<<*(p+i);//指针形式 
	puts("");
	for(int i=0;i<len;i++)	cout<<p[i];//数组形式
	return 0;
}

输出如下

image

4.typedef与自定义类型

image

这里用新类型数组和指针结合的时候我一开始不懂:*p到底是指针数组还是数组指针?后来根据调试我最终确定应该是数组指针,即 *p指向一整个数组。可能 typedef 之后再定义指针和我想象中的有点差别吧。

代码

#include<iostream>
using namespace std;
typedef int T[5];
T a={ 9,8,7,6,5 };
int main()
{
	
	T *p=&a;
//  T (*p)=&a; 这种写法和上面的写法是等效的,这也意味着 *p 是数组指针 
	for (int i = 0;i < 5;i++)
		cout << a[i] << " ";
	cout << endl;
	for (int j = 0;j < 5;j++)
		cout <<(*p)[j]<< " ";
	return 0;
}

输出

image

5.针对下列数据结构简单输入输出

image
这里做其中的(e)(f),其余的前面做过了

(e)

#include<bits/stdc++.h>
using namespace std;
struct node 
{
	int a[5];
}x;
int main()
{
	for(int i=0;i<=4;i++) x.a[i]=i;
	for(int i=0;i<=4;i++) cout<<x.a[i]<<' ';
	return 0;
}

输出:0 1 2 3 4

(f)

构建了指针 *r->*q->*p

#include<bits/stdc++.h>
using namespace std;
int* p,*q,*r;
int main()
{
	int a=5;
	p=&a;
	q=p;
	r=q;
	cout<<*r;
	return 0;
}

输出:5

6.自由设计复杂数据结构

这里就介绍一种用于建边和存储的结构吧---链式前向星
通过结构体数组和链表式的存储方式,可以遍历一个点的所有出边。
代码如下:

	struct edge
	{
		int nxt,to,w;
	}a[N];
	inline void add_edge(int x,int y,int w)
	{
		a[++ecnt]=(edge){head[x],y,w};
		head[x]=ecnt;
	}
posted @ 2023-10-17 19:33  conprour  阅读(8)  评论(0编辑  收藏  举报