CUDA编程入门之__c/c++的指针与二级指针

CUDA编程入门之__指针与二级指针

c、c++指针的作用

指针作为c的灵魂,相信已经困扰了大家很久,希望我可以带给大家一篇用人话来解说:

在C语言中,访问变量的方式有两种:

1、通过变量名访问(例如说去什么花店,以花店的名称找到对应的花店)

2、通过地址访问(通过花店的地址,导航过去)

也就是说,我们定义一个变量int a=3;那么我们可以想象有一个长方块,里面存放的数据就是3,而长方块的地址我们假设是0x77777777;

这时候定义一个指针int *p=a;那么p=&a;因此我们又可以想象有一个长方块,里面存放的就是a的地址0x77777777,而长方块的地址我们

假设为0x66666666,这就是指针的地址。int *p表示一个int型的指针变量,*p就是p这个指针里面存放的地址(0x77777777)所对应的值。
在这里插入图片描述

为什么要用二级指针

一级指针的最简单的使用情况如下:

#include <stdio.h>
void _swap(int a, int b)
{
	int temp=a;
	a=b;
	b=temp;
}
int main(void)
{
	int a=5,b=10;
	_swap(a,b);
	printf("a=%d   b=%d",a,b);
	return 0;
}

我们想交换a,b的值,但是结果好像并不如我们所愿,因为在函数_swap中我们只是对形参进行了交换,和实际上的a,b(实参)并没有什

么联系,于是我们可以使用以下方法:

#include <stdio.h>
void _swap(int *c,int *d)
{
	int temp=*c;
	*c=*d;
	*d=temp;
}
int main()
{
	int a=5,b=10;
	_swap(&a,&b);
	printf("a=%d    b=%d\n",a,b);
	return 0;
}

在函数_swap中我们通过传入a,b的地址,相当于让int *c=a;int d=b;那么c表示的就是他(肚子里)的地址的对应的值,也就是a的值,

这样子我们就精准的定位了实参a,b的值,对其进行改变,就不会出现上面的情况。

二级指针的机制

那么我们在什么情况下会用到二级指针呢,分析一下如下代码:

#include<iostream>
 
using namespace std;
 
int a= 10;
int b = 100;
int *q;
 
void func(int *p)
{
	cout<<"func:&p="<<&p<<",p="<<p<<endl;  //note:3
	p = &b;
	cout<<"func:&p="<<&p<<",p="<<p<<endl;  //note:4
}
 
 
int main()
{
	cout<<"&a="<<&a<<",&b="<<&b<<",&q="<<&q<<endl;  //note:1
	q = &a;
	cout<<"*q="<<*q<<",q="<<q<<",&q="<<&q<<endl;  //note:2
	func(q);
	cout<<"*q="<<*q<<",q="<<q<<",&q="<<&q<<endl;  //note:5
 
	system("pause");
	return 0;
}

请大家耐心的将所有的输出按照自己的思路模拟一下,我们发现,*q并没有像我们想的那样变成100,来一起分析一下:
{
&a=0032F000,&b=0032F004,&q=0032F228

*q=10,q=0032F000,&q=0032F228

func:&p=0018FD24,p=0032F000

func:&p=0018FD24,p=0032F004

*q=10,q=0032F000,&q=0032F228
}
note:1 a,b,q都有一个地址.

note:2 q指向a.

note:3我们发现参数p的地址变了,跟q不一样了,是的参数传递是制作了一个副本,也就是p和q不是同一个指针,但是指向的地址0x0032F000(a的地址)还是不变的.

note:4 p重新指向b.

note:5 退出函数,p的修改并不会对q造成影响。

因此,如果我们想要在函数中改变指针(肚子里)的值,而不是像之前的案例一样改变指针(肚子里)的地址的(肚子里)的值,是不可行

的,就是因为我们上面提到的参数传递是制作了一个副本,所以我们要使用二级指针:

#include<iostream>
 
using namespace std;
 
int a= 10;
int b = 100;
int *q;
 
void func(int **p)  //2
{
	cout<<"func:&p="<<&p<<",p="<<p<<endl;
	*p = &b;  //3
	cout<<"func:&p="<<&p<<",p="<<p<<endl;
}
 
 
int main()
{
	cout<<"&a="<<&a<<",&b="<<&b<<",&q="<<&q<<endl;
	q = &a;
	cout<<"*q="<<*q<<",q="<<q<<",&q="<<&q<<endl;
	func(&q);  //1
	cout<<"*q="<<*q<<",q="<<q<<",&q="<<&q<<endl;
 
	system("pause");
	return 0;
}

在这里我们传入的是指针q的地址,那么p(肚子里)装的就是q的地址,而q的(肚子里)装的是a的地址,我们在函数中定义了*p=&b,那

么我们让p的(肚子里)对应的值改变为b的地址,也就是改变了q所指向的地址,即q=&b。

因为传了指针q的地址(二级指针**p)到函数,所以二级指针拷贝(拷贝的是p,一级指针中拷贝的是q所以才有问题,拷贝了指针但是指针内容也

就是指针所指向的地址是不变的)所以它还是指向一级指针q(p = q)。在这里无论拷贝多少次,它依然指向q,那么p = &b;自然的就是 q = &b;了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值