指针是有类型的,指针分变量和常量
常量指针:
指向一个常量,就是不能做*p运算
比如:
int n = 0,m = 1;
const int *p;
p=&n;
n这个空间的值不能通过*p这个渠道去赋值,只能通过其本身的变量名去赋值:即不能写成 *p=5,必须写成n=5;
但p可以修改指向其他的空间p = &m
指针常量:
必须在定义时赋值,之后再也不能对它进行赋值操作
比如:
int n = 0,m = 1;
int * const p = &n;
p不能修改指向其他的空间,但可以修改空间里面的值:即不能 p = &m
空间里面的值可以通过两个渠道修改 *p = 5,n = 5
数组-特殊性质的指针:
数组名这个地址没有存储空间,是一个特殊性质的指针
一维数组:
int a[3]中a为特殊性质地址,类型为int型,a+1偏移4个字节
二维数组:
int b[2][3]中a和a[0]为特殊性质地址,但还是有类型的,b的类型为3*int型,b+1偏移3*int=12个字节,b[0]的类型为int型,b[0]+1偏移4个字节,对于二维数组的指针可以通过 int (*p)[3];p = b;来接收
对特殊性质的指针进行sizeof运算会得到整个数组的大小
对一维数组a进行sizeof(a)运算,得到的结果为:3*int=12
对二维数组b进行sizeof(b),得到的结果为:2*3*int=24
对一维数组b[0]进行sizeof(b[0])运算,得到的结果为:3*int=12
对于特殊性质的指针赋给指针变量,要求指针变量和特殊数组是同类型的:
一维数组:
int a[3]={0,1,2};
a的类型为int型;所以要用int型的指针变量去接收;即为int *p=a;
对一位数组元素进行访问时有三种方式:
*p=p[0]=a[0]=0;
*(p+1)=p[1]=a[1]=0;
二维数组:
int b[2][3]={0,1,2,3,4,5};
b的类型为int*3型;所以要用int*3型的指针变量去接收;即为int (*p)[3]=b;
这样p的的类型为int*3;
对二维数组元素进行访问时有三种方式:
(*p)[0]=p[0][0]=b[0][0]=0;
(*(p+1))[0]=p[1][0]=b[1][0]=3;
指针变量:
int *p中p为变量地址,p的类型为int型,p+1偏移4个字节
对指针变量进行sizeof运算只会得到4个字节,对指针变量指向的空间进行sizeof运算才会得到类型所占的空间
对p进行sizeof(p)运算得到的结果为:4
对*p进行sizeof(*p)运算得到的结果为:int=4
当将指针常量当做实参传递时,在子函数中会被当做指针变量来处理,因为形参是有空间的
有下面的代码:
void pointer(char *a)
{
printf("%d\n%d\n", sizeof(a), sizeof(*a));
}
int main()
{
char a[5][5] = { { 5 },{ 4 } };
printf("%d\n", sizeof(a[0]));
pointer(a[0]);
return 0;
}
上面代码的运行结果为:
5
4
1
如果指针为char型,*char会取出一字节的数据;
如果指针为short型,*short会取出两字节的数据;
如果指针为int型,*int会取出四字节的数据;
如果指针为long型,*int会取出四字节的数据;
如果用char类型的指针去取int数据:分大端模式和小端模式;
大端模式下会取出高位字节数据;
小端模式下会取出低位字节的数据;
举例:定义一个char类型的指针和一个int型的数据;char *i;int j=1;
j赋值为1:所以j在内存中的存储为:
[0000 0000][0000 0000][0000 0000][0000 0001]
高位字节 低位字节
把int型的首地址赋给char指针
i=&j;
大端模式下数据取出先后顺序为:
*i=0; 低地址存高字节数据
*(i+1)=0;
*(i+2)=0;
*(i+3)=1; 高地址存低字节数据
小端模式下数据取出先后顺序为:
*i=1; 低地址存低字节数据
*(i+1)=0;
*(i+2)=0;
*(i+3)=0; 高地址存高字节数据
其他例子:定义一个short一维数组用int型指针取四字节的数据
int *z;short i[2]={1,2};
i数组在内存中的存储为:
[0000 0000][0000 0001][0000 0000][0000 0010]
高字节数据 低字节数据
把首地址赋给z;
z=i;
大端模式下数据取出先后顺序为:i --> [0000 0000] 低地址存高字节数据
[0000 0001]
[0000 0000]
[0000 0010] 高地址存低字节数据i --> [0000 0001] 低地址存低字节数据
[0000 0000]
[0000 0010]
[0000 0000] 高地址存高字节数据int main(void)
{
int *z;
short i[2]={1,2};
z=&i;
printf("%x",*z);
return 0;
}
小端模式下运行结果为:
00020001
大端模式下运行结果为:
02000100