C++学习笔记基础篇15——地址和指针

之前每次看C++都是在这部分内容中学的迷迷糊糊,今天突然觉的好像有点懂了。

1、什么是地址?

我们在程序中定义的任何变量实际上都是存在内存中的,对吧?那么既然是存在的东西就应该有装他的地方。举个例子,小明家,肯定有小明家的地址,张三家也应该有张三家的地址。再来说一个,比如说谁家都有电视机,对吧,那么我问你电视机在哪里?你肯定会说在客厅的墙上挂着,不管在哪,电视机肯定在他的位置摆放着呢,换句话说电视机也有他自己的地址。所以变量的地址也是一个意思,就是这个变量真正存在哪,在哪里!这就是变量的地址。
下面我们用代码举个例子,例如定义一个字符: char ch = ‘a’; 我们用vs的监视窗口来看下字符 ch
的地址是多少呢?他在内存中又是如何来展现的呢?具体看视频教程演示! 那么在使用 cout << ch; 进行输出的时候,cout 也会去从
ch 的地址开始读取一个字符,之后打印输出出来。

好了,通过上面的讲解大家应该大概了解了什么是变量的地址。

2、什么是指针?

变量的地址一般都是比较难记的,例如:0x007f2eab 之类的,那么能不能用专门的一个东西,或者说一种特殊类型的变量来保存这个地址呢?
答案当然是可以的,这个特殊类型的变量就是指针。那么接下来就教大家如何定义指针: 例如: char* p;
//定义什么类型的指针,就在类型的后面加上一个*,代表是指针类型变量的意思。
这样就定义了一个指向char类型变量的指针,但是他没有指向任何变量的地址。接下来我们给他赋值一下: p = &ch;
这样我们就将指针p指向了字符ch的地址。

备注:为什么指针变量的命名一般总带着一个字母p,因为指针的英文单词是pointer,所以简写就是p

那么我们换一下: int a = 5; int* pa = &a;
这里面我们就将一个int类型的指针pa指向了int类型变量a的地址。&符号是取地址符号,&a 就是取变量a的地址。 这么这样解释一下:
变量a的值或者说a的内容是5,变量a的地址是 &a 指针pa他也是一个变量,只不过是一个指针类型的变量,所以指针变量pa的值或者说内容就是
&a,指针变量pa的地址是 &pa
也就是说指针变量也是变量,他也有内容和地址。之前给大家讲解的其他类型变量的值或者说内容都是反应自身的。但是指针变量里面的值或者内容是反应其他变量的。

3、变量与指针:

在C/C++语言中可以通过取地址符号&得到变量的地址,例如:
int a = 5;
int* pa = &a;
那么,通过变量的地址,能否得到变量自身呢?答案是可以的!
int a = 5;
int* pa = &a;
pa = 6;
即:在指针变量的前面加上一个
就能得到指针指向的变量自身。
所以对一个变量的修改,既可以通过该变量自身(直接修改),也可以通过指针/地址来实现修改(间接修改)。

4、指针变量的定义及初始化:

①、指针变量的定义格式如下:基类型 * 指针变量名; ②、符号* 既可以靠近基类型,也可以靠近指针变量名,例如: int* p; 和 int
*p; 都是正确的。 ③、指针变量可以在定义的时候就初始化,也可以先定义后初始化,也可以在以后的任意一个时间去指向某个变量的地址:
int a = 5;
int *pa;
pa = &a;
int *pb = &a;

④、基类型就是该指针变量指向的变量的类型。例如: int* pa;
这个指针变量的定义,就是定义了一个指向int类型的指针变量pa;你就不能把一个float类型的变量地址赋给他。例如:
int* pa;
float a = 2.6;
pa = &a;
这种写法是错误的。 ⑤、指针变量可以指向同一类型的变量,例如:
int a = 5, b= 6;
int *p = &a;
p = &b;
即:指针变量p既可以指向变量a的地址,也可以指向变量b的地址。

5、&和*的实例

定义一个函数实现两个参数的值

void swap(int a, int b)
 {
     int t = a;
     a = b;
     b = t;
 }

上面这个函数是没法实现功能的,我的理解为void为无返回值的,需要定义成int 型,return 对应的值,但是仍然有问题。

int swap( int a, int b)
{
	int t = a;
	a = b;
	b = t;
	return a;
}

函数的返回参数只能有一个,所以这里要实现功能的话,最方便的是使用指针来定义。

void swap(int* pa, int* pb)
{
	int t = *pa;
	*pa = *pb;
	*pb = t;
}

这里和前面的区别就是一个用的是变量一个是指针变量,在前一个程序中无法正常转换a,b值的原因是在函数中用了形参,是新申请的地址中把a,b的值放进去,但是没有把转换的结果return到原来的地址中。而后面这个使用指针变量他没有采用新的地址,是直接对原始地址中的a,b进行操作,所以不需要返回,已经修改了a,b的值。

6、小作业:

实现一个函数,作用是获取一个数组中的最大值和最小值,函数声明如下:

#include <iostream>
using namespace std;
#include <string> //C++语法
void get_min_max(int *src, int* max_v, int* min_v,int length)
{
	//函数代码写在这个下面
	int i;
	cout << "length = " << length << endl;
	for (i = 0; i <= length; i++)
	{
		if (src[i] > *max_v)
		{
			*max_v = src[i];
		}
		else if (src[i] < *min_v)
		{
			*min_v = src[i];
		}
	}
}

int main()
{
	int max_v=0;
	int min_v=100;
	int length;
	int src[] = { 1, 2, 3, 4, 5, 32, 14, 3 };
	length = sizeof(src)/sizeof(src[0]);
	cout << "length = " << length << endl;
	get_min_max(src, &max_v, &min_v,length);
	cout << "max_v = " << max_v << endl;
	cout << "min_v = " << min_v << endl;
	system("pause");
	return 0;
}

在这里插入图片描述
可以看到运行结果的min_v的计算结果不正确。
出现一个负的那么大的值,可以猜到是数组越界。检查了几遍,想到

	for (i = 0; i <= length-1; i++)

这里length-1才能对,因为数组是从0,开始的,到length-1就结束了,-858993460这个值即为0xcccccccc的十进制表示。
修正之后仍然有问题,最小值的计算结果为3。下面这个程序才是对的,要分别使用if不能直接if ,else

#include <iostream>
using namespace std;
#include <string> //C++语法
void get_min_max(int *src, int* max_v, int* min_v,int length)
{
	//函数代码写在这个下面
	int i;
	cout << "length = " << length << endl;
	for (i = 0; i <= length-1; i++)
	{
		if (src[i] > *max_v)
		{
			*max_v = src[i];
		}
		if (src[i] < *min_v)
		{
			*min_v = src[i];
		}
	}
}

int main()
{
	int max_v=0;
	int min_v=100;
	int length;
	int src[] = { 1, 2, 3, 4, 5, 32, 14, 3 };
	length = sizeof(src)/sizeof(src[0]);
	get_min_max(src, &max_v, &min_v,length);
	cout << "max_v = " << max_v << endl;
	cout << "min_v = " << min_v << endl;
	system("pause");
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值