指针

1.内存

在这里插入图片描述

2.指针

其实是一个内存地址,通过地址可以找到我们这个变量
我们可以将上面的100,101等,叫做一个指针
&:取地址运算符
通过&可以获取对应的地址
#include<stdio.h>
main()
{
	int a = 10, b = 20, c = 30;
	printf("a=%d,b=%d,c=%d\n", a, b, c);
	printf("a的地址:%d,b的地址:%d,c的地址:%d\n", &a, &b, &c);//没次运行结果不同,每次运行都会重新为abc分配地址
	//%p:打印一个地址(16进制)                                  
	printf("a的地址:%p,b的地址:%p,c的地址:%p\n", &a, &b, &c);
	return 0;
}

对a,b,c的地址不能赋值,&a,&b,&c等都是常量,称为指针常量
指针变量(容器):存储的是地址

char ch='A';
char* p;//p的类型就是char*, char*是指向char型的指针,即指向一个字符
short* p1;
int* p2;//指向三个不同类型的指针

*靠近char和靠近变量没区别

char* p; char *p;//没区别

区别typedef和define
起别名:typedef

#define MYINT int
typedef int MYPLUSINT;
MYINT m;    //该定义在预处理时MYINT会替换成int
MYPLUSINT n;//typedef不会进行替换,而是当做int进行使用

在有define定义的地方全部替换成原型
typedef已经定义了一个新类型,不会在预处理时替换
二者都是全局变量

#define PMYINT int*
PMYINT P1,P2,P3;//这里只定义了一个指针变量
typedef int PMYPIUSINT;
PMYPIUSINT p1,p2,p3;//这里定义了3个指针变量

指针初始化
没有初始化的指针不能用

int *p=&a;
int *p1=&b;//初始化

定义空指针(NULL)
不能进行间接访问

int *p=NULL;
printf("p=%d\n",p);

非法指针:没有定义指针指向的指针,也不能间接访问
在执行间接访问时,一定要进行判断指针是不是为NULL。
指针间接访问
*:间接访问运算符

int a=10,b=20,c=30;
int *pa=&a,*pb=&b,*pc=&c;
printf("*pa=%d\n",*pa);//*pa等价于a
*pc=*pa+*pb;//指针可以作为变量使用
*pa=100;//相当于将100赋给a
//*&a等于a
//&*pa是a的地址

指针改变指向

pa=&c;

二级指针
指向一级指针的指针,是常量,存储的是一级指针的地址

int **ppa=&pa,**ppb=&pb,**ppc=&pc;

在这里插入图片描述
二级指针也可以改变指向、

*ppc==pc;
*pc==c;
**ppc==*(*ppc)==*pc==c;

多级指针

int ***pppa=&ppa;
int ****ppppa=&pppa;

指针所占内存大小

不管什么类型的指针,多级指针,统统都占4个字节
指针只是一个地址编号
虚拟内存:windows编程
所有应用程序在系统里面都占用4G虚拟内存,c盘当中有一个非常大的隐藏文件pagefile.sys,该文件用来实现虚拟内存,实际上为每个应用程序分配的物理内存没有4G的,在磁盘当中给每个应用程序划分了一块空间,因为应用程序在内存当中运行的部分只有一小部分,用到的数据放到内存当中,不用的放入磁盘当中(相当于CPU的,一级缓冲,二级缓冲)
4G虚拟内存有232,分为4块:栈,堆,静态区,代码段(空指针赋值区,用户区,内核区)
在这里插入图片描述

3.指针的运算及指针偏移

指针+整数=指针
地址大小实际增加=整数*指针的类型

#include<stdio.h>
main()
{
	int a = 10, b = 20, c = 30;
	int *pa = &a, *pb = &b, *pc = &c;
	printf("pa=%d,pb=&d,pc=%d\n", pa, pb, pc);
	printf("pa+10=%d\n", pa + 10);//增加10*4
	//
	double d = 45.6;
	double *pdouble = &d;
	printf("pdouble=%d\n", pdouble);
	printf("pdouble+5=%d\n", pdouble + 5);//增加5*8
	//
	char ch = 'A'; 
	char *pch = &ch;
	printf("pch=%d\n", pch);
	printf("pch+5=%d\n", pch + 5);//增加5*1
	//实际增加=整数*指针的类型
	return 0;
}

在这里插入图片描述

指针-整数=指针
地址大小实际减少=整数*指针类型
指针-指针=单位长度
表示两个地址之间相差多少个单位,两个地址之间间隔有多远
以上三种运算要在一段连续的内存空间,数组,动态开辟的内存空间
指针指向不同的地方就是指针偏移

>,<,==,!=
>,<这两个判断指针大小,也只有在一段连续的内存空间中比较才有意义
==!=这两个可以随便两个指针互相比较

4.指针与一维数组的关系

#include<stdio.h>
main()
{
	int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
	printf("arr=%d",arr);//arr表示数组的首地址,数组名
	printf("arr[0]的地址=%d\n", &arr[0]);//两者相等
	//arr=1561566不合法,地址是常量,不能改变
	//arrd的类型:指向int型的指针
	int *parr = arr;//一维数组指针
	printf("arr+1=%d\n", arr + 1);//实际+4个字节,&arr[1]的值
	printf("arr+2=%d\n", arr + 2);//实际+8个字节
	printf("arr+9=%d\n", arr + 9);//实际+36个字节
	printf("arr+10=%d\n", arr + 10);//越界,仍可以打印一个地址,但不属于数组内存,在数组外
	//指针后移
	printf("&arr[1]=%d\n", &arr[1]);
	printf("&arr[2]=%d\n", &arr[2]);
	return 0;
}

在这里插入图片描述
故:
arr+0=&arr[0];
arr+1=&arr[1];
arr+2=&arr[2];

arr+9=&arr[9];
继续推:
*(arr+0)=arr[0];–1
*(arr+1)=arr[1];–2
*(arr+2)=arr[2];–3

*(arr+9)=arr[2];–10

5.指针与二维数组的关系

#include<stdio.h>
main()
{
	int i, j;
	int arr2[4][5]=
	{
		{1,2,3,4,5},//第1个一维数组
		{6,7,8,9,10},
		{11,12,13,14,15},//第3个一维数组
		{16,17,18,19,20}
	};
	for (i = 0; i < 4; i++)
	{
		for (j = 0; j < 5; j++)
		{printf("%4d", arr2[i][j]);}
		printf("\n");
	}
	return 0;
}

arr2同一维数组一样,是二维数组的首地址
但是,arr2不是指向int型的指针,而是一个指向数组的指针
我们可以将二维数组当做一维数组开看,则该一维数组有4个元素,分别为arr2[0]={1,2,3,4,5}arr2[1]={6,7,8,9,10}arr2[2]={11,12,13,14,15}arr2[3]={16,17,18,19,20},4个元素,每个元素都是一个数组,这四个元素代表了四个数组,如arr2[0]表示1,2,3,4,5的数组名

printf("arr2+0=%d\n",arr2+0);
printf("arr2+1=%d\n",arr2+1);//偏移了5*4个字节,加1指向下一个一维数组
printf("arr2+2=%d\n",arr2+2);
printf("arr2+3=%d\n",arr2+3);

数组指针:是一个指针,指向一个数组
指针数组:是一个数组,数组里面存的都是指针

定义数组指针的两种方法

int(*parr2)[5]=arr2;//定义了一个数组指针
typedef int(*PARR2)[5];//PARR2是数组指针类型
PARR2 parr2=arr2;

二维数组的间接访问

arr2+n是一个指针,则该指针也可以进行间接访问

printf("arr2+0=%d\n",arr2+0);
printf("arr2+1=%d\n",arr2+1);//偏移了5*4个字节,加1指向下一个一维数组
printf("arr2+2=%d\n",arr2+2);
printf("arr2+3=%d\n",arr2+3);
printf("*(arr2+0)=%d\n",*(arr2+0));
printf("*(arr2+1)=%d\n",*(arr2+1));//输出整个数组
printf("*(arr2+2)=%d\n",*(arr2+2));//输出
printf("*(arr2+3)=%d\n",*(arr2+3));

以上两种输出的结果一样,但是类型不一样。
第一种是指向数组的指针,存的是数组的地址。
第二个得到的是数组,*(arr2+0)相当于是一维数组的数组名,相当于arr2[0]。
推导


*(arr2+0) => arr2[0]
*(arr2+1) => arr2[1]
*(arr2+2) => arr2[2]
*(arr2+3) => arr2[3]

arr2+0的类型:指向整个一维数组的指针
arr2[0]的类型:指向整形的指针

所以对*(arr2+0)还可以继续间接访问

*(*(arr2+0)+0)  =>  *(arr2[0]+0)//指向第一个数组的第一个元素
printf("*(*(arr2+0)+0)=%d\n", *(*(arr2 + 0) + 0));//输出1
printf("*(arr2[0]+0)=%d\n", *(arr2[0] + 0));//输出1
*(arr2+0)是个一维数组
则*(arr2+0)+2  =>  &arr2[0][2]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Typora是一款适合写一些程序相关的博客,因为可以用代码+快捷键的方式,方便的对文章内容进行处理,不用在担心排版和样式变形的问题了,在编辑的过程中,就能预览到效果,看到这篇文章,能让在短时间内适应Typroa的使用,一起了解一下吧! Typora介绍:Typora是一款适合写一些程序相关的博客,因为可以用代码+快捷键的方式,方便的对文章内容进行处理,不用在担心排版和样式变形的问题了,在编辑的过程中,就能预览到效果,看到这篇文章,能让在短时间内适应Typroa的使用,一起了解一下吧! ## 1标题设置 “#” + “空格” +“标题” {^"#"的个数表明几级标题} #一级标题 ##二级标题 ###三级标题 **6个#就是六级标题** 或ctrl+“数字键”{^数字是几即标题几级} Ctrl+1 一级标题 Ctrl+2 二级标题 Ctrl+3 三级标题 Ctrl加数字6就是六级标题 # 2序列 ## 2.1有序序列 “1.” + “空格” +“文字内容” 有序序列 按下换行键,第二行的排头自动出现 双击换行键,可退出序列 ## 2.2创建无序序列 “*“或”+“或”-” + “空格” + “文字内容” 无序序列 按下换行键,自动出现 双击换行键,可退出序列 ## 2.3创建可选序列 “*“或”+“或”-” + “空格” +[ ] + “空格” + “文字”{^注意,中括号内,有空格} # 3代码块 “~~~” + 使用语言的名字 ![2020-5-18 19-59-45](C:\Users\Tao\Desktop\CSDN\照片\2020-5-18 19-59-45.jpg) # 4引注 “>” + “空格”+“引注内容” # 5表格 Ctrl + T 就可以出现表格,可以一有的选择行数,也可以的选择字体位置 ![2](C:\Users\Tao\Desktop\CSDN\照片\2.jpg) # 6数字块 “$$” + “enter”就会出现输入区域($符号为英文模式下shift+4) ![3](C:\Users\Tao\Desktop\CSDN\照片\3.jpg) # 7水平线 “***“或”—” + “换行键” 效果如下 # 8脚注 { "^" + “ 注释内容 ” } # 9删除线 \~\~删除线的内容\~\~ 效果:~~删除内容~~ # 10字体加粗 使用 两个星号 或者 两个下划线 可以字体加粗,快捷键 Ctrl + B 11字体倾斜 使用 单个星号 或者 单下划线 可以倾斜字体。快捷键 Ctrl + I # 12图片的插入 {显示的文字](C:\Users\Hider\Desktop\echart.png "图片标题") {显示的文字](C:\Users\Hider\Desktop\echart.png) 还可以直接将图片拖拽进来,自动生成链接 # 13URL Typora允许用, 把URL作为链接插入。 Typora还会自动链接标准网址。 www.baidu.com ## Typora快捷键 | 快捷键 | 作用 | 快捷键 | 作用 | | :---------- | :----------------- | :----------- | :------------- | | Ctrl+1 | 一阶标题 | Ctrl+B | 字体加粗 | | Ctrl+2 | 二阶标题 | Ctrl+I | 字体倾斜 | | Ctrl+3 | 三阶标题 | Ctrl+U | 下划线 | | Ctrl+4 | 四阶标题 | Ctrl+Home | 返回Typora顶部 | | Ctrl+5 | 五阶标题 | Ctrl+End | 返回Typora底部 | | Ctrl+6 | 六阶标题 | Ctrl+T | 创建表格 | | Ctrl+L | 选中某句话 | Ctrl+K | 创建超链接 | | Ctrl+D | 选中某个单词 | Ctrl+F | 搜索 | | Ctrl+E | 选中相同格式的文字 | Ctrl+H | 搜索并替换 | | Alt+Shift+5 | 删除线 | Ctrl+Shift+I | 插入图片 | 注:一些实体符号在使用之后要加空格,还有一些实体符号需要在实体符号之前加”\”才能够显示。如有错误,还挺谅解。 tyopra下载链接:https://www.typora.io/ 参考链接1:[Typora入门(中文版)](https://www.simon96.online/2018/10/18/Typora入门(中文版)/) 参考链接2:[Typora](

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值