指针与数组

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));
}

【运行结果】如上…

posted on 2015-12-03 12:37  Keatles  阅读(111)  评论(0)    收藏  举报

导航