数组和指针(一)

一.数组
数组由一系列类型相同的元素构成。可以使用声明告诉编译器你需要一个数组。
数组的声明中包括数组元素的数目和元素的类型。
1.初始化
含有12个元素的数组可以用来存储12个月的天数。
int days[12]={31,28,31,30,31,30,31,31,30,31,30,31};
数组的第一个元素为days[0],最后一个元素为days[11],没有day[12]这个元素。
如果出现 int days[12]={};这种初始化,代表12个元素的数值都为0.
若是int days[12]={31,28};则表示后面10个元素的数值为0.
#include <stdio.h>
#define MONTHS 12


int main(void)
{
    int days[MONTHS] = {31,28,31,30,31,30,31,31,30,31,30,31};
    int index;


    for (index = 0; index < MONTHS; index++)
        printf("Month %d has %2d days.\n", index +1,
               days[index]);
  
    return 0;
}


这个例子打印12个月的天数。例子中采用标识符常量来代表数组的大小,这样利


于我们修改程序。
如果我们进行了如下的声明:
const int days[MONTHS]={31,28,31,30,31,30,31,31,30,31,30,31};
这样,程序会把数组中的每个元素当做常量处理,无法改变,不能赋值。
#include <stdio.h>
#define SIZE 4
int main(void)
{
    int no_data[SIZE]; 
    int i;


    printf("%2s%14s\n",
           "i", "no_data[i]");
    for (i = 0; i < SIZE; i++)
        printf("%2d%14d\n", i, no_data[i]);
  
    return 0;
}




和不同变量相似,在初始化之前数组元素的数值是不定的。
#include <stdio.h>
#define SIZE 4
int main(void)
{
    int some_data[SIZE] = {1492, 1066};   
    int i;


    printf("%2s%14s\n",
           "i", "some_data[i]");
    for (i = 0; i < SIZE; i++)
        printf("%2d%14d\n", i, some_data[i]);
  
    return 0;
}


初始化列表中的元素数目应该和数组大小一致。如果不一致,当数值数目少于数


组元素数目时,多余的元素初始化为0,当数值数目多余数组元素数目时,编译器


会认为这是一个错误。我们可以省略括号中的数字,让编译器自动匹配数组大小


和初始化列表中的项目数目。
#include <stdio.h>
#define MONTHS 12


int main(void)
{
    int days[MONTHS] = {31,28,31,30,31,30,31,31,30,31,30,31};
    int index;


    for (index = 0; index < MONTHS; index++)
        printf("Month %2d has %d days.\n", index +1,
               *(days + index));   
  
    return 0;
}


需要注意的两点:
1.使用空括号进行初始化,编译器会根据列表中的数值数目来确定数组的大小。
2.使用for循环控制语句时,由于人工计算容易出错,可以让计算机来计算数组的


大小。


2.指定初始化项目
c99增加了一种新特性:指定初始化项目。此特性允许选择对某些元素进行初始化


。例如:int arr[6]={[5]=212};
#include <stdio.h>
#define MONTHS 12
int main(void)
{
    int days[MONTHS] = {31,28, [4] = 31,30,31, [1] = 29};
    int i;


    for (i = 0; i < MONTHS; i++)
        printf("%2d  %d\n", i + 1, days[i]);
   
    return 0;
}


从上述例子中可以看出,我们可以指定初始化元素,并且如果一个元素进行多次


初始化,那么最后一次的初始化有效。
3.赋值
c不支持把数组作为一个整体来进行赋值,也不支持用花括号括起来的列表形式进


行赋值,而应该采用循环的方法对元素逐个赋值。
4.边界
使用数组是,需要注意的是数组的索引不能超过数组的边界。
#include <stdio.h>
#define SIZE 4
int main(void)
{
    int value1 = 44;
    int arr[SIZE];
    int value2 = 88;
    int i;


    printf("value1 = %d, value2 = %d\n", value1, value2);
    for (i = -1; i <= SIZE; i++)
        arr[i] = 2 * i + 1;
        
    for (i = -1; i < 7; i++)
        printf("%2d  %d\n", i , arr[i]);
    printf("value1 = %d, value2 = %d\n", value1, value2);


    return 0;
}


以上程序就使用了错误的索引,如果使用那么程序执行结果将不可知。为了避免


这个问题的出现的比较简单的方法是使用符号常量。
二.多维数组
二位数组的声明方法:
float rain[5][12];
这个数组包含5个元素的数组,每一个元素又是一个包含12个元素的数组。即数组


是一个5行12列的数组。
#include <stdio.h>
#define MONTHS 12    
#define YEARS   5   
int main(void)
{
    const float rain[YEARS][MONTHS] =
    {
        {4.3,4.3,4.3,3.0,2.0,1.2,0.2,0.2,0.4,2.4,3.5,6.6},
        {8.5,8.2,1.2,1.6,2.4,0.0,5.2,0.9,0.3,0.9,1.4,7.3},
        {9.1,8.5,6.7,4.3,2.1,0.8,0.2,0.2,1.1,2.3,6.1,8.4},
        {7.2,9.9,8.4,3.3,1.2,0.8,0.4,0.0,0.6,1.7,4.3,6.2},
        {7.6,5.6,3.8,2.8,3.8,0.2,0.0,0.0,0.0,1.3,2.6,5.2}
    };
    int year, month;
    float subtot, total;


    printf(" YEAR    RAINFALL  (inches)\n");
    for (year = 0, total = 0; year < YEARS; year++)
    {             
        for (month = 0, subtot = 0; month < MONTHS; month++)
            subtot += rain[year][month];
        printf("%5d %15.1f\n", 2000 + year, subtot);
        total += subtot; 
     }
    printf("\nThe yearly average is %.1f inches.\n\n",
            total/YEARS);
    printf("MONTHLY AVERAGES:\n\n");
    printf(" Jan  Feb  Mar  Apr  May  Jun  Jul  Aug  Sep  Oct ");
    printf(" Nov  Dec\n");


    for (month = 0; month < MONTHS; month++)
    {             
        for (year = 0, subtot =0; year < YEARS; year++)
            subtot += rain[year][month];
        printf("%4.1f ", subtot/YEARS);
    }
    printf("\n");
 
    return 0;
}




这个一个二维数组以及他的应用。
二位数组的初始化:
const int rain [2][2]={
                        {1,3},
                        {4,5} 
};
初始化使用了2个数组列表,每个数组列表都用花括号括起来。第一个列表被赋值


给数组的第一行,第二个列表被赋值给数组的第二行。初始化的时候也可以省略


内部花括号,只保留最外面的一对花括号,只要保证数值的个数正确即可。
对于更加多维的数组声明方法和二维一样:
int rain[10][20][30]
三.数组和指针
由于指针提供了一种用来使用地址的符号方法,使得指针能够类似计算机底层的


表达方式来表达自己的意愿,使得依赖指针能够更加高效的工作。特别的,指针


能够很有效地处理数组。例如:
flizny==&flizny[0]
数组名同时也是该数组首个元素的地址。
#include <stdio.h>
#define SIZE 4
int main(void)
{
    short dates [SIZE];
    short * pti;
    short index;
    double bills[SIZE];
    double * ptf;


    pti = dates;    
    ptf = bills;
    printf("%23s %10s\n", "short", "double");
    for (index = 0; index < SIZE; index ++)
        printf("pointers + %d: %10p %10p\n",
                index, pti + index, ptf + index);
  
    return 0;
}


在c中对一个指针加1的结果是指对该指针增加一个存储单元。对于数组而言,地


址会增加到下一个元素的地址,而不是下一个字节。
#include <stdio.h>
int main(void)
{
    const int days[] = {31,28,31,30,31,30,31,31,30,31};
    int index;


    for (index = 0; index < sizeof days / sizeof days[0]; index++)
        printf("Month %2d has %d days.\n", index +1,
               days[index]);
  
    return 0;
}


上述例子中体现了c语言的优点,即例如
dates+2==&date[2]    //相同的地址
*(dates+2)==dates[2]  //相同的值
此外,days是数组首元素的地址,day+index是元素days[index]的地址,*


(days+index)是这个元素的值,与days[index]等价。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值