c++指针【1】

在C++中,指针是一种特殊的变量,它存储了一个内存地址。C++指针在处理内存、数组、函数参数传递、文件I/O、动态内存分配等方面有着重要的应用。

一个指针变量通常被声明为特定类型的指针。例如,一个整数类型的指针可以指向一个整数。在声明指针变量时,应该在变量名前面加上星号(*)。

例如,下面的代码声明了一个整数类型的指针:

int* p;

 要初始化一个指针,可以使用另一个变量(或其他类型的内存地址)来赋值给它。例如:

int x = 10;  
int* p = &x;  // p现在指向x的内存地址

 在C++中,可以通过解引用操作(使用*运算符)来访问指针指向的值。例如:

std::cout << *p << endl;  // 输出10,因为p指向x的内存地址*,p就是取出这个地址的值

 获取对象地址,要想获取改地址,需要使用取地址符(操作符&);

int val = 56;
int *p = &val; //p存放变量val的地址,或者说p是指向变量val的指针
double val;
double *pd = &val; //正确:初始值是double型对象的地址
double *pd2 = pd;  //正确:初始值是指向double对象的指针

int *pi  = pd;     //错误:指针pi的类型和pd的类型不匹配
     pi  = &val;   //错误:试图把double型对象的地址赋值给int型指针

 指针值

指针的值(即地址)应属于下列4种状态之一:

1.指向一个对象。

2.指向紧邻对象所占空间的下一个位置。

3.空指针,意味着指针没有指向任何对象。

4.无效指针,也就是上述情况之外的其他值。

利用指针访问对象

如果指针指向了一个对象,则允许使用解引用符(操作符*)来访问该对象;

int val = 42;
int *p  = &val;   //p存放着变量val的地址,或者说p是指向变量val的指针
cout   <<  *p;   //由符号*得到指针p所指向的对象,输出42;

*p = 0;    //由符号*得到指针p所指向的对象,即可有p为变量val赋值
cout << *p;    //输出0 

 接引用操作,仅适用于那些确实指向了某个对象的有效指针

空指针

空指针(null pointer)不指向任何对象,在试图使用一个指针之前代码可以先检查他是否为空。以下列出几个生成空指针的方法:

int *p1 = nullptr;  //等价于int *p1 = 0;

int *p2 = 0;        //直接将p2初始化为字面常量0

//需要首先#include cstdlib

int *p3 = null;  //等价于int *p3 = 0;

得到空指针最直接的办法就是字面值nullptr来初始化指针。

赋值和指针

指针和引用都能提供对其他对象的间接访问

记住:赋值永远改变的是等号左侧的对象

void* 指针

void*是一种特殊的指针类型,可用于存放任意对象的地址。一个void*指针存放着一个地址。

double obj = 3.14,*pd = &obj; //正确:void*能存放任意类型对象的地址

void *pv = &obj; //obj可以是任意类型的对象

pv = pd;        //pv可以存放任意类型的指针

        利用 void*指针能做的事儿比较有限:拿它和别的指针比较、作为函数的输入或输出,或者赋给另外一个void*指针。不能直接操作 void*指针所指的对象,因为我们并不知道这个对象到底是什么类型,也就无法确定能在这个对象上做哪些操作。

总的概括:以void*的视角来看内存空间,没办法访问内存空间中所存的对象。

练习巩固:

 1.c++编写指针代码,分别更改指针的值以及指针所指向对象的值

#include<iostream>

int main()
{
	float  x = 3.6; //定义一个整型变量x并初始化为3.6
	float *ptr = &x ; //定义一个指向x的指针ptr

	std::cout << "原始指针的值:ptr = " << ptr << std::endl;
	std::cout << "原始指针所指向的对象的值:*ptr = " << *ptr << std::endl;

	//更改指针的值
	float  y = 2.3;
	ptr = &y;
	std::cout << "更改后指针的值:ptr = " << ptr << std::endl;
	std::cout << "更改后指针所指向对象的值: *ptr = " << *ptr << std::endl;

	//更改指针所指向对象的值
	*ptr = 3030;

	std::cout << "再次更改指针所指向的对象的值: *ptr= " << *ptr << std::endl;

 	return 0;
}

2.说明指针和引用的主要区别:

C++中的指针和引用是两个重要的概念,它们都可以用来间接访问其他对象,但它们之间存在一些关键的区别:

  1. 基本性质:指针是一个变量,存储的是另一个变量的地址;而引用是变量的别名,它和变量指向同一块内存空间。
  2. 初始化:引用在定义时必须被初始化,并且初始化后不能改变;而指针在定义时可以不被初始化,初始化后也可以改变其所指向的对象。
  3. 空值:指针可以为NULL,但引用不能。
  4. 取值方式:引用直接访问其所指向的对象,像操作普通变量一样;而指针需要通过解引用操作符*来访问其所指向的对象。
  5. 安全性:引用比指针更安全,因为引用总是指向一个存在的变量,而指针则可能指向一个不存在的内存地址。
  6. 语法形式:引用使用起来就像使用普通变量一样简单,而指针需要使用解引用操作符*来访问其所指向的对象。

总的来说,指针和引用都可以用来间接访问其他对象,但它们的使用方式和设计目标不同。指针更加灵活,可以用来操作内存中的任意地址;而引用更加安全和方便,可以像使用普通变量一样使用。

#include<iostream>

int main()
{
	int x = 10;   // 定义一个整型变量x并初始化为10  
	int* ptr = &x; // 定义一个指向x的指针ptr  
	int& ref = x;  // 定义一个引用ref,它是变量x的别名  

	// 输出指针、引用和变量的值  
	std::cout << "x = " << x << std::endl;
	std::cout << "ptr = " << ptr << ", *ptr = " << *ptr << std::endl;
	std::cout << "ref = " << ref << std::endl;

	// 修改变量的值  
	x = 20;
	ptr[0] = 30;
	ref = 40;

	// 输出指针、引用和变量的值  
	std::cout << "x = " << x << std::endl;
	std::cout << "ptr = " << ptr << ", *ptr = " << *ptr << std::endl;
	std::cout << "ref = " << ref << std::endl;

	return 0;
}

3.请简述下面这段代码的作用:

int i= 42;
int *p1 = &i;
*p1 = *p1 * *p1;

这段代码的主要作用是使用指针来修改它所指向的变量的值。

  1. int i= 42;  //定义了一个整型变量i并初始化为42。
  2. int *p1 = &i;//定义了一个整型指针p1,并将它初始化为变量i的地址。
  3. *p1 = *p1 * * p1;//这里有两个指针解引用操作(*p1),第一个解引用操作获取p1所指向的值(即变量i的值),第二个解引用操作获取p1所指向的变量的地址。然后,代码将这两个值相乘,并将结果存回p1所指向的变量中。

因此,这段代码的作用是将变量i的值从42修改为42*42(即1764)。

 4.假设p是一个int型指针,请说明下述代码的含义

if(p) // ...
if(*p) //...

这两个条件判断语句的含义是不同的。

  1. if(p) // ...这个语句是在检查指针变量 p 是否为非空(即指向一个有效的内存地址)。如果 p 非空,则会执行后面的代码块;如果 p 为空,则不会执行后面的代码块。
  2. if(*p) //...这个语句是在检查指针 p 所指向的内存地址中存储的值是否为非零。如果 *p 非零,则会执行后面的代码块;如果 *p 为零,则不会执行后面的代码块。

5.下面代码中为什么 p 合法而 lp 非法?

int i = 42;

void *p = &i;

long *lp = &i;

        在C语言中,intlong是两种不同的数据类型。int通常用于存储整数,而long通常用于存储较大的整数。在大多数平台上,intlong的长度是不同的。int通常为32位,而long通常为64位。

在这段代码中:

int i = 42;
void *p = &i;
long *lp = &i;

第一行代码定义了一个名为i的整数,并初始化为42。

第二行代码定义了一个名为pvoid指针,并将它初始化为整数i的地址。这是合法的,因为void指针是一个通用指针类型,可以存储任何数据类型的地址。

第三行代码试图定义一个名为lp的长整数指针,并将它初始化为整数i的地址。

        这是非法的,因为整数i的地址不能被直接赋给一个长整数指针。虽然它们的位数不同,但它们的对齐要求可能不同,也就是说,它们的内存模型可能不同。因此,将一个int的地址赋值给一个long指针可能会导致未定义的行为。

        在C++中,你不能将一个类型的地址直接赋给另一个类型,除非它们是兼容的类型。例如,如果你有一个指向整数的指针,你可以将它转换为指向字符的指针(因为一个字符的大小和一个整数的大小通常是一样的),但你不能将它转换为指向长整数的指针。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值