Chapter 6 善于使用指针和引用

目的:学习指针和引用,并且区分什么样的情况是取地址/取内容

🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍

6.1 什么是指针(地址)

1.指针的定义:指针是一个编程语言中的对象,利用地址,他的值直接指向存在电脑存储器中的另一个地方的值,由于通过地址能找到所需的变量单位,可以说地址指向该变量单位,所以通过它能找到以它为地址的内存单元,也可以理解为指针就是地址

补充:

a:指针的大小在32平台是4字节,在64位平台是8字节

3.访问方式的分类:直接访问+间接访问

a:直接访问:是按变量地址存取变量值的方式

b:间接访问:将变量i的地址存放在另一个变量中

🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍

6.2 变量与指针

1.指针变量和指针区分

a:指针:一个变量的地址称为该变量的指针

b:指针变量:一个是专门用来存放地址(即指针)的变量

补充—理解+注意⚠️:

a:可以理解为指针=地址,指针变量是打开该地址的钥匙

 b:指针变量只装地址,不装数据

2.指针变量的两个含义:

a:是以存储单元编号表示的地址

b:是它指向的存储单元的数据类型

🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍

6.3 定于指针变量(指针=地址+基类型)

1.定义的形式:  基类型   *     指针变量名

补充—定义:

a:int*  x =int  *  x,这两种形式相等,但是“ * ”和变量名要有空格就好

b:基类型的作用一是就是指定该指针只能存放该类型的地址,所以一个指针变量只能指向同一个类型的变量,例如:float类型的指针就不能存放int型的地址,另一个作用是使系统根据不同的类型分配不同的存储空间

c:“ * ”不是指针变量名的一部分,在变量名前加一个“ * ”表示该变量是指针变量

2.定义指针的注意事项⚠️:

a:在定义指针变量必须制定基类型

b:指针的表示,例如:整型数据的指针类型表示为“ int * ”,读作“ 指向int的指针 ”或简称“ int指针 ”

c:不能用一个整数给一个指针变量赋值,例如一个错误写法:int * x=10(❌);应该写成:

int * x=&m(☑️若m是一个已经定义好的一个变量)

d:避免野指针(就是指向的位置不可知的,很随机)的出现,所以所有的指针在定义时要初始化,若实在不知道指给谁,就指向NULL,让他为空指针

e:避免指针越界(就是超过自己的管辖范围),在使用前验证指针的有效性

f:指针指向的空间释放

2.两个与指针变量有关的运算符:“ & ”(取地址运算符)和“ * ”(指针运算符/间接访问运算符)

a:“ & ”可以理解为是取地址,“ * ”可以理解为取内容,这的理解会影响到后面对传值和传址的判断

例如:若a是一个已知变量,&a表示为变量a的地址,* a表示为指针变量a所指向的存储单位

b:两者的优先级别相同,自右而左

c: * & a=* point =a ;& *point = & a

🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍

6.3 数组与指针

1.指向数组元素的指针

a:数组元素的指针就是数组元素的地址

注意⚠️:

a:数组指针就是指针

b:指针数组,是存放地址的数组,就是数组的每个元素是指针

c:数组名都代表首元素地址,所以这里是把首元素地址赋给指针

int a[10];
int *p;
p=&a[0];

d:区分一些情况,这是用的int型的指针做例子,也可以用float型的2

int a[10];
cout<<a<<endl;//代表首元素地址
cout<<&a[0]<<endl;//同上
cout<<a+1<<endl;//首元素地址+4字节(跳过一个int)
cout<<&a[0]+1<<endl;//同上
cout<<&a<<endl;//整个数组地址
cout<<&a+1<<endl;//整个数组地址+4(跳过一个int)

🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍

6.4字符串与指针

1.3种访问字符串的方法

a:用字符数组存放一个字符串

#include<iostream>
using namespace std;
int main()
{
  char str[]=" I love China !";
  cout<<str<<endl;
  return 0;
}

结果: 

2.用字符串变量存放字符串

#include <iostream>
#include <string>
int main()
{
   string str ="I love China !";
   cout<<str<<endl;
   return 0;
}

🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍

6.5 函数与指针

1.函数的指针:一个函数编译时被分配给一个入口地址,这个函数入口地址就称为函数的指针

2.指向函数的指针变量:专门存放函数地址的指针变量

3.形式:函数类型 (* 变量名)(函数形参表);

#include<iostream>
using namespace std;
int main()
{
  int max(int x,int y);
  int (* p)(int ,int );
  int a,b,m;
  p=max;
  cin>>a>>b;
  m=p(a,b);
  cout<<"max="<<m<<endl;
  return 0;
}

🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍

6.6 void指针类型

1. 不要把“指向void类型”理解为能指向“任何类型”的数组,而应理解为“指向空类型”或“不指向确定的类型”

2.可以把非void的类型赋给void型指针变量,但不能把void指针直接赋给非void型的指针变量,必须先进行强制转化

p3=p1;
p2=p3;
p2=(char *)p3;

🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍

6.7 有关指针的数据类型和指针运算的小结

1.有关指针的数据类型小结

 

2.指针运算小结:

a:指针变量加/减一个整数:例如:p++,p--,p+i,p-i,p-=i

#include<iostream>
using namespace std;
int main()
{
  int a=1;
  int *p;
  p=&i;
  cout<<p<<endl;
  cout<*p<<endl;
  cout<<p+1<<endl;
  cout<<*p+1<<endl;

}

结果:

 

 3.指针变量赋值

int a;
int *p;
p=&a;//将变量a的地址赋给p
p=arry;//将数组arry首元素的地址赋给p
p=&arry[i];//将数组arry第i个元素的地址赋给p
p=max;//max为以定义的函数,讲max的入口地址赋给p
p1=p2;//p1和p2都是同类型的指针变量,将p2的值赋给跑

4.指针变量可以有空值,即该指针变量不会指向任何变量,例如int * p;p=NULL;

注意⚠️:p的值等于NULL和p未被赋值是两个不同的概念,前者是有值的(值为0),不指向任何变量,后者虽未被对p赋值但不等于p无值,只是他的值是一个无法预料的值,这就是野指针

5.两个指针变量可以相减

6.两个指针变量比较:若两个指针指向同一个数组元素,则可以进行比较,但指向不同数组的两个指针作比是没有意义的

7.对指针变量的赋值应注意类型问题

8.指针的优点:

a:提高程序效率

b:在调用函数时,如果改被调用函数中某些变量的值,这些值能为主调函数使用,即可以通过函数的调用,得到多个可以改变的值

c:可以实现动态存储分配

🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍

6.8 引用(取别名的那个引用,不是取地址)

1.引用:对一个数据建立一个“引用”,为一个变量起一个别名,“同一个地址两个名字”

2.符号:“&”引用声明符,并不代表地址

3.注意⚠️:

a:引用不是一种独立的数据类型,对引用只有声明,没有定义,所以必须先定义一个变量,必须先定义一个变量,然后声明对该变量建立一个引用

b:声明一个引用时,必须同时使之初始化,即声明他代表哪一个变量,但在函数中做形参时不必再声明中初始化

c:再声明一个引用后,不能再使之作为另一个变量的引用,下面是错误示范❌❌

int a1,a2;
int &b=a1;//声明b是a1的引用(别名)
int &b=a2;//试图使b又变成a2的引用(别名),不合法

d:不能建立引用数组,下面是错误示范❌❌

int a[5];
int &b[5]=a1;//不合法,不能建立引用数组
int &b=a[0];//不合法,不能作为数组元素的别名

e:不能建立引用的引用,也没有引用的指针,下面是错误示范❌❌

int a=3;
int &b=a;//声明b是a的别名,合法
int &c=b;//试图建立引用的引用,错误
int *p=b;//不能建立指向引用的指针

f:可以取引用地址

//如已声明b是a的引用,则&b就是变量a的地址&a
int *pt;
pt=&b;

g:区别取地址运算符和引用声明运算符,出现在声明中的&是引用声明符,其他情况下的&是地址运算符,再声明了引用后,后面的使用不带&

char &d=c;//此处的&引用声明符
int *p =&a;//此处的&是地址符
cout<<&b<<endl//此处不是地址

如果在程序中声明了是b是a变量的引用,实际在内存中为b开辟了一个指针型的存储单元,在其中存放变量a的地址,输出引用b时,就输出b所指向的变量a值。

共同学习,欢迎指正!

  • 59
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值