C语言日记 24 指针的概念

书P92:

指针变量的赋值:

(1):指向变量初始化

例1:

#include<iostream>
using namespace std;
void main()
{
    int a=1,*pa;
    pa = &a;
    cout << pa << endl;
    cout << *pa << endl;
}

亦等价于:

#include<iostream>
using namespace std;
void main()
{
    int a=1,*pa = &a;
    cout << pa << endl;
    cout << *pa << endl;
}

结果:

5a039a2b3cfe48a28b70b33837e235ed.png

整个程序运行过程如下:

1.利用取址运算符“&”,把a的地址赋给指针变量pa;

2:输出pa;

3.利用指针(间接寻址)运算符“*”,输出指针pa所指向的内容(的值)。

根据本例,我们可以得到如下结论:

指针变量本身表示的,就是指向的变量的地址;

所以在输出语句中直接输出指针变量(不带星号,指针变量实际上只在声明变量时要求要带星号,其他时间他只是一个变量本身)时自然输出的只是一个地址

而当我们在输出时用指针(间接寻址)运算符“*”去寻找该地址所代表的数值以后,输出的就是这个(那个指向的变量)所表达的值了

(2):指向数组初始化:

例2:

#include<iostream>
using namespace std;
void main()
{
	int a[5], * p = a;
	a[5] = { 1,2,3,4,5 };
	cout << p << endl;
	cout << *p << endl;
}

结果:

同样的(例3):

#include<iostream>
using namespace std;
void main()
{
	int a[5], * p = a, * pa = &a[2];
	a[5] = { 1,2,3,4,5 };
	cout << p << endl;
	cout << *p << endl;
}

也不行,显示的报错(问题)也同上面一样;

为什么:

其中(的)“    int a[5], * p = a;”表示的是声明a[5]这个数组元素而不是“数组a[5]”。

所以输出时自然会无法输入到数组当中去,认为“初始设定值太多”

而此时哪怕我们在输入数组的值时只输入一个值,此时会显示:

Run-Time Check Failure #2 - Stack around the variable 'a' was corrupted.(数组越界)

即给出的数组的范围为a[0]~a[4],而我们这里却给a[5]赋了值

那么问题来了:tmd这个a[5]到底表示的是数组元素a[5]还是整个a[5]数组?

我也搞不清楚了

不过,反正只要记得:对数组的赋值语句别这么(分开)写,要记得全部放在一起写:

具体安排改动如下:

将其(例2)改为:

#include<iostream>
using namespace std;
void main()
{
	int a[5] = { 6536,1231,112,1232,764123 }, * p = a;
	cout << p << endl;
	cout << *p << endl;
}

即可(运行)

运行结果

 为什么这里显示数组第一个元素的取值和地址而不显示别的:

在给指针变量赋值的时候用的是数组的变量名a也就是数组的首地址(数组首元素的内存首地址)

同样的:(例3)

#include<iostream>
using namespace std;
void main()
{
	int a[5] = { 6536,1231,112,1232,7644 }, * p = &a[2];
	cout << p << endl;
	cout << *p << endl;
}

结果:

 同样的,这里输出的是数组第三个元素本身的取值和地址的原因为:

在给指针变量赋值时赋值的对象为a[2]本身,也就是说是数组第三个元素本身

#include<iostream>
using namespace std;
void main()
{
    int a = 3, *pa = &a;
    int* pb = pa;
    cout << pa << endl;
    cout << *pa << endl;
    cout << pb << endl;
    cout << *pb << endl;
}

结果:

 例6-1指针的赋值。

源程序:

#include <iostream>
using namespace std;
void main()
{
    int* p, a;//p 是整型指针变量,a是整型变量
    double* pc, c = 123.9875;
    a = 78;
    p = &a;//类型要一致,把整型数的地址赋值给一个整型指针
    pc = &c;//把double 的地址赋值给一个double 指针
    cout << "a=" << a << " c=" << c << endl;
    cout << "a=" << a << "    a的地址是:" << p << endl;
    cout << "c=" << c << "    c的地址是:" << pc << endl;
}

#include <iostream>
using namespace std;
void main()
{
	int* p, a;//p 是整型指针变量,a是整型变量
	double* pc, c = 123.9875;
	a = 78;
	p = &a;//类型要一致,把整型数的地址赋值给一个整型指针
	pc = &c;//把double 的地址赋值给一个double 指针
	cout << "a=" << a << " c=" << c << endl;
	cout << "a=" << a << "    a的地址是:" << p << endl;
	cout << "c=" << c << "    c的地址是:" << pc << endl;
}

结果:
d4a5cdf1ca7b44d48356ad1d6e4b4ee1.png

为什么原变量和指针变量类型要一致:

指针变量的类型不是指指针变量本身的类型,而是指它所指向的变量的数据类型。

无论何种类型的指针变量,它们都是用来存放地址的

因此指针变量自身所占的内存空间大小和它所指向的变量数据类型无关,

尽管不同类型的变量所占的内存空间不同,但不同类型指针变量所占的内存空间大小都是相同的

具体类型不一致的实例:

#include <iostream>
using namespace std;
void main()
{
	int* p, c;
	double* pc, a = 123.9875;
	a = 78;
	p = &a;
	pc = &c;
	cout << "a=" << a << " c=" << c << endl;
	cout << "a=" << a << "    a的地址是:" << p << endl;
	cout << "c=" << c << "    c的地址是:" << pc << endl;
}

 结果:

45ad0aadce894fc88e607f6f1c8cf1af.png

 &:引用声明符

(引用:给一变量起一个别名)

例:(变量a,别名b)

int a;  int &b = a;

此时,a、b代表同一个变量,作用相同。

设计程序证明“此时,a、b代表同一个变量,作用相同”:

#include <iostream>
using namespace std;
int main()
{
	int a = 10;
	int& b = a;
	a = a * a;
	cout << a <<"   "<< b << endl;
	b = b / 5;
	cout << b << "   " << a << endl;
	return 0;
}

结果:

我们可以发现:

在两次输出间隔里,虽然我们只修改了b的值,但是在输出的结果中a和b却都为20

而只修改a也同理:(最终结果一样)

#include <iostream>
using namespace std;
int main()
{
	int a = 10;int& b = a;
	a = a * a;
	cout << a << "   " << b << endl;
	a = a / 5;
	cout << b << "   " << a << endl;
	return 0;
}

也就是说:

即使我们只单独修改a或b的值,输出结果中的a和b也始终一样,同步变化。

这就说明实际上a和b是同一个变量,只是叫不同名字而已。

例6-2指针的引用。

源程序:

#include <iostream>
using namespace std;
void main()
{
    int* ip;//定义了整型指针变量 ip
    int icount = 8;//定义了整型变量 icount
    ip = &icount;//指针初始化,指针使用前一定要初始化
    cout << *ip << endl;
    //通过*运算符间接引用指针 ip 指向的变量,相当于 icout
    cout << icount << endl;
}

#include <iostream>
using namespace std;
void main()
{
	int* ip;//定义了整型指针变量 ip
	int icount = 8;//定义了整型变量 icount
	ip = &icount;//指针初始化,指针使用前一定要初始化
	cout << *ip << endl;
	//通过*运算符间接引用指针 ip 指向的变量,相当于 icout
	cout << icount << endl;
}

结果:

5c4700a5d8b14d3092b8b770cc09cec9.png

其实还可以有更简便的写法:

#include <iostream>
using namespace std;
void main()
{
	int icount = 8;//定义了整型变量 icount
	int* ip = &icount;//定义了整型指针变量 ip
	cout << *ip << endl;
	//通过*运算符间接引用指针 ip 指向的变量,相当于 icout
	cout << icount << endl;
}

感觉这里的“&”引用好像表示的只是引用一个已经声明过的变量

而且从这里我们不难发现:

经改为"更简便的写法"后,完全变成了本文开头“(1):指向变量初始化”的赋初值模式

所以我觉得这里的这个示例意义不大

具体可参考:

C语言日记 27 引用_宇 -Yu的博客-CSDN博客

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值