专栏文章

指针

算法·理论参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@mintdl3t
此快照首次捕获于
2025/12/02 08:02
3 个月前
此快照最后确认于
2025/12/02 08:02
3 个月前
查看原文
今天学习了指针的应用,希望自己能够吸收消化。
指针:
CPP
    int a=2;
	int *p=&a;//*是间接运算符
	cout<<*p<<" "<<&p<<" "<<&a<<" "<<p; 
	int *pp=NULL;//空指针,但有自己的特殊地址。
	cout<<" "<<*pp<<'\n';
	int *p2=new(int);//开启一个int 大小的空间,随机给指针p2一个4Byte大小的空间,并且明确空间里存储的是一个整数。指针需要初始化,否则电脑系统容易崩溃。
指针变量加减运算:
CPP
#include<bits/stdc++.h>
using namespace std;
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int a[100],n;//指向a[1]的地址,即a数组的第二位。
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	int *p=&a[1];
	for(int i=1;i<=n;i++){
		printf("%d ",*p);
		p++;//内存地址右移一位。
	}
	return 0;
}
//int *p=a;与int*p=&a[0]效果一样。
//&a[0]与a,都是a数组的地址。
无类型指针:
CPP
#include<bits/stdc++.h>
using namespace std;
int a=10;
double b=2.5;
void *p;
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	p=&a;
//	cout<<*p<<'\n';  强制转化为int *p的指针,并且输出指着的值。
	cout<<*(int *)p<<'\n';
	p=&b;//强制转化为double *p指针。
	cout<<*(double *)p<<'\n';
	return 0;
}
多重指针:
CPP
#include<bits/stdc++.h>
using namespace std;
int a=10;
int *p;
int * *pp;//定义双重指针,指向int类型指针的指针。
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	p=&a;
	pp=&p;//pp指针指向一个p指针。
	printf("%d=%d=%d\n",a,*p,**pp); 
	return 0;
}
指针与数组:
CPP
#include<bits/stdc++.h>
using namespace std;
int a[100];
int *pa=a; 
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
    //pa=&a[0];
	int n;
	cin>>n;
	for(int i=0;i<n;i++){
		scanf("%d",pa+i);//a+i或&a[i],pa+i
		printf("%d",*(pa+i));//pa[i]或a[i]或*(a+i);
	}
	return 0;
}
指针看成数组名:
CPP
#include<bits/stdc++.h>
using namespace std;
int n;
int *a;
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	scanf("%d",&n);
	a=new int[n+1];//向系统申请一个连续的n+1个长度的int类型的空间。
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);//或a+i-1
		printf("%d",a[i]);//或*(a+i-1);
	}
	delete []a;//使用完,删除a指针指向的空间,但是原来存的数据还在。
	return 0;
} 
行列转换问题:
CPP
#include<bits/stdc++.h>
using namespace std;
const int LP=1e5+5;
int n,m,k;
int x[LP],y[LP],d[LP];
int c[LP];//每列多少个数(记录)
int *a[LP]; //每列一个指针。
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	scanf("%d%d%d",&n,&m,&k);
	for(int l=1;l<=k;l++){
		scanf("%d %d %d",&x[l],&y[l],&d[l]);//第某行:x[i],第某列:y[i],的值:d[i]。
		c[y[l]]++;//统计每一列多少个数。
	}
	for(int i=1;i<=m;i++){
		a[i]=new int(c[i]);//给每一列指针开相应数量的空间。
	}
	for(int i=1;i<=k;i++){
		*a[y[i]]=d[i];
		a[y[i]]++;
	}
	for(int i=1;i<=m;i++){
		a[i]-=c[i];
		for(int j=1;j<=c[i];j++,a[i]++){
			printf("%d ",* a[i]);
		}
	}
	return 0;
}
//*a[i]可写成a[i][j-1]。
指针与字符串:
CPP
#include<bits/stdc++.h>
using namespace std;
int main(){
	string str="abcde";
	string *s=&str;
	cout<<*s<<'\n';
	cout<<s<<'\n';
	cout<<&s<<'\n';
//	printf("%s",str);//由于string类型是C++版本的(类类型),而printf是C语言的标准输出,C语言中没有string,只有char a[]代表字符串。所以有编译错误出现。
	printf("%s\n",str.c_str());
	
	char str1[]="abcdef";
	char *s1=str1;
	cout<<s1<<'\n';//abcdefg
	cout<<*s1<<'\n';//a
	printf("%s\n",s1);//abcdef
	printf("%c\n",s1);//unknown char
	printf("%c\n",*s1);//a the first char
	printf("%s\n",*s1);//no cout
	
	const char *str2="abcd";//等价于:char *str2;   str2="abcd";
	printf("%s\n",str2);
//	str2[0]='b';//只读,不能修改。只能重新指向新的地址。
	str2="bcdef";
	printf("%s\n",str2);
	
	char str3[]="12345";
	string s3=str3;
	printf("%s\n",str3);//12345
	printf("%s\n",s3.c_str());//12345
	cout<<str3<<" "<<s3<<'\n';//12345 12345
	return 0;
}

字符串指针做函数:
CPP
#include<bits/stdc++.h>
using namespace std;
void swapp(char &a,char &b){
	char t;
	t=a;
	a=b;
	b=t;
}
void work(char *str){
	int len=strlen(str);
	for(int i=0;i<=len/2-1;i++){
		swapp(str[i],str[len-i-1]);
	}
}
int main(){
	char s[100];
	char *str=s;
	gets(s);//读取字符串,包括空格,也可gets(str);
	work(str);
	printf("%s\n",s);
	return 0;
}
指针与函数:
引用和指针: 传入不一样,函数内不一样。只能由指针交换地址下的值。
CPP
#include<bits/stdc++.h>
using namespace std;
void swapp(int *x,int *y){
	int t=*x;
	*x=*y;
	*y=t;
}
int main(){
	int a=5,b=3;
	swapp(&a,&b);
	printf("%d %d\n",a,b);
	return 0;
}
函数返回指针:
样子:int *a(int x,int y)
CPP
#include<bits/stdc++.h>
using namespace std;
int n,a[100];
bool isprime(int x){//寻找第一个质数。
	for(int j=2;j*j<=x;j++){
		if(x%j==0) return false;
	}
	return true;
}
int *find(){
	for(int i=1;i<=n;i++){
		if(isprime(a[i])){
			return &a[i]; 
		}
	}
	return NULL;
}
int main(){
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];
	int *p=find();
	if(p!=NULL){
		printf("%d\n",*p);
	}
	else {
		printf("can't find it!\n");
	}
	int*(*pp)()=&find;
	cout << reinterpret_cast<void*>(pp) << '\n';//查看函数地址。
	return 0;
}
函数指针:
CPP
#include<bits/stdc++.h>
using namespace std;
int t(int a){
	return a;
}
int main(){
	cout<<t<<'\n';//显示函数t的地址。
	int(*p)(int a);//定义函数指针变量。
	p=t;//将函数地址赋给指针p(函数指针)
	cout<<p(5)<<','<<(*p)(10)<<','<<t(15)<<'\n';
	return 0;
}

int *p(int a);//整数指针的p函数
int (*p)(int a);//整数函数的p指针
使用typedef定义函数指针:
CPP
#include<bits/stdc++.h>
using namespace std;
int sum(int a,int b){
	return a+b;
}
typedef int(*p)(int,int);//定义一个含两个参数的整形函数指针类型
int main(){
	p pp=sum;
	cout<<pp(2,5);
	return 0;
}
// int (*p)(int a,int b)  生成一个指针p,p指针是一个有含有2个参数的int函数指针,是一个变量
使用指针模拟菜单:
CPP
#include<bits/stdc++.h>
using namespace std;
void t1(){cout<<"test1";}
void t2(){cout<<"test2";}
void t3(){cout<<"test3";}
void t4(){cout<<"test4";}
void t5(){cout<<"test5";}
typedef void(*p)();
int main(){
	p a[]={NULL,t1,t2,t3,t4,t5};//a里存的是地址。
	int x;
	cin>>x;
	a[x]();
	return 0;
}
链表结构:
CPP
#include<bits/stdc++.h>
using namespace std;
struct Node{
	int data;
	Node *next;
};
Node *head,*p,*r;
int x; 
int main(){
	cin>>x;
	head=new Node;//申请头结点
	r=head;
	while(x!=-1){
		p=new Node;
		p->data=x;
		p->next=NULL;
		r->next=p;
		r=p;
		cin>>x;
	}
	p=head->next;
	while(p!=NULL){
		cout<<p->data<<" ";
		p=p->next;
	}
	return 0;
} 
结构体指针:
CPP
#include<bits/stdc++.h>
using namespace std;
struct Node{
	int a;
	string name;
}*p;
int main(){
	p->name="Wu";
	(*p).name="Wu";
	return 0;
}
双向链表:
CPP
#include<bits/stdc++.h>
using namespace std;
struct node{
	int data;
	node *pre,*next;
};
node *head1,*p1,*q1,*r1;
void insert(node *head,int i,int x){
	node *s,*p;
	int j=0;
	s=new node;
	p=head;
	while((p!=NULL)&&(j<i)){
		p=p->next;
		j++;
	}
	if(p==NULL){
		cout<<"can't insert"<<'\n';
	}
	else {
		s->data=x;
		s->pre=p->pre;
		p->pre->next=s;
		s->next=p;
		p->pre=s;
	}
}
void delete1(node *head,int i){
	int j=0;
	node *p;
	p=head;
	while((p!=NULL)&&(j<i)){
		p=p->next;
		j++;
	}
	if(p==NULL){
		cout<<"can't "<<'\n';
	} 
	else {
		p->pre->next=p->next;
		p->next->pre=p->pre;
		free(p); //释放p指针当前指向的内存
	}
}
int main(){
	
}
循环链表,约瑟夫环:
CPP
#include<bits/stdc++.h>
using namespace std;
struct node{
	long long data;
	node *next;
};
long long n,m;
node *head,*p,*r;
int main(){
	long long k,l;
	cin>>n>>m;
	head=new node;
	head->data=1;
	head->next=NULL;
	r=head;
	for(int i=2;i<=n;i++){
		p=new node;
		p->data=i;
		p->next=NULL;
		r->next=p;
		r=p;
	}
	r->next=head;
	r=head;
	
/*	for(int i=1;i<=n;i++){
		cout<<r->data<<" ";
		r=r->next;
	}
	cout<<'\n';*/

//为什么双重循环的j循环从1到m-2:因为r在j循环里被赋值的就是当前数的下一个数,j循环外又输出的是r的下一个,所以数的人数要减去2
	for(int i=1;i<=n;i++){//i列举从第i个人开始数
		for(int j=1;j<=m-2;j++){//j表示从第i个人开始数m个人
			r=r->next;
		}
		cout<<r->next->data<<" ";
		r->next=r->next->next;
		r=r->next;
	}
	return 0;
}
完结撒花

评论

0 条评论,欢迎与作者交流。

正在加载评论...