爱它,就让它去学C语言的指针
恨它,也让它去学C语言的指针
学习了指针,才算真正踏入C语言的大门
想要学习指针,必须要先了解内存这个东西。内存—很熟悉的名词,但又觉得很神秘。
知识点一【内存地址的概述】
内存含义
存储器:计算机的组成中,用来存储程序和数据,辅助CPU进行运算处理的重要部分
外存又叫外部存储器,长期存放数据,掉电不丢失数据;常见的外存设备:硬盘、flash、rom、u盘、光盘、磁带
内存又叫内部存储器,暂时存放数据,掉电数据丢失;常见的内存设备:ram、DDR
内存的作用(内存储器):
1.内存是沟通cpu与硬盘的桥梁:
2.暂存放CPU中的运算数据
3.暂存与硬盘等外部存储器交换的数据
内存的两个概念:
物理内存:实实在在存在的存储设备
虚拟内存:操作系统虚拟出来的内存
在运行程序的时候,操作系统会将 虚拟内存进行分区
堆:在动态申请内存的时候,在堆里开辟内存
栈:主要存放局部变量(在函数内部,或复合语句内部定义的变量)。
静态全局区
1):未初始化的静态全局区:
静态变量(定义的时候,前面加static修饰),或全局变量 ,没有初始化的,存在此区
2):初始化的静态全局区
全局变量、静态变量,赋过初值的,存放在此区
代码区:存放咱们的程序代码
文字常量区:存放常量的。
总结:
内存以字节为单位来存储数据的,咱们可以将程序中的虚拟寻址空间,看成一个很大的一维的字符数组
知识点二【指针的相关概念】
指针概念:
操作系统给每个存储单元分配了一个编号,从0x00 00 00 00 ~0xff ff ff ff,这个编号咱们称之为地址
实际上说指针就是地址
指针变量:
指针本质就是个变量,是个指针变量,即这个变量用来存放一个地址编号,在32位平台下,地址总线是32位的,所以地址是32位编号,所以指针变量是32位的即4个字节
注意:
无论什么类型的地址,都是存储单元的编号,在32位平台下都是4个 字节,即任何类型的指针变量都是4个字节大小
对应类型的指针变量,只能存放对应类型的变量的地址
举例:整型的指针变量,只能存放整型变量的地址
扩展:
字符变量 char ch; ch占1个字节,它有一个地址编号,且这个地址编号就是ch的地址
整型变量 int a; a占4个字节,它占有4个字节的存储单元,有4个地址编号。
知识点三【定义指针变量】(重要)
定义指针变量的步骤
*修饰指针变量名
保存什么类型变量的地址,就用该类型定义一个普通的指针变量;
从上往下,整体替换
案例:
#include<iostream>
using namespace std;
int main()
{
//第一步:明确保存什么类型变量的地址;
int num = 10; //num必须有一个合法的空间;
//需求:定义一个指针变量并保存num的地址;
//P就是指针变量,变量名为P,不是*P;
int* p; //在定义的时候:*修饰p,表示p为指针变量;
//建立指针p和num的关系,p保存的是num的地址;
printf("&num = %p\n", &num);
cout << "&num = " << &num << endl;
p = # //注意:&num 代表的是num变量的起始地址;
printf("p = %p\n", p);
cout << "p = " << p << endl;
//也用了两种输出方法,以免没学过的童鞋看不懂什么意思;
return 0;
}
运行结果:
知识点四【指针变量的使用】:通过指针p对所有保存的地址空间,进行读写操作(重要)
注意:在使用中,*P表示P所保存的地址编号对应的空间内容。指针变量P的解引用->*p等价于num
案例:
#include<iostream>
using namespace std;
int main()
{
int num = 10; //让num拥有一个合法的空间;
//需求:请定义一个指针变量,并使其保存num的地址;
int *p;
//建立p和num的关系:p保存num的地址;
printf("&num = %p\n", &num);
p = # //&num代表的是num变量的起始地址(首地址);
printf("p = %p\n", p);
printf("*p = %d\n", *p); //*p等价于num;
*p = 100; //num = 100;
printf("num = %d\n", num);
//scanf("%d", &num);
scanf_s("%d", p); //如果此处为&p的话,则表示键盘给p赋值,而不是给nunm赋值;
printf("num = %d\n", num);
system("pause");
return 0;
}
运行结果:
知识点五【指针变量的类型】(重要)
定义:
在指针变量的定义中,指针变量自身类型,简单的来说,只是把指针变量名拖黑,剩下的类型就是指针变量自身的类型;(佩服我自己,如此的通俗易懂)
p的自身类型就是int *;
指针便俩个所指的类型,简单的来说就是把指针变量名和离它最近的一个修饰符“*”一起拖黑,剩下的就是指针指向的类型;
p指向的类型为int-------->p所保存的就是int类型变量的地址
指向什么类型<==>保存什么类型变量的地址
小案例:
int num = 999;
int* p = #
//p指向num<==>p保存了num的地址;
大案例:
#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
int num = 0x01020304;
int *p;
short *p2;
char *p3;
p = #
p2 = #
p3 = #
printf("*p = %#x\n", *p);
printf("*p2 = %#x\n", *p2);
printf("*p3 = %#x\n", *p3);
return 0;
}
宽度:是指针变量指向的类型长度决定,也是指向的类型的所占的字节数
案例:指针变量的跨度(重要)
跨度:指针变量只想的类型长度决定
#include<iostream>
using namespace std;
int main()
{
int num = 0x01020304;
short* p = #
printf("%#x\n", *(p + 1));
return 0;
}
总结:
这只是一部分,下部分等我总结好之后更新
(写在后面:)
我发这个博客并不是为了帮组别人,是因为CSDN记笔记比较方便,还有代码块,还能云同步。戳中了我的心巴,有什么不会的东西,请自行去CSDN搜索相关问题,千万不要私信问我,千万千万千万不要那你的烦恼来烦我。