简介
-
指针是C语言的一个重要知识点,其使用灵活、功能强大,是C语言的灵魂
-
指针与底层硬件(内存)联系紧密,使用指针可操作数据的地址,实现数据的间接访问
计算机存储机制
-
存储有大端和小端的区别,此处以小端存储为例
-
总结一句话为:低位在前为小端,高位在前为大端
-
目前计算机主要以小端为主
int a = 0x12345678;
short b = 0x5A6B;
char c[] = {0x33,0x34,0x35};
定义指针
-
指针即指针变量,用于存放其他数据单元(变量/数组/结构体/函数等)的首地址。若指针存放了某个数据单元的首地址,则这个指针指向了这个数据单元,若指针存放的值是零,则这个指针为空指针
-
定义一个指针变量:
数据类型 |
指向该数据类型的指针 |
||
(unsigned)char |
1字节 |
(unsigned)char * |
x字节 |
(unsigned)short |
2字节 |
(unsigned)short * |
x字节 |
(unsigned)int |
4字节 |
(unsigned)int * |
x字节 |
(unsigned)long |
4字节 |
(unsigned)long * |
x字节 |
float |
4字节 |
float * |
x字节 |
double |
8字节 |
double * |
x字节 |
-
16位系统:x = 2,32位系统:x = 4,64位系统:x = 8
指针的操作
-
若已定义:
int a; //定义一个int型的数据
int *p; //定义一个指向int型数据的指针
("&"的运用)
运用 |
解释 |
(变量A)&(变量B) |
变量B按位与上变量A |
&(变量A) |
取出变量A的首地址 |
("*"的运用)
运用 |
解释 |
(变量A)*(变量B) |
变量A乘以变量B |
(变量类型) *(变量A) |
定义指针A为一个变量类型 |
*(变量A) |
取出A(此时的A为一个变量的首地址)存储的内容 |
-
则对指针p有如下操作方式:
操作方式 |
举例 |
解释 |
取地址 |
p = &a; |
将数据a的首地址赋值给p |
取内容 |
*p; |
取出指针指向的数据单元 |
加 (一般用于数组/结构体) |
p++; |
使指针向下移动1个数据宽度 |
p=p+5; |
使指针向下移动5个数据宽度 |
|
减 (一般用于数组/结构体) |
p–; |
使指针向上移动1个数据宽度 |
p=p-5; |
使指针向上移动5个数据宽度 |
例:
#include <stdio.h>
int main(void)
{
int a = 0x66;
int *p;
p=&a;
printf("x%\\n",a);
printf("x%\\n",p);
printf("x%\\n",*p);
p++;
printf("x%\\n",p);
return 0;
}
则运行结果为:
66
62fe44(此处为计算机分配的内存地址)
66
62fe48(与上个首地址相差4位的原因为int型变量占四个字节)
数组与指针
-
数组是一些相同数据类型的变量组成的集合,其数组名即为指向该数据类型的指针。数组的定义等效与申请内存、定义指针和初始化
例:char c[] = {0x33,0x34,0x35};
等效于:申请内存 定义char *c = 0x4000;
初始化数组数据
-
利用下标引用数组数据也等效于指针取内容
例:c[0] = *c;
c[1] = *(c+1)
c[2] = *(c+2)
-
数组其实就是指针(数组取下标其实就是指针取内容的另一种形态),换句话说就是数组名就是该数组的指针首地址
例:
int main(void)
{
char a[]={0x33,0x34,0x35};
char *p;
p=a;
printf("a[0]=%x\\n",a[0]);
printf("a[1]=%x\\n",a[1]);
printf("a[2]=%x\\n",a[2]);
printf("*p=%x\\n",*p);
printf("*(p+1)=%x\\n",*(p+1));
printf("*(p+2)=%x\\n",*(p+2));
printf("*a=%x\\n",*a);
printf("*(a+1)=%x\\n",*(a+1));
printf("*(a+2)=%x\\n",*(a+2));
return 0;
}
输出结果为:
a[0]=33
a[1]=34
a[2]=35
*p=33
*(p+1)=34
*(p+2)=35
*a=33
*(a+1)=34
*(a+2)=35
-
地址加一实际是根据定义类型决定的
如:
char *p;
p的地址为0x4000,由于char类型长度为1位,那么(p+1)的地址为0x4001
如果是int *p;
同样p的地址为0x4000,由于int类型长度为4位,那么(p+1)的地址为0x4004
注意事项
-
在对指针取内容之前,一定要确保指针指在了合法的位置,否则将会导致程序出现不可预知的错误
-
同级指针之间才能相互赋值,跨级赋值将会导致编译器报错或警告
评论前必须登录!
注册