不知道对于初学者而言指针是什么样的存在,不过对于我而言,指针就是雾,看不懂,理不清。最开始学的时候感觉自己理清了,可是时间一长,又忘了。以至于到了现在码代码的时候老是出问题,所以又回过头重新复习了一遍指针。下边是我整理的一些指针相关的知识,已便自己日后查漏补缺时用。
一 指针是什么?
在计算机科学中,指针是编程语言中的一个对象,利用地址,它的值直接指向存在电脑存储器中另一个地方的值,可以说,地址指向该变量单元。也就是说通过它能找到变量单元。感觉有点混乱,那就记住一句:指针就是地址。
二 指针、指针变量与变量指针的区别是什么?
指针:就是地址。
指针变量:是一个变量,用来存放地址的变量。
变量指针:指的是变量的地址。
三 指针变量的类型表示(type + *)
(一)指针变量出现类型的原因:
(1) 出现类型后,可以使得编码更加严谨。
(2) 出现指针变量的类型,就确定了指针运算的规律。
(二)解释一些简单的指令:
(1)int *p = &a; 定义了一个指针变量p,将a的地址存放在p变量中。
(2)int a = 10; 定义了一个整型变量,将数字10存放在a变量中。
int *pa = &a; 定义了一个指针变量pa,将a的地址存放在pa变量中。
int **ppa = &pa; 定义了一个指针变量ppa,将指针变量pa的地址存放在ppa中。
*ppa = 1; *ppa就等价于pa,将1赋值给pa,就相当于pa指向1号地址。
**ppa = 1; **ppa就等价于a, 将1赋值给a,就相当于将变量a的内容改为1。
*ppa = &b; *ppa就等价于pa,将ppa指向变量b。
四 指针的运算
(一) 指针加一,相当于加上指针类型的大小,指针加n,就相当于加上指针类型的大小的n倍。具体看下述代码:
#include<stdio.h>
#include<windows.h>
int main()
{
int n = 10;
char * pc =(char *)&n;
int * pi = (int *)&n;
printf("%p\n", pc);
printf("%p\n", pi);
printf("%p\n", pc+1);
printf("%p\n", pi+1);
system("pause");
return 0;
}
该段代码运行的结果如下图:
(二) 同一个数组中的两个指针相减,通常代表两指针之间经历的指针类型字节的个数。具体情况见如下代码所示:
#include<stdio.h>
#include<windows.h>
int main()
{
int a[10] = {0,1,2,3,4,5,6,7,8,9};
int * p = &a[5];
int * q = &a[8];
char * p1 = (char *)&a[5];
char * q1 = (char *)&a[8];
printf("%d\n", p-q);
printf("%d\n", q-p);
printf("%d\n", p1-q1);
printf("%d\n", q1-p1);
system("pause");
return 0;
}
该段代码的运行结果如下所示:
(三) 指针的类型决定了对指针解引用的时候有多大权限。比如,char* 的指针解引用只能访问一个字节,int * 的指针解引用就可以访问四个字节。
案例:代码如下:
#include<stdio.h>
#include<windows.h>
int main()
{
int n = 0x11223344;
char *pc = (char *)&n;
int *pi = &n;
*pc = 0x55;
*pi = 0;
printf("%p\n", pc);
printf("%p\n", pi);
system("pause");
return 0;
}
调试过程:
开始调试后,打开调试中的窗口,打开内存,逐步调试可得如下情况。
刚开始没有查看&n得到:
按F11进行逐行调试,初始化完n,赋值之后的内存变化为:(具体如下图所示:)
由上述调试过程可得:char* 的指针解引用只能访问一个字节,int * 的指针解引用就可以访问四个字节。即:指针的类型发决定了指针解引用时候的权限有多大。
五 二级指针
(一)二级指针的定义:
指针变量是一个存放指针的变量,那么指针变量的地址就是二级指针。下图可以帮助大家理解二级指针:
(二)二级指针的运算
解引用:二级指针解引用就是找到对应的一级指针。例如上例中:*ppa 找到的就是pa,*ppa其实访问的就是pa。
我们用下边的例子来说明一下二级指针与一级指针的相关运算。
在这儿我们就引入了一个新的知识点:左值与右值。顾名思义,左值就是放在等号左边的值,右值就是放在等号右边的值。那么左值与右值有什么要求呢?有哪些是可以做左值?哪些可以做右值?哪些既可以做左值又可以做右值呢?
(三)左值与右值
通过上边的例子,大家也能发现:左值表示的是该变量的地址。右值表示该变量的内容。那么自然就有:地址常量不能做左值,可以做右值;变量既可以做左值,也可以做右值;常量可以做右值,但不能做左值。
下面通过一些例子来说明:
&ch; 表示一个地址,不能做左值,但可以做右值。(char *p = &ch可以, 但是&ch = 1不可以。)
cp; 表示变量,既可以做左值,也可以做右值,(int cp = 1;int m = cp;这两句都可以。)
++cp; 表示一个变量,不可以做左值,可以做右值。
cp++; 表示一个变量,不可以做左值,可以做右值。
*(cp+1); 表示cp的下一个空间,既可以做左值,也可以做右值。(做左值表示将一个值存在该空间中,做右值表示将该空间中的值复制给其他变量)
*cp+1; 该表达式的结果是常量,可以做右值,但不能做左值。
本篇是一些关于指针的简单理解,指针的其他内容请见后期博客。如有错误之处,请大佬批评指正。