C语言指针
1.指针简介
- 指针与底层硬件紧密联系,使用指针可操作数据地址,实现数据的间接访问
2.计算机存储机制
在C语言中内存的分配是以一个字节为单位进行线性分配且每个字节都会对应的地址
-
int a = 0x12345678;
-
short b = 0x5A6B;
-
char c[] = {0x33,0x34,0x35 };
**int:**一个int 32字节,那么一个int则跨越四个地址,存储规则为:小段模式(小段在前)
目前计算机常用小段在前的分配方式
**数组:**数组在内存中是一个连续的空间
3.定义指针
- 指针即指针变量,用于存放其他数据单元(变量,数组,结构体,函数等)的首地址。若指针存放了某个数据单元的首地址,则这个指针指向了这个数据单元,若指针存放的值为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()
{
int a;
//指向int*的指针变量
int *p;
//sizeof用来查看占用多少字节
printf("%d\n",sizeof(a));
printf("%d\n",sizeof(p));
return 0;
}
输出结果如下:
4
4
--------------------------------
Process exited after 0.009431 seconds with return value 0
字符型:
#include <stdio.h>
int main()
{
char a;
//指向int*的指针变量
char *p;
//sizeof用来查看占用多少字节
printf("%d\n",sizeof(a));
printf("%d\n",sizeof(p));
return 0;
}
输出结果如下:
1
4
--------------------------------
Process exited after 0.008878 seconds with return value 0
4.指针的操作
- 若已定义:
int a; //定义一个int型数据
int *p //定义一个指向int型的数据
- 则对定义指针P有如下操作方式:
操作方式 | 举例 | 解释 |
---|---|---|
取地址 | p=&a; | 将数据a的首地址赋值给p |
取内容 | *p; | 取出指针指向的数据单元 |
加 | p++; | 使指针向下移动1个数据宽度 |
p=p+5 | 使指针向下移动5个数据宽度 | |
减 | p–; | 使指针向上移动1个数据宽度 |
p=p-5 | 使指针向上移动5个数据宽度 |
代码演示:
取地址与取内容:
#include <stdio.h>
int main()
{
char a = 0x66;
//指向int*的指针变量
char *p;
p = &a;
//sizeof用来查看占用多少字节
printf("%x\n",a);
printf("%x\n",p);
//取出指针p的内容
printf("%x\n",*p);
return 0;
}
输出结果:
66
62fecb
66
--------------------------------
Process exited after 0.009014 seconds with return value 0
实际上a存储在了62fecb这个地址,该地址为程序分配
指针加法演示:
#include <stdio.h>
int main()
{
int a = 0x66;
//指向int*的指针变量
int *p;
p = &a;
//sizeof用来查看占用多少字节
printf("%x\n",a);
printf("%x\n",p);
printf("%x\n",*p);
p++;
printf("%x\n",p);
return 0;
}
输出结果:
66
62fec8
66
62fecc
--------------------------------
Process exited after 0.01018 seconds with return value 0
通过计算62fec8-62fecc=4;可得通过P++后,指针向下移动一个数据宽度
如将p++改为p–则结果相反
5.数组与指针
- 数组是一些相同数据类型的变量组成的集合,其数组名即为指向该数据类型的指针。数组的定义等效于申请内存、定义指针和初始化
例如:char c[] = {0x33,0x34,0x35};
等效于:申请内存
定义char *c = 0x4000;
初始化数组数据
- 利用下标引用数组数据也等效于指针取内容
例如: C[0]; 等效于:*C
C[1];等效于:*(C+1);
C[2];等效于: *(C+2);
代码演示:
#include <stdio.h>
#include <stdlib.h>
int main()
{
// char a[]={0x33,0x34,0x35};
int *a;
a = (int*)malloc(3*4);
*a = 0x33;
*(a+1)=0x34;
*(a+2)=0x35;
printf("char[0]=%x\n",a[0]);
printf("char[0]=%x\n",a[1]);
printf("char[0]=%x\n",a[2]);
printf("\n");
printf("*a=%x\n",*a);
printf("*(a+1)=%x\n",*(a+1));
printf("*(a+2)=%x\n",*(a+2));
return 0;
}
输出结果:
char[0]=33
char[0]=34
char[0]=35
*a=33
*(a+1)=34
*(a+2)=35
--------------------------------
Process exited after 0.0111 seconds with return value 0
6.指针的注意事项:
- 在对指针取内容之前,一定要确保指针指在了合法的位置,否则将会导致程序出现不可预知的错误
- 同级指针之间才能相互赋值,跨越赋值将会导致编译器出错
7.指针的应用
-
传递参数
1.使用指针传递大容量参数,主函数与子函数使用的是同一套数据,避免了参数传递过程中的数据复制,提高了运行效率,减少了内存占用
2.使用指针传递输出参数,利用主函数和子函数同一套数据的特性,实现数据返回,可实现多返回值函数的设计
-
传递返回值
1.将模块内的公有部分返回,让主函数持有模块的“句柄”,便于程序对指定对象的操作
-
直接访问物理地址下的数据
1.访问硬件指定内存下的数据,如设备ID号等
2.将复杂的格式数据转换为字节,方便通讯与存储
代码演示:
参数的传递:
#include <stdio.h> #include <stdlib.h> //const表示该数据只读 int FindMAX(const int *data,int c) { int i; int max=data[0]; for(i=1;i<=c;i++) { if(data[i]>max) { max=data[i]; } } return max; } int main() { int a[]={2,3,4,4,5,6}; int max; max=FindMAX(a,5); printf("max=%d\n",max); return 0; }
输出结果:
max=6 -------------------------------- Process exited after 0.009708 seconds with return value 0
多返回值函数:
#include <stdio.h> #include <stdlib.h> //const表示该数据只读 void FindMAX(int *max,int *count,int *data,int length) { int i; *max=data[0]; *count=1; for(i=1;i<=length;i++) { if(data[i]>*max) { *max=data[i]; *count = 1; }else if(data[i]==*max) { (*count)++; } } } int main() { int a[]={6,3,4,4,5,6}; int max; int count; FindMAX(&max,&count,a,5); printf("max=%d\n",max); printf("count=%d\n",count); return 0; }
输出结果:
max=6 count=2 -------------------------------- Process exited after 0.009176 seconds with return value 0