[C语言] 指针的详解与应用-理论结合实践,真正理解指针!_哔哩哔哩_bilibili
------学习视频来自B站江科大自化协
指针简介
- 指针(pointer)是C语言的一个重要知识点,其使用灵活、功能强大,是C语言的灵魂。
- 指针与底层硬件联系紧密,使用指针可操作数据的地址,实现数据的间接访问。
计算机存储机制
int a = 0x12345678;
short b =0x5a6B;
char c[]={0x33,0x34,0x35};
现在计算机普遍采用小端存储模式。小端存储模式:低位保存在低地址中。
ps:0x12345678 12是高位 这个和十进制1000中的“1”来说是一样的,1相对于后面来说是高位。
数组作为数据整体是按顺序存储的,数组里的数据是按小端存储模式存储的。
定义指针
- 指针即指针变量,用于存放其他数据单元(变量/数组/结构体/函数等)的首地址。若指针存放了某个数据单元的首地址,则这个指针指向了这个数据单元,若指针存放的值是0,则这个指针为空指针。
- 定义一个指针变量:
数据类型 | 指向该数据类型的指针 | ||
(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
#include <stdio.h>
int main(void)
{
char a;
int b;
int *p,p1;//*号可以放在int的后面,也可以放在指针变量名的前面 放在指针变量名前面方便区分数据类型。
printf("%d\n",sizeof(a));
printf("%d\n",sizeof(b));
printf("%d\n",sizeof(p));
return 0;
}
输出结果:
1
4
8
指针的操作
若已定义:
int a; //定义一个int型的数据
int *p; //定义一个指向int型数据的指针
则对指针p有如下操作方式:
操作方式 | 举例 | 解释 |
取地址 | p=&a; | 将数据a的首地址赋值给p |
取内容 | *p; | 取出指针指向的数据单元 |
加 | p++; | 使指针向下移动1个数据宽度 |
p=p+5; | 使指针向下移动5个数据宽度 | |
减 | p--; | 使指针向上移动1个数据宽度 |
p=p-5; | 使指针向上移动5个数据宽度 |
如果*出现在变量类型后面,它只是一种标志,代表该变量是指针变量。
如:
int *p;
如果*p单独出现,代表的是取指针p所指向的内容
如:
a=*P;
#include <stdio.h>
int main(void)
{
char a=0x66;
char *p;
p=&a;
printf("%x\n",a);
printf("%x\n",p);
printf("x\n",*P);
return 0;
}
结果:
66
62fe47---------------不同机器以及编译器会出现不同的值
66
ps:指针的加减并不是加减十进制数据,而是加减数据宽度。指针的加减一般用于数组,对于单独的数据来说没有意义。
如果是
char类型 1字节
short int 类型 2字节
int类型 4字节
数组与指针
- 数组是一些相同数据类型的变量组成的集合,其数组名即为指向该数据类型的指针。数组的定义等效于申请内存、定义指针和初始化。
例如:char c[] = {0x33,0x34,0x35}
等效于:1、申请内存 2、 char *c = 0x4000; 3、初始化数组数据
- 利用下表引用数组数据也等效于指针取内容。
例如:
c或c[0]; 等效于: *c
c[1]; 等效于: *(c+1)
c[2]; 等效于: *(c+2)
#include <stdio.h>
int main(void)
{
char a[]={0x33,0x34,0x35};//这条代码和下面注释的代码是一样的
//int *a;
//a = malloc(3*4);
//*a=0x33;
//*(a+1)=0x34;
//*(a+2)=0x35;
char *P;
p=a;
printf("a[0]=%x\n",a[0]);
printf("a[1]=%x\n",a[1]);
printf("a[1]=%x\n",a[2]);
printf("*p=%x\n",*p);
printf("*(p+1)=%x\n",*(p+1));
printf("*(p+1)=%x\n",*(p+1));
printf("*a=%x\n",*a);
printf("*(a+1)=%x\n",*(a+1));
printf("*(a+1)=%x\n",*(a+1));
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
注意事项
- 在对指针取内容之前,一定要确保指针指在了合法的位置,否则将会导致程序出现不可预知的错误。
- 同级指针之间才能相互赋值,跨级赋值将会导致编译器报错或警告。