有书共读22《C primer Plus》

1)数组:可以存储一个固定大小的相同类型元素的顺序集合。数组是用来存储一系列数据,但它往往被认为是一系列相同类型的变量。

数组的声明并不是声明一个个单独的变量,比如 number0、number1、...、number99,而是声明一个数组变量,比如 numbers,然后使用 numbers[0]、numbers[1]、...、numbers[99] 来代表一个个单独的变量。数组中的特定元素可以通过索引访问。

所有的数组都是由连续的内存位置组成。最低的地址对应第一个元素,最高的地址对应最后一个元素。


2)声明数组:声明一个数组,需要指定元素的类型和元素的数量,如下所示:

type arrayName [ arraySize ];

这叫做一维数组。arraySize必须是一个大于零的整数常量,type可以是任意有效的 C 数据类型。例如,要声明一个类型为 double 的包含 10 个元素的数组balance,声明语句如下:

double balance[10];

现在balance是一个可用的数组,可以容纳10个类型为 double的数字。

3)初始化数组:可以逐个初始化数组,也可以使用一个初始化语句,如下所示:

double balance[5] = {1000.0, 2.0, 3.4, 7.0, 50.0};

大括号 { } 之间的值的数目不能大于我们在数组声明时在方括号 [ ] 中指定的元素数目。

如果您省略掉了数组的大小,数组的大小则为初始化时元素的个数。因此,如果:

double balance[] = {1000.0, 2.0, 3.4, 7.0, 50.0};

您将创建一个数组,它与前一个实例中所创建的数组是完全相同的。下面是一个为数组中某个元素赋值的实例:

balance[4] = 50.0;

上述的语句把数组中第五个元素的值赋为 50.0。所有的数组都是以 0 作为它们第一个元素的索引,也被称为基索引,数组的最后一个索引是数组的总大小减去 1。以下是上面所讨论的数组的图形表示:

4)访问数组元素:

数组元素可以通过数组名称加索引进行访问。元素的索引是放在方括号内,跟在数组名称的后边。例如:

double salary = balance[9];

上面的语句将把数组中第 10个元素的值赋给 salary 变量。下面的实例使用了声明数组、数组赋值、访问数组的概念:

#include <stdio.h>
 
int main ()
{
   int n[ 10 ]; /* n 是一个包含 10 个整数的数组 */
   int i,j;
    /* 初始化数组元素 */        
    for ( i = 0; i < 10; i++ )    {
        n[ i ] = i + 100; /* 设置元素 i 为 i + 100 */
    }       
/* 输出数组中每个元素的值 */
    for (j = 0; j < 10; j++ )    {
        printf("Element[%d] = %d\n",
j, n[j] );
    }
    return 0;
}

程序运行结果如下:


5)***数组:***数组声明的一般形式如下:

type name[size1][size2]...[sizeN];

例如,下面的声明创建了一个三维 5 . 10 . 4 整型数组:

int threedim[5][10][4];

6)二维数组

***数组最简单的形式是二维数组。一个二维数组,在本质上,是一个一维数组的列表。声明一个 x 行 y 列的二维整型数组,形式如下:

type arrayName [ x ][ y ];

其中,type可以是任意有效的 C 数据类型,arrayName是一个有效的 C 标识符。一个二维数组可以被认为是一个带有 x 行和 y 列的表格。因此,数组中的每个元素是使用形式为 a[ i , j ] 的元素名称来标识的,其中 a 是数组名称,i 和 j 是唯一标识 a 中每个元素的下标。

7)初始化二维数组:

***数组可以通过在括号内为每行指定值来进行初始化。下面是一个带有 3 行 4 列的数组。

int a[3][4] = { 

 {0, 1, 2, 3} ,   /*  初始化索引号为 0 的行 */

 {4, 5, 6, 7} ,   /*  初始化索引号为 1 的行 */

 {8, 9, 10, 11}   /*  初始化索引号为 2 的行 */

};

内部嵌套的括号是可选的,下面的初始化与上面是等同的:

int a[3][4] = {0,1,2,3,4,5,6,7,8,9,10,11};

8)访问二维数组元素:

二维数组中的元素是通过使用下标(即数组的行索引和列索引)来访问的。例如:

int val = a[2][3];

下面是使用嵌套循环来处理二维数组:

#include <stdio.h>
int main ()
{
   /* 一个带有 5 行 2 列的数组 */
   int a[5][2] = { {0,0}, {1,2}, {2,4},
{3,6},{4,8}};
   int i, j;
   /* 输出数组中每个元素的值 */
   for ( i = 0; i < 5; i++ )
   {
      for ( j = 0; j < 2; j++ )
      {
         printf("a[%d][%d] = %d\n",
i,j, a[i][j] );
      }
   }
   return 0;
}

运行结果如下:


9指针:

每一个变量都有一个内存位置,每一个内存位置都定义了可使用连字号(&)运算符访问的地址,它表示了在内存中的一个地址。如动态内存分配,没有指针是无法执行的。

指针是一个变量,其值为另一个变量的地址,即内存位置的直接地址,就像其他变量或常量一样,必须在使用指针存储其他变量地址之前,对其进行声明。指针变量声明的一般形式为:

type *var-name;

type是指针的基类型,它必须是一个有效的 C 数据类型,var-name是指针变量的名称。用来声明指针的星号 * 与乘法中使用的星号是相同的。但是,在这个语句中,星号是用来指定一个变量是指针。以下是有效的指针声明:

int    *ip;    /* 一个整型的指针 */

double *dp;    /* 一个 double 型的指针 */

float  *fp;    /* 一个浮点型的指针 */

char   *ch     /* 一个字符型的指针 */

所有指针的值的实际数据类型,不管是整型、浮点型、字符型,还是其他的数据类型,都是一样的,都是一个代表内存地址的十六进制数。不同数据类型的指针之间唯一的不同是,指针所指向的变量或常量的数据类型不同。

10)如何使用指针

使用指针时会频繁进行以下几个操作:定义一个指针变量、把变量地址赋值给指针、访问指针变量中可用地址的值。这些是通过使用一元运算符*来返回位于操作数所指定地址的变量的值。下面的实例涉及到了这些操作:

#include <stdio.h>
int
main ()
{
   int 
var = 20;   /* 实际变量的声明 */
   int 
*ip;        /* 指针变量的声明 */
   ip = &var;  /* 在指针变量中存储 var 的地址 */
   printf("Address of var variable: %x\n",
&var  );
   /* 在指针变量中存储的地址 */
   printf("Address stored in ip variable: %x\n",
ip );
   /* 使用指针访问值 */
   printf("Value of *ip variable: %d\n", *ip );
   return 0;
}

运行结果如下:

11指向整数的指针数组的声明:int *ptr[MAX];

12指向指针的指针:是一种多级间接寻址的形式,或者说是一个指针链。通常,一个指针包含一个变量的地址。当我们定义一个指向指针的指针时,第一个指针包含了第二个指针的地址,第二个指针指向包含实际值的位置。一个指向指针的指针变量必须如下声明,即在变量名前放置两个星号。例如 int **var;

是一个指向 int 类型指针的指针。

13)指针的算术运算

指针是一个用数值表示的地址。因此,可以对指针进行四种算术运算:++、--、+、-。

假设ptr是一个指向地址 1000 的整型指针,是一个 32 位的整数,我们对该指针执行下列的算术运算:ptr++,在执行完运算之后,ptr将指向位置 1004,因为 ptr 每增加一次,它都将指向下一个整数位置,即当前位置往后移 4 个字节。这个运算会在不影响内存位置中实际值的情况下,移动指针到下一个内存位置。如果ptr指向一个地址为 1000 的字符,上面的运算会导致指针指向位置 1001,因为下一个字符位置是在 1001。

14)递增一个指针

在程序中可以使用指针代替数组,因为变量指针可以递增,而数组不能递增,因为数组是一个常量指针。下面的程序递增变量指针,以便顺序访问数组中的每一个元素:

#include
<stdio.h>
const
int MAX = 3;
int
main ()
{
   int 
var[] = {10, 100, 200};
   int 
i, *ptr;
   /* 指针中的数组地址 */
   ptr = var;
   for ( i = 0; i < MAX; i++)
   {
      printf("Address of var[%d] =
%x\n", i, ptr );
      printf("Value of var[%d] = %d\n",
i, *ptr );
      /* 移动到下一个位置 */
      ptr++;
   }
   return 0;
}

运行结果如下:

15)递减一个指针

同样地,对指针进行递减运算,即把值减去其数据类型的字节数,如下所示:
#include
<stdio.h>
const
int MAX = 3;
int
main ()
{
   int 
var[] = {10, 100, 200};
   int 
i, *ptr;
   /* 指针中最后一个元素的地址 */
   ptr = &var[MAX-1];
   for ( i = MAX; i > 0; i--)
   {
      printf("Address of var[%d] =
%x\n", i, ptr );
      printf("Value of var[%d] =
%d\n", i, *ptr );
      /* 移动到下一个位置 */
      ptr--;
   }
   return 0;
}

运行结果如下:

16)指针的比较

指针可以用关系运算符进行比较,如 ==、< 和 >。如果 p1 和 p2 指向两个相关的变量,比如同一个数组中的不同元素,则可对 p1 和 p2 进行大小比较。

17)对形式参数使用const如果编写的函数需要修改数组,在声明数组参数时则不使用const,如果写的函数不用修改数组,那么在声明数组形参时最好使用const。

课后习题(编程练习):

10、
#include<stdio.h>
#define SIZE 4
void printf_ar(int ar[],int n);
void add_ar(int ar1[], int ar2[], int ar3[], int n);
int main(void)
{
    int ar1[SIZE]={2,4,5,8};
    int ar2[SIZE]={1,0,4,6};
    int ar3[SIZE];
    printf("the first array:");
    printf_ar(ar1,SIZE);
    printf("the second array:");
    printf_ar(ar2,SIZE);
    
    add_ar(ar1,ar2, ar3, SIZE);
     printf("the third array:");
    printf_ar(ar3,SIZE);
    return 0;
}
void printf_ar(int ar[],int n)
    {
    int i;
    for (i = 0; i < n; i++)
    printf("%d", ar[i]);
    printf("\n");
    }
 void add_ar(int ar1[], int ar2[], int ar3[], int n)
    {
     int i;
    for (i = 0; i < n; i++)
       ar3[i]=ar1[i]+ar2[i];
   }
运行结果: 

11、
#include<stdio.h> 
#define ROWS 3
#define COLS 5
void change_ar(int ar[][COLS], int n);
void print_ar(int ar[][COLS], int n);
int main(void)
{
    int array[ROWS][COLS] =
    {
        { 1, 3, 3, 6, 5 },
        { 3, 6, 3, 2, 8 },
        { 5, 6, 5, 2, 3 }
    };
    printf("original array:\n");
    print_ar(array, ROWS);
    change_ar(array, ROWS);
    printf("present array:\n");
    print_ar(array, ROWS);
    return 0;
}
void change_ar(int ar[][COLS], int n)
{
    for(int i=0;i<ROWS;i++)
        for(int j=0;j<COLS;j++)
          ar[i][j] = ar[i][j] * 2;
}
void print_ar(int ar[][COLS], int n)
{
    for (int i = 0; i < ROWS; i++)
    {
        for (int j = 0; j < COLS; j++)
            printf("%3d ", ar[i][j]);
        printf("\n");
    }
}
运行结果:

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务