————指针变量和常数的运算
前提条件:指针指向一片连续分配的空间,例如数组。
分析:以数组为例
#include<stdio.h>
int main()
{
int arr[9] = { 1,2,3,4,5,6,7,8,9 };
int* p = arr;
printf("p=%d\n", *p);
printf("p+5=%d\n", *(p + 5));
return 0;
}
打印出的结果应当是: p=1
p+5=6
即机器会自动识别指针变量后面那个常数(不妨将其设为number),将其转化为sizeof(int)*number的字节数,把这个转化过的数和地址相加,从而使得指针变量指向number个单元格后的数组元素。
事实上,sizeof(int)=4字节,sizeof(char)=1字节
——*p++
在某些系统中,*p++是一种汇编语言,能够比较快速的调用运行。
分析:*运算符优先级比较高,但是++运算符的优先级更高,因此运行的结果是先让指针变量移动,在取其所指变量的值。
——遍历数组元素的方法
循环次数的确定:假设定义了一个数组,名叫AC,认为for循环(打印数组元素)的次数为sizeof( AC)/sizeof(AC[0]) //用数组元素的总长除以单位长度,得到数组元素个数 。
for(i=0;i<sizeof(AC)/sizeof(AC[0];i++)
{
printf("%d",AC[i]);
}
————指针的比较
<,>,<=,>=,==,!=都可以对指针进行,可以比较他们在内存中的地址,一般认为数组中的单元的地址都是线性增加的(每次增加sizeof(数据类型)个字节。)
————0地址
在给指针变量赋值的时候,应该避免赋值0的情况。
0地址通常是个不能随便乱碰的地址。
0地址通常可以做一些特殊的事情,例如
——表示返回的指针是无效的
——表示指针没有真正的被初始化(先初始化为0,后续再补充。)
在某些编译器中,不愿意使用赋值为0来完成上面的工作,因此直接用“NULL”即可。
————指针的类型
——指针变量的值
无论指向何种类型的变量,指针的大小都是相同,因为都是地址。
但是指向不同类型的指针无法相互赋值。
——声明指针变量所指向的类型的作用
我们认为,声明不同类型的作用是,规定指针在内存中每次移动的字节数(可以用盖革表来形象的理解),来获取变量的值(在一片连续的内存空间中适用)。例如
int *p=&a //规定指针每次移动的字节数是4(在常见编译器环境下)
——值相同的两个指针变量可以指向不同的变量
首先要明白,指针指向变量的过程分两个,先是指向首地址(定位),然后移动若干个字节数来读取变量的值(移动),值相同仅仅意味着两个指针变量定位在了同一个首地址上,但由于类型不同,即移动的字节数不同,从而指向了不同的变量。
事实上,这就引入了指针类型转换这一操作,即通过类型的转换,来迫使两个类型不同的指针变量的移动保持一致。