C - 指针操作
指针的分类
近指针(near)
近指针为16位指针,它只含有地址的偏移量部分,近指针用于不超过64K字节的单个数据段或代码段。在微、小和中编译模式下产生的数据指针是近指针(缺省状态),在微、小和中编译模式下产生的码指针(指向函数的指针)是近指针(缺省状态)。
远指针(far)
远指针为32位指针,指针的段地址和偏移量都在指针内,可用于任意编译模式,每次使用远指针时都要重装段寄存器,远指针可寻址的目标不能超过64K,因为远指针增减运算时,段地址不参与运算,在紧凑、大和巨模式下编译产生的数据指针是远指针(缺省状态)。
巨指针(huge)
巨指针为32位指针,指针的段地址和偏移量都在指针内,可用于任意编译模式,远指针可寻址的目标可以超过64K,巨指针是规则化的指针。
常见指针类型
//这里以int整型为例,其它数据类型同样适用,例如字符型char
char *p; //p是一个指针,该指针指向字符串首地址
int *p; //p是一个指针,该指针指向整型数
int *p[]; //p是一个数组,该数组的每一个元素是指向整数的指针
int (*p)[]; //p是一个指针,该指针指向一个数组,这个数组的每个元素是一个整数
int *p(); //p是一个函数,该函数返回一个指向整型的指针
int (*p)(); //p是一个指针,该指针指向一个函数,这个函数返回一个整数
int *(*p)();//p是一个指针,该指针指向一个函数,这个函数返回一个指向整数的指针
指针的初始化(赋值)
int *p = NULL;
int *q = (int *)malloc(sizeof(int));
指针与数组的联系
//对于一位数组 int a[] 或 指针 int *a, a + i 指向第i个元素 a[i], 即:
*(a + i) == a[i];
//对于字符串 char s[] 或 指针 char *s, s + i 指向第i个字符 s[i], 即:
*(s + i) == s[i];
//对于二维数组int a[i][j]
*a + j == &a[0][j]
*(a+i) == &a[i][0]
*(a+i)+j == &a[i][j]
//eg:
int arr[3][4] = {
1, 2, 3, 4,
5, 6, 7, 8,
9, 10, 11, 12 };
*(*(arr+2) + 3) == 12;
//对于字符串数组 char p[i][j] 或 字符型指针数组 char *p[i];
*p + j == &p[0][j];
*(p + i) + j == &p[i][j];
//eg:
char *p[3] = {"ABC", "DEF", "GHI"};
*(*(p+1)+1) == 'E';
//对于结构体
struct STR {
int x;
int *y;
} *q;
(*q).x == q->x; //表示x的内容
(*q).y == q->y; //表示指针y的值(地址)
*(*q).y == *q->y; //表示指针y指向的内容
&(*q).x == &q->x; //表示x的地址
指针的应用
float 转 unsigned char
//转换
unsigned char arr[4];
float value = 12.3;
arr[0] = (*(uint32_t *)&value) >> 24 & 0xff;
arr[1] = (*(uint32_t *)&value) >> 16 & 0xff;
arr[2] = (*(uint32_t *)&value) >> 8 & 0xff;
arr[3] = (*(uint32_t *)&value) >> 0 & 0xff;
//验证
float v = 0;
*(uint32_t *)&v = arr[0]<<24 | arr[1]<<16 | arr[2]<<8 | arr[3];
printf("v = %f\n", v);