C++学习笔记

ssssa

 1.指针

    官方介绍:指针也就是内存地址,指针变量是用来存放内存地址的变量,在同一CPU构架下,不同类型的指针变量所占用的存储单元长度是相同的,而存放数据的变量因数据的类型不同,所占用的存储空间长度也不同。有了指针以后,不仅可以对数据本身,也可以对存储数据的变量地址进行操作。指针描述了数据在内存中的位置,标示了一个占据存储空间的实体,在这一段空间起始位置的相对距离值。在 C/C++语言中,指针一般被认为是指针变量,指针变量的内容存储的是其指向的对象的首地址,指向的对象可以是变量(指针变量也是变量),数组,函数等占据存储空间的实体。

学习完指针说白了就是一个操作地址空间的东西,他的作用是可以有效地表示复杂的数据结构、动态分配内存、高效地使用数组和字符串、使得调用函数时得到多个返回值等。

1.指针怎么定义

int* p;

这样就定义了一个整数型的指针。

2.指针怎么赋值

int a =10;  //创建一个变量
int* p = NULL; //创建一个指针
p = &a;  //把a的地址赋值给p

在创建完指针p后,就要给指针赋值,指针不同于int float char这些,指针只能赋值地址,因此把一个地址赋值给指针,就要在改变量前面加取地址符& ,&a的作用就是把a的地址取出来。NULL是什么意思,他是一个空指针,就等于给指针p符一个初值。上面是第一种给指针赋值的方式,还有第二种,在定义指针的时候之间给指针赋值。

int a =10; //给a变量之间赋值
int* p = &a; //与上面类似在定义指针的时候也可以之间给指针赋值

3.怎么获得指针对应那段地址里面的真实值。

这里面有点绕。下来分为两部分说明,第一部分指针里面的值,这个值就是对应的a里面的一个地址。想要查看这个值可以运行下面代码。

#include <iostream>
using namespace std;

int main()
{
	int a = 10;
	// 1.定义指针
	int* p;  // 定义指针
	p = &a;   //& 取a的地址  建立关系
	//  也可 int *p =&a 
	cout << "a的地址 " << &a << endl;
	cout << "指针p  " <<  p << endl;
	system("pause");
}

通过上面代码我们发现p的值和a的地址的值是一样的。

第二个是指针对应那段地址里面的真实值。这个的意思是说咱们不是得到一个地址(这里就是a的地址)但是这个地址里面的值是多少,看了代码就知道这个值是10。那么我们怎么用指针获得这个值,那么就是在地址前面加*,进行解引用,即*p。也可以通过给*p赋值来改变这个地址里面的真实值。下面代码可以测试。


#include <iostream>
using namespace std;

int main()
{
	int a = 10;
	// 1.定义指针
	int* p;  // 定义指针
	p = &a;   //& 取a的地址  建立关系
	// 2.使用指针
	// 可以通过解引用的方式找到指针指向的内存
	cout <<"*p等于" <<*p<<  endl;
	cout <<"a等于" <<a<<  endl;
	*p = 1000;   // *p的意思是指向p所指向内存的数据
	cout <<"*p等于" <<*p<<  endl;
	cout <<"a等于" <<a<<  endl;
	system("pause");
}

通过这个代码我们发现通过修改*p里面的值就可以修改p对应的地址里面的值,也就是修改a的值。

运行结果如下

在最后,我们要声明一下,指针占多少字节,

32位操作系统。指针4个字节      64位操作系统  指针8个字节

#include <iostream>
using namespace std;

int main()
{
	cout << "sizeof(int *) = " << sizeof(int*) << endl;
	cout << "sizeof(char*) = " << sizeof(char*) << endl;
	cout << "sizeof(float*) = " << sizeof(float*) << endl;
	cout << "sizeof(double*) = " << sizeof(double*) << endl;
	system("pause");
}

运行结果如下

我们发现在32位操作系统里面无论哪种指针都是4个字节。

 注意事项:

             1.  NULL 空指针不能访问, 0-255之间的内存是不能使用的,因为系统用

             2. (int *) 0x0110; 意思是把0x0110强制转化为指针

             3.int* p = (int*)0x1100;   //这种定义是一种错误称为野指针,野指针是一种错误,避免出现野指针。因此在定义指针之前尽量赋值NULL,即int* p = NULL;

             4. 空指针和野指针都不是我们申请的空间,因此不要访问,访问就会出错

2.CONST与指针

 我们都知道const它限定一个变量不允许被改变。例如:

const int a=10;

那么在后面代码中a就一直等于10,不能被赋予其他值,否则报错。

那么const在指针中又有什么作用。我们下来分为三种进行介绍。

1.const 修饰指针  称为常量指针

首先常量指针怎么定义   const int* p ;  

const 防止int 前面这样就代表指针所指的地址对应的数值不能改变,指针对应的地址可以改变。

就是 *p不能改变,p可以重新赋值地址,因为const 在指针int* 前面因此称为常量指针。

    int a = 10;
	int b = 20;
	const int* p = &a;
	// 指向的值不可以修改,指针的指向可以修改
	// *p = 20;  错误
	// p = &b; // 正确

 2.const 修饰常量 称为指针常量

指针常量怎么定义   int* const p;

这个对应的指针p就是,指针的地址不可以修改,指针的地址里面对应的值可以修改。因为const在指针前面放着就是在p前面放着,我们又知道p是指针,因此这种形式就是p不可以修改,*p可以修改。 因为 int *指针 const常量,因此称这种方式为指针常量。

	int a = 10;
	int b = 20;
// 2.const 修饰常量 指针常量
	int* const p1 = &b;
	// 指向的值可以修改,指针的指向不可以修改
	// *p1 = 20; // 正确
	// p = &b;    错误

3.const 修饰指针和常量

看了上面那个我们知道谁前面加const,谁的值就不能修改,那么要是我们想指针和值都不修改那么就这样定义。const int* const p  在int前面和指针p前面都加const。这个指向的值不可以修改,指针的指向不可以修改。


#include <iostream>
using namespace std;

int main()
{
// 1.const 修饰指针  常量指针
	int a = 10;
	int b = 20;
	const int* p = &a;
	// 指向的值不可以修改,指针的指向可以修改
	 // *p = 20;  错误
	p = &b; // 正确
// 2.const 修饰常量 指针常量
	int* const p1 = &b;
	// 指向的值可以修改,指针的指向不可以修改
	 *p1 = 20; // 正确
	// p = &b;    错误	
// 3.const 修饰指针和常量
	 const int* const p2 = &a;
	// 指向的值不可以修改,指针的指向不可以修改
	system("pause");
	return 0;
}

3.指针和数组

            数组:数组是连续的空间中存放相同类型的元素

              数组名就是指针。

接下来我们通过一个例子来演示用指针遍历数组。


#include <iostream>
using namespace std;

int main()
{
	int arr[10] = { 0,1,2,3,4,5,6,7,8,9 };
	cout << "第一个元素是 " << arr[0] << endl;
	int* p = NULL;
	p = arr;   // arr就是数组的首地址
	cout << "第一个元素" << *p << endl;
	p++;  // 指针p就往后移动四个字节(int是四个字节),因为是int*
	cout << "第二个元素" << *p << endl;
	cout << "指针便利数组" << endl;
	int* p2 = arr;
	for (int i = 0; i < 10; i++)
	{
		cout << *p2 << endl;
		p2++;
	}
	system("pause");
	return 0;
}

4.指针和函数

指针和函数,前面我们学习函数的时候传递的都是一个值例如

void print_a(int a)

那我们要往函数里面传递指针应该怎么定义函数

void print_a(int* a)

下面是一个函数指针的实例


#include <iostream>
using namespace std;

int arr[10] = { 9,5,8,6,14,2,98,10,51,16 };
void bubblleSort(int* arr, int len)
{
	for (int i = 0; i < len; i++)
	{
		for (int j = 0; j < len - i-1; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				int temp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = temp;
			}
		}
	}
}
void print_Arr(int* arr, int len)
{
	int* p;
	p = arr;
	for (int i = 0; i < len; i++)
	{
		cout << *p << endl;
		p++;
	}
}
int main()
{
    bubblleSort(arr,10);
    print_Arr(arr,10);
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值