c primer plus第10章总结:数组和指针

1、数组初始化 :
    数组:元素数目+元素类型;
int powers[4] = {1, 2, 4, 6} ;     // 花括号,逗号隔开;未经初始化的数组,编译器会使用存储单元中的已有的数值给它赋值;
days[] = {31,28,31,30,31,30,31,31,30,31,30,31}; // 允许,编译器会根据列表中数值数目来确定数组大小;
指定初始化项目: int arr[6] = {212};// 其他未初始化的元素都被设置为0;多次对同一元素赋值,最后一次有效;
      指针初始化 :
int* p = NULL;
int* p = new int[10];   // 注意  delete []p(数组) 或者delete p(非数组);
  指针和数组粘合:
// 一维数组
char str[10] = { '1', '2', '3'};
char* p = str; 
// 一维数组
char str[10] = { '1', '2', '3'};
char* p = str; 
// 普通变量
int a = 1;
int* pa = &a;
若函数参数为指针,且指向二维数组,调用该函数时,需要带[0];例: rain_ptr ( rain [0]);

2、const 声明数组:
使用const 使数组只读,程序可以从数组中读取数值,但是不能像数组中写数据;
const int days[12] = {31,28,31,30,31,30,31,31,30,31,30,31};     //  声明之后不能再对它赋值;
形参使用const:
     int sum(const int ar[], int n);// 定义ar所指向的数组值为常量,不允许修改;
指向常量的指针不能修改数值,将常量或非常量数据的地址赋值给指向常量的指针时合法的;但只有非常量的数据地址才可以赋值给普通指针;
const double* p = days[] ; 指针指向的值不能被改变,但可以改变地址来改变指向的数组值;
double* const p = days[] ; 指针地址不能变; 

守则:在能加const的地方都加上 

3、遍历index,打印数组中各个元素:
 int days[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
  for (int index = 0;  index < 12;  index++)
        printf("Month %d has %2d days.\n", index +1,   days[index]);
仅字符数组可以直接整体打印,但字符数组 必须有 0 结尾;标识符用 %s;
char  ar[] = { 'a' , 's' , 'c' , '\0' };
   printf( "%s\n" ,ar);

4、为数组赋值:
c语言不支持把数组作为一个整体赋值,也不支持花括号括起来的列表形式赋值(初始化的时候除外);
通过循环数组索引对数组成员赋值:
     int counter, evens[12];
     for (counter = 0; counter < 12; counter++)
          evens[counter] =  2 * counter;

5、多维数组:
     float rain[5][12]; // 5个由12个浮点数组成的数组的数组;
     初始化二维数组:
 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},     // 逗号分离隔的5个数值列表;
        {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}
    };

6、指针和数组:
     数组名也是该数组首元素的地址,指针说明符%p,通常以十六进制显示值;系统按字节编址,对指针+1 ,是对该指针增加一个 存储单元,对数组,会增加到下一个元素的地址;
     dates +2 ==  &dates[2];// 地址相同
     *(dates + 2) == dates[2];// 相同的值    // 间接运算符* 的优先级高于+;
       ar为指针或数组,均有 ar[i] 和 *(ar+i) 等价;
      ar为指针时,才能使用 ar++;
     计算数组长度:
     int ar [] = {11, 5, 9, 6};
     int n = sizeof ar / sizeof (int );
    指针指向的数组长度怎么计算??无法计算。
     

7、函数、数组、指针:
     仅 在函数原型或函数定义头时,可以用 int *ar 代替 int ar[];   此时指针与数组等效;
声明数组参量:
     如果实际参数是一个数组名,形式参量必须是与之匹配的指针;
函数原型中,以下4种可相互等效:
     int sum (int *char, int n)
     int sum (int *, int )
               int sum (int ar[], int n)
     int sum (int [], int )
函数定义时,名称不能省略,以下2种可相互等效 :
      int sum (int *char, int n)
     {
     }
     int sum (int ar[], int n)
    {
    }
说明符打印sizeof()的返回值,用%zd;

 8、使用指针参数:
// 用index遍历元素,求数组元素和;
 int main(void)
{
    int marbles[SIZE] = {20,10,5,39,4,16,19,26,31,20};
    long answer;
    answer = sum(marbles, SIZE);
    return 0;
}
int sum(int ar[], int n)    
{
    int i;    
    int total = 0;
    for( i = 0; i < n; i++)
        total += ar[i];
     return total;
}

// 定义两个指针,start 和 end 指明指针起始和结束地址;    
int main(void)
{
    int marbles[SIZE] = {20,10,5,39,4,16,19,26,31,20};
    long answer;
    answer = sump(marbles, marbles + SIZE);
     return 0;
}
int sump(int * start, int * end)
{
    int total = 0;
    while (start < end)  //  结束地址指向数组结尾之后的下一个元素
    {
        total += *start; 
  // 等价total += *start++; * 和 ++优先级相等,但结合方式是从右到左;
        start++;       
    }
    return total;
}

课后习题

第一题:二维数组转化为一维数组:
  for ( year = 0, total = 0; year < YEARS ; year ++)
    {                                                                     
        for ( month = 0, subtot = 0; month < MONTHS ; month ++)
               subtot += rain [ year   MONTHS   month ];// 二维转为一维,求所有元素之和;
        printf ( "%d %.1f\n" , year , subtot );                                              
     }

第二题:用数组和指针复制一个数组;


// 用数组符号进行拷贝
voidcopy_arr(doublesource[],doubletarget1[],intn)
{
      for ( inti = 0; i < n;i++)
     {
           target1[i] = source [i ];
           printf("%.2f ", target1 [i ]);   
     }
      printf("\n");
}
// 用指针进行拷贝
void copy_ptr (double* source , double *target2 , int n )
{
      for ( inti = 0; i < n;i++)
     {
          *( target2 + i) = *(source+ i);
           printf("%.2f ", target2 [i ]);    
     }
      printf("\n");
}

第十题:初始化数组、翻倍数组中各元素;
double * ar = get_double ( n , m );
double * init_ar ( int n , int m )
{
      double * ar = new double [ n * m ];   // 用new创建指针数组;
      // 初始化声明的数组
      for ( int i = 0; i < n; i++)
     {
           for ( int j = 0; j < m; j++)
          {
              ar[i * m + j ] = i + j / 10.;
              printf( "%.1f " , ar[i * m + j ]);  // 注意是乘以内存循环参数
          }
          printf( "\n" );
     }
      printf ( "\n" );
      return ar;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值