指针与数组
1.1对一个数组的所有元素求和
/* sum_arr1 */ #include <stdio.h> #define SIZE 10 int sum(int ar[],int n); int main() { int marbles[SIZE] ={20,10,5,39,4,16,19,26,31,20}; long answer; answer =sum(marbles,SIZE); printf("The total number of marbles is %ld .\n",answer); printf("The size of marbles is %zd bytes.\n",sizeof marbles); //%zd格式化字符 return 0; } int sum(int ar[],int n) { int i; int total = 0; for(i=0;i<n;i++) total +=ar[i]; printf("The size of ar is %zd bytes .\n",sizeof ar); return total; }
marbles包含10个int类型的数,每个数字占4个字节,使用数组的函数需要知道何时开始和何时结束数组。函数sum()使用一个指针参量来确定数组的开始点,使用一个整数参量来指明数组的元素个数。还有另外一种方法传递两个指针。
1.2使用指针参数进行数组
/* sum_arr2*/ #include <stdio.h> #define SIZE 10 int sump(int *start,int *end); int main() { int marbles[SIZE] ={20,10,5,39,4,16,19,26,31,30}; long answer; answer =sump(marbles,marbles+SIZE); printf("The total number of marbles is %ld.\n",answer); return 0; } int sump(int *start,int *end) { int total =0; while (start<end) { total +=*start; start++; } return total; }
total +=*start++;
可以用这一行代码代替上面相同作用的代码,一元运算符*和++具有相等的优先级,在结合时是从右向左进行的。意味着++应用于start,而不是++start
1.3指针运算的优先级
/*order.c*/ #include <stdio.h> int data[2] = {100,200}; int moredata[2] = {300,400}; int main() { int *p1,*p2,*p3; p1=p2=data; p3 =moredata; printf("*p1=%d,*p2=%d.*p3=%d\n",*p1,*p2,*p3); printf("*p1++=%d,*++p2=%d.(*p3)++=%d\n",*p1++,*++p2,(*p3)++); printf("*p1=%d,*p2=%d.*(p3)=%d\n",*p1,*p2,*p3); return 0; }
【运行结果】*p1=100,*p2=100.*p3=300;
*p1++=100,*++p2=200.(*p3)++=300;
*p1=200,*p2=100.*p3=301;
上面例子中只有(*p3)++改变了数组的元素的值,其他两个操作增加了一个数组元素。
1.4指针的基本操作
1.赋值、可以把一个地址赋给指针,通常使用数组名或地址运算符&进行赋值。
2.求值、运算符*可取出指针指向地址中存储的数值。
3.取指针地址、指针变量同其他变量一样具有地址和数值,使用运算符&可以得到存储指针本身的地址
4.将一个整数加给指针、可以使用+运算符来把一个整数加给一个指针,或者把一个指针加给一个整数。
5.增加指针的值、可以通过一般的加法或增量运算符来增加一个指针的值。
6.从指针中减去一个整数、可以使用运算符来从一个指针中减去一个整数。指针必须是第一个操作数,或者是一个指向整数的指针。
7.减小指针的值、同上
8.求差值、求出两个指针间的差值。通常对分别指向同一数组内两个元素的指针求差值,以求出元素之间的距离。差值的单位是相应类型的大小
9.比较、可以使用关系运算符来比较两个指针的值,前提是两个指针具有相同的类型。
1.5 常量const
如果函数不需要修改数组,那么在声明数组参量时最好使用const
/* arf.c --处理数组的函数*/ #include <stdio.h> #define SIZE 5 void show_array(const double ar[],int n); void mult_array(double ar[],int n,double mult); int main() { double dip[SIZE] ={20.0,17.66,8.2,15.3,22.22}; printf("The original dip array: \n"); show_array(dip,SIZE); mult_array(dip,SIZE,2.5); printf("The dip array after calling mult_array(): \n"); show_array(dip,SIZE); return 0; } /*显示数组内容*/ void show_array(const double ar[],int n) { int i; for(i =0;i<n;i++) printf("%8.3f",ar[i]); putchar('\n'); } /*用同一乘数去乘每个数组*/ void mult_array(double ar[],int n,double mult) { int i; for(i =0;i<n;i++) ar[i] *=mult; }
【运行结果】
The original dip array:
20.000 17.660 8.200 15.300 22.220
The dip array after calling mult_array():
50.000 44.150 20.500 38.250 55.550
1.5.2指向常量的指针不能用于修改数组
double rates[5] ={66.2,11.5,33.6,332.3,44.6,44.2}; const double *pd =rates //pd指向数组开始处 *pd =29.89 //not allow pd[2] =222.33 //not allow rates[1] = 939.22 //allow
无论是采用数组符号还是指针符号,都不能使用pd修改所指向数据的值。rates并没有被设置为常量,所以可以使用rates来修改其数值。
1.5.3
将常量或非常量数据的地质指向常量的指针是合法的
double rates[2] ={2.33,2.11}; const double locked[3] ={1.22,3.44,2.53}; const double *pc = rates; //legal pc = locked; //legal pc = &rates[1]; //legal
然后,只有非常量数据的地址才可以赋给普通指针
double rates[2] ={2.33,2.11}; const double locked[3] ={1.22,3.44,2.53}; double *pnc =rates; //legal pnc =locked; //illegal pnc =&rates[1]; //legal
另外,show_array(const int ar[],int n)这样的函数接受普通数组和常量数组作为实际参数,想mult_array(int ar[],int n,double mult)这样的函数则不能接受常量数组的名称作为参数。
const不仅可以保护数据,而且使函数可以使用声明为const的数组、例如使用关键字const来声明并初始化指针,以保证指针不会指向别处,关键在于const的位置:
double rates[2] ={2.33,2.11}; double *const pc =rates //pc指向数组的开始处 pc =&rates[2]; //illegal *pc =92.99 //legal,edit rate[0]
这样的指针仍然可用于修改数据,但它只能指向最初赋给它的地址.
最后,可以使用两个const来创建指针,这个指针既不可以更改所指的地址,也不可以修改所指向的数据:
double rates[2] ={2.33,2.11}; const double *const pc =rates; pc =&rates[2]; //illegal *pc =92.99 //illegal
1.6多维数组
int (*pz) [2] //pz 指向一个包含2个int值得数组
为什么要使用圆括号?因为[]的优先级高于()
int *pax [2]
这代表pax是两个指针组成的数组
多维数组的示例:
/*zippo1.c--有关zippo的信息*/ #include <stdio.h> int main() { int zippo[4][2] = { {2,4},{6,8},{1,3},{5,7} }; printf("zippo= %p,zippo+1 =%p \n", zippo, zippo + 1); printf("zippo[0]= %p,zippo[0]+1 =%p \n", zippo[0], zippo[0]+ 1); printf(" *zippo= %p,*zippo+1 =%p \n", *zippo, *zippo + 1); printf("zippo[0][0] =%d\n", zippo[0][0]); printf(" **zippo=%d\n", **zippo); printf("zippo[2][1]=%d \n", zippo[2][1]); printf("*(*(zippo+2)+1)=%d\n", *(*(zippo + 2) + 1)); return 0; }
【运行结果】
zippo =003BFD1C,zippo+1=003BFD003BFD24 //[][]2*4
zippo[0]=003BFD1C,zippo[0]+1=003BFD20 //[]4
*zippo=003BFD1C,*zippo+1=003BFD20 //4
zippo[0][0] =2
**zippo =2
zippo[2][1]=3
*(*(zippo+2)+1)=3
指向多维数组的指针
/*zippo2.c --通过一个指针变量获取有关zippo的信息*/ #include <stdio.h> int main() { int zippo[4][2] = { {2,4},{6,8},{1,3},{5,7} }; int(*pz)[2]; pz = zippo; printf("pz =%p,pz+1 =%p\n", pz, pz + 1); printf("pz[0] =%p,pz[0] +1 =%p\n", pz[0], pz[0] + 1); printf(" *pz=%p,*pz+1 \n", *pz, *pz + 1); printf("pz[0][0] =%d\n", pz[0][0]); printf("*pz[0] =%d\n", *pz[0]); printf("**pz = %d \n", **pz); printf("pz[2][1] = %d\n", pz[2][1]); printf("*(*(pz+2)+1) = %d\n", *(*(pz + 2) + 1)); }
【运行结果】如上…
浙公网安备 33010602011771号