点击目录传送ฅʕ•̫͡•ʔฅ
指针
可以认为:指针就是地址,是它所指向的变量的地址
根据课本的理解
1.引入一个重要的运算符——指针运算符“ * ”,也称间接运算符。
2.指针运算符“ * ”用来定义指针变量,指针变量(简称指针)是一种特殊的变量,它存储的内容只能是内存地址,比如存储另一个变量的地址。
语法格式:指针所指向的类型 * 指针变量的名称;
用一个例子说明指针变量的含义和用法。
int num = 1;
int * p;
p = #
定义指针变量 p,指针变量 p 存储的是变量 num 的地址(即 &num)。
形象的把指针变量 p 存储变量 num 的地址,称为指针变量 p 指向变量 num。
指针变量也是一种变量,而变量是一块空间的名称,特殊在于以指针变量为名的这块空间里只能存放地址。
指针变量,简称指针。(指针的本质是一种特殊的变量)
————————————
指针变量和变量的区别只是所表示的空间要存的东西不一样
变量所表示的空间想存什么存什么
指针变量所表示的空间只能存内存地址
——————————————————
所谓指向,就是存有一个变量的地址,就是指向这个变量。
——————————————————————————
指针和地址的区别在于,指针是一个变量,是一块地址空间的名称,而地址是一块空间的地址(额…)是一个整数。
从某种意义上来说,指针和地址都像是一个房间的房间号,就比如一个房间叫腾云阁,门号是1024,这里的腾云阁就是指针,1024就是内存地址。
只不过这个腾云阁里存的是一个内存地址(也只能存内存地址),这个1024就是这个指针的地址。
没毛病ヽ(✿゚▽゚)ノ
所以说指针就是地址,地址就是指针这种说法也有一定道理
翻译过来就是指针变量就是地址
那也就可以说变量就是地址。。。感觉好像有哪里不对?
不能说变量就是地址的原因就是指针变量里存的才是地址。
“指针就是地址” 这句话中的这个地址是指针变量所存的地址,而不是指针变量本身的地址。
用一句话来说指针就是它所指向的变量的地址
内存地址是一种用于软件及硬件等不同层级中的数据概念,用来访问电脑主存中的数据。–百度
指针变量 p | 变量 num | |
---|---|---|
&num | → | 1 |
注意:
①可以在定义指针变量的同时进行初始化。
例如: int * p = #
②不能使用常量给指针变量赋值。
假设变量 num 的地址是 1234002,即使这样,也不能写成 p = 1234002。
③指针变量无论指向什么样的数据类型,都占用相同大小的空间,在 32 位机器上占 4 个字节( 32 位)。
④指针变量的类型必须和它所指向的数据类型一样。
⑤指针变量指的是“ p ”,而不是“ *p ”。
定义指针变量时的“ int * ”表示它是一个指向整型变量的指针。
⑥在明确指针变量 p 指向变量 num 后,表达式“ * p ”就是指针变量 p 所指向的那个变量,即 num。
比如:*p = 2; //等价于num = 2;
因为指针运算符“ * ”的优先级高居第2位,远高于排在倒数第2的赋值运算符,所以表达式“ *p ”先组成一个整体,表示指针 p 所指向的变量,即 num,自然对表达式“ *p ”赋值就是对变量 num 赋值。
⑦分析表达式“ *p += 1 ”、“ *p++ ”和“ (*p)++ ”的不同,假设指针变量 p 指向变量 num,且 num = 1。
“ * ” 的优先级高于赋值运算符“ += ”,即原式可化为 num += 1;
“ * p++;”指针运算符 “ * ”和自加运算符“ ++ ”优先级相同,运算顺序是从右至左的,所以先计算“ p++ ”,又因为使用的是自加的后置运算,所以表达式“ p++ ”的值仍是指针变量 p 的值,即变量 num 的地址,所以整个表达式的值等于1。
在获取到整个表达式的值之后,指针变量 p 自身的值加 1,指针变量 p 存储的不再是变量 num 的地址,也就是 p 的指向发生了变化。
至于如何变化,第九章讲,这是第五章的内容。
小括号的优先级是最高的,第三个式子等价于 num++;结果是2。
因为 return 语句只能返回唯一的一个值,且实参和形参各自占据独立的存储空间,所以如果希望在调用 swap() 函数后交换实参 x 和 y ,
只能在 swap() 函数体中借助形参 a 和 b,直接交换实参 x 和 y 的值。
这就用到了传递地址给函数。
代码如下:
#include<iostream>
using namespace std;
void swap(int *,int *);
int main()
{
int x=1,y=3;
cout << "&x:" << &x << endl;
cout << "&y:" << &y << endl;
swap(&x,&y);
cout << x << " " << y << endl;
return 0;
}
void swap(int * pa,int *pb)
{
int t;
cout << "*pa,pa:" << * pa << " " << pa << endl;
cout << "*pb,pb:" << * pb << " " << pb << endl;
t = * pa;
* pa = * pb;
* pb = t;
return ;
}
这里的地址就是用十六进制表示的(ˉ▽ˉ;)…
关于 指针和一维数组的关系
数组在内存中占据一块连续的存储区域
以 int 类型的 code 数组为例
code[1] 的地址等于在 code[0] 地址的基础上增加 4 个字节
可以通过表达式“ &code[0] ”来获取 code[0] 的地址
因为中括号“ [ ] ”的优先级高于取地址运算符“ & ”,所以“ code[0] ”将作为一个整体
编译器在定义 code 数组分配存储空间时,就已经在内存中自动创建了一个存储空间,用来存储数组的起始地址,
通过使用一维数组的数组名 code 来访问该地址。
即 code 就是指针。即int * p,p = code。
同样都是一个存地址的空间的名字(。・∀・)ノ
所以也可以这样用 p[3],等价于 code[3]。
函数void get(int *elem)
小测试
Little Test
7.函数调用的语法格式:函数名称(参数列表);
函数调用时,传递给函数的参数,称为实参。
函数定义中参数列表的参数,称为形参。
实参可以改变形参,但形参不会影响实参。
——https://blog.csdn.net/qq_43763494/article/details/101620281#14__56----【记录】C语言知识点总结
#include<iostream>
using namespace std;
void get(int *elem) { //这样的函数要的都是地址,即,形参是一个地址
*elem = 3;
}
int main()
{
int elem = 0; //这个 elem 必须有,否则程序运行无结果
int *e;
e = &elem;
cout << *e << endl;
cout << e << endl;
get(e); //传递的这个 e (实参)是一个地址
cout << *e << endl;
return 0;
}
运行结果:
事实证明:实参为地址的时候,
就是传参传的是个地址的时候
只能用指针类型接收:
#include<iostream>
using namespace std;
void get3(int &L) {
cout << "get3L: " << &L << endl;
/*int *L;
L = &L;
*L = 3;*/ //失败
}
void get2(int L) {
cout << "get2L: " << L << endl;
/*int *L;
L = L;
*L = 2;*/ //失败
}
void get(int *L) { //这样的函数要的都是地址,即,形参是一个地址
*L = 1;
}
int main()
{
int elem = 0; //这个 elem 必须有,否则程序运行无结果
int *e;
e = &elem;
cout << *e << endl;
cout << e << endl;
get(e); //传递的这个 e (实参)是一个地址
cout << elem << endl;
get2(elem); //不能传 e
cout << elem << endl;
get3(elem); //不能传 e
cout << elem << endl;
return 0;
}