1. 数组
①使用数组之前需要初始化数组,否则会存储垃圾值;如果部分初始化数组,剩余的元素会被初始化为0;对于数组的长度,可以省略,让编译器自动匹配数组大小。
②sizeof 数组名,得到的是整个数组的大小(以字节为单位),sizeof 数字名[0],得到的是数组中一个元素的大小(以字节为单位)。整个数组的大小除以单个元素的大小就是数组元素的个数。
③C语言不允许把数组作为一个单元赋给另一个数组。
2. 指针和数组
① 数组名是数组首元素的地址。
eg. int a[10]={0};
a==&a[0];
a和&a[0]都表示数组首元素的内存地址,两者都是常量,可以把它们赋值给指针,然后可以修改指针变量的值。
② 指针的值是它所指向对象的地址,在指针前面使用 * 运算可以得到该指针所指向对象的值,指针+1,指针的值递增它所指向类型的大小(以字节为单位)。(一个数组中,将首地址赋值给指针,指针+1就达到第二个地址的位置)
③ 可以使用指针标识数组的元素和获得元素的值。
eg1. short dates[4];
dates+2==&dates[2]; //相同的地址
* (dates+2)==dates[2]; //相同的值
eg2. 不要混淆 *(dates+2) 和 *dates+2
* 的优先级高于+,所以*dates+2==(*dates)+2
*(dates+2) //dates中的第三个元素的值
*dates+2 //dates中第一个元素的值+2
④ c语言在描述数组的时候借助到了指针,定义ar[n]的意思是*(ar+n)。
3. 函数、数组和指针
① 假设我们要编写一个处理数组的函数,该函数返回数组中所有元素的和,待处理的是名为a的int类型的数组,如何调用函数?
也许是这样:total=sum(a);
我们知道数组名代表数组首元素的地址,所以实际参数a是一个存储int类型值的地址,应该把它赋给一个指针形式参数: int sum(int *ar);
也就是说能使用指针表示数组名,也可以用数组名表示指针。
int sum(int * ar,int n){
int i;
int total=0;
for(i=0;i<n;i++){
total+=ar[i];
}
return total;
}
注意:
int *ar 形式和int ar[ ]形式都表示ar是一个指向int的指针。
② 数组名是该数组元素的首地址,作为实际参数的数组名要求形式参数是一个与之匹配的指针。只有在这种情况下,c才会把int ar[ ]和int *ar 解释成一样。也就是说,ar是指向int的指针。
4. 指针操作
int a[5]={100,200,300,400,500}
int *p1,*p2,*p3;
p1=a; //数组a[0]的首地址(第一个元素),也就是元素100所在的地址
p2=&a[2]; //数组a[2]第三个元素300的地址
p3=p1+4; //0+4=4 数组a[4]代表第五个元素500的地址
p1++; //0+1=1 数组a[1]第二个元素200的地址
p2--; //2-1=1 数组a[1]第二个元素200的地址
--p1; //1-1=0 数组a[0]第一个元素100的地址
++p2; //1+1=2 数组a[2]第三个元素300的地址
p2-p1; //2-1=1 所以是数组a[1]第二个元素200的地址
p3-2; //4-2=2 数组a[2]代表第三个元素300的地址
① 赋值:可以把地址赋给指针
② 解引用:* 运算符给出指针指向地址上存储的值
③ 取址:&运算符给出指针本身的地址
④ 指针与整数相加:实际是当前指针所代表的数组的下标和整数相加,得到的数字是数组的下标,进行+1,就是第几个元素的值
⑤ 递增指针:++
⑥ 指针减去一个整数:同④
⑦ 递减指针:--
⑧ 指针求差:也是两个指针所代表的数组下标进行相减,同④