目的:学习指针和引用,并且区分什么样的情况是取地址/取内容
🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍🌍
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值。
共同学习,欢迎指正!