回 帖 发 新 帖 刷新版面

主题:c语言入门很简单

内 容 简 介
本书是一本与众不同的C语言学习读物,是一本化繁为简,把“抽象”问题“具体”化,把复杂问题简单化的书。在本书中,避免出现云山雾罩、晦涩难懂的讲解,代之以轻松活泼、由浅入深的剖析,这必将使每一个阅读本书的读者少走弯路,快速上手,从而建立学习C程序设计的信心。
本书15章,分为5篇,从实用出发,由遇到的问题引出解决问题的方法来系统讲述C语言的各个特性及程序设计的基本方法。本书内容主要包括常量、变量、程序结构、数组、字符串、指针、结构体、共同体、枚举类型、函数、局部变量和全局变量、预处理命令和文件等一些非常重要的知识。通过阅读本书,读者可以在较短的时间内理解C程序设计的各个重要概念和知识点,为进一步学习打好基础。
本书配带1张DVD光盘,收录了本书重点内容的教学视频和涉及的源代码,光盘中还赠送了大量超值的C语言进阶视频。
本书最为适合没有基础的C语言入门新手阅读;对于有一定基础的读者,可通过本书进一步理解C语言的各个重要知识点和概念;对于大、中专院校的学生和培训班的学员,本书不失为一本好教材。

回复列表 (共40个回复)

31 楼

5.2.4  数组元素的引用
无论是数组使用初始化或者数组赋值的方式给数组中保存了数据,目的都是为了以后方便的去使用这些数据。那该如何去从数组中拿出想要的数据呢?这就是数组元素的引用问题了。
数组元素的引用是使用取数组元素运算:
数组名[下标]
这个运算就是相当于打开图5.4中小方格的盖子。
例如:
radius[1]
就是打开数组radius的第2个小格子的盖子。打开了小格子的盖子之后,就可以使用方格中的数据了。我们可以使用这个数据进行赋值运算、基本数学运算、关系运算、逻辑运算、输出等各种操作。当然,使用完数组中的数据还得将其放回去,以备下次使用。就像你上完课还得把书装进书包带回家一样。
可以使用下面的例子将数组中的元素求和,每加一个数,将和的结果输出。
#include<stdio.h>

int main()
{
int radius[5] = {1,2,3,4,5};
    int sum = 0;
    int i;

    for(i=0; i<5; i++)
    {
       sum += radius[i];            //把下表为i的数组元素加到sum上
       printf("sum: %d\n",sum);
    }

    return 0;
}
程序中使用了一个for循环。依次从下标0到4引用数组中的元素,然后使用加后赋值运算将每个数组运算和sum相加并赋值给sum,然后输出sum的值。

32 楼

5.3  二维数组
我们已经知道,数组是用来存储同一种类型的数据的。之前看到的都是用数组存储简单数据类型的数据。其实,数组还可以用来存储数组类型的数据,也就是数组中的元素是一个数组。
5.3.1  数组的维
数组中的元素既可以是简单数据类型的数据,也可以是数组类型的数据。这样数组元素就有了数组嵌套的关系了,数组元素可以是数组,数组元素中的数组的元素也可以是数组,…。依次类推就形成了不同嵌套深度的数组。这就好像我们送礼物的时候,小盒子套中盒子,中盒子再套大盒子一样:四个装糖果的小盒子放到一个中号盒子,然后5个中号的盒子,放到一个大号的盒子,最后把大盒子装到礼包里送给亲朋好友。
对于这样的嵌套深度,称之为数组的“维”。对于元素只是简单数据类型的数组,称之为一维数组。在上一节中介绍的,像下面这样的保存简单数据类型数据的数组都是一维数组。
int     radius[20];
float   result[100];
char   name[5];
当数组中的嵌套深度加一其维数就加一。如果一维数组中保存的元素不是简单数据类型数据,而是一维数组数据时,其嵌套深度就相当于加一了,称之为二维数组。类似的,如果二维数组的一维数组元素中的元素保存的不是简单数据类型,而是一维数组数据的话,就形成了三维数组。依次类推,可以形成四维数组、五维数组、…、n维数组

33 楼

5.3.2  二维数组表示和含义
在C语言中,一维数组和二维数组是较常用的数组类型。上小一节介绍的都是一维数组,这小节详细介绍二维数组。
按照数组的维的定义,二维数组就是用来保存一维数组数据的数组。其中的一维数组数据又是用来保存简单数据类型的数据的数组。我们已经知道一维数组的C语言表示,二维数组在C语言中又是如何表示的呢?其表示如下:
数据类型 数组名[表达式1][表达式2]
其中,“数据类型”、“数组名”、“表达式1”和“表达式2”的含义和一位数组C语言相应的表示含义是相同的。“数据类型”就是一种数据类型的关键字,如int、float、char等等。“数组名”是数组变量标识符。中括号中的“表达式”是一个具有常量值的表达式。
二维数组表示和一维数组表示唯一不同的就是,其表达式中有两个“[ ]”和两个“表达式”。这正是二维数组的特点,两个中括号和两个表达式分别表示二维数组的两个维。第一个中括号中的表达式表示的是二维数组中最多可以保存多少个一维数组元素,第二个中括号中的表达式表示二维数组中保存的每个一维数组最多可以保存多少个基本数据类型的数据。
例如,要保存m个一维数组元素,并且这m个一维数组中都可以保存n个整型数据。给这个二维数组取名为Matrix,这里的m和n都是常量或者常量表达式。就可以用下面的表示了:
int Matrix[m][n];
进行这样的声明定义之后,计算机就会按照图5.6所示的样子来保存数据了。在图5.6中纵向的大方格用来保存的是m个一维数组,大方格中的横向的小方格用来保存每个一维数组中的n个整型数据。

34 楼

5.3.3  二维数组的初始化
要想往二维数组中保存数据,类似于一维数组,也有两个方法:初始化和赋值。对于二维数组初始化的C语言表示,如下所示:
数据类型  数组名[表达式1][表达式2] = {数值, 数值, 数值, 数值, ..., 数值, 数值, 数值};

数据类型  数组名[表达式1][表达式2] = { {数值, ..., 数值},  {数值, ..., 数值},  …, {数值, ..., 数值}};
两个表达式是等效的,只不过第二个会比较直观点,因为外面的大括号中的每个小括号表示的就是二维数组中的每个一维数组元素。
另外,两个表达式中的“数值”的个数为最多为“表达式1”乘以“表达式2”个。如果不够的话,就相当于数组中某些地方没有保存数据,如果太多的话,编译器就会报错。可以写一个简单的二维数组的例子,如下所示:
#include<stdio.h>

int main()
{
    int Matrix[3][2] = {1,2,3,4,5,6,7,8};
}
其中,二维数组Matrix可以保存3x2 = 6个整型数值。但是,我们给其初始化了8个整型数值,当进行编译的时候就会出现图5.7所示的错误。
 
图5.7  数组初始化太多值
类似于一维数组,在对二维数组进行初始化的时候,初始化表示中的“表达式”的值可以省略不写,交给计算机自己根据所初始化的值,自己去判断数组可以保存多少个元素。但是,只能省略“表达式1”的值,不然的话计算机无法判断图5.6中的m和n的值,也就不知道你到底声明定义的是什么样的一个二维数组。
例如,下面就是一个正确的省略“表达式1”值的程序例子。
#include<stdio.h>

int main()
{
    int Matrix[][2] = {1,2,3,4,5,6,7,8};
}
经过这样的赋值以后,系统就知道数组Matrix中可以存4个一维数组,每个一维数组中有两个值,就像图5.8中那样。

35 楼

5.3.4  二维数组的赋值
当声明定义了一个二维数组之后,这个数组的样子如图5.6所示。总共有m*n个格子,可以使用初始化给每个格子中放入数据,也可以使用赋值给某个格子中放入数据。我们依然可以使用取数组元素表达式,来打开二维数组中的某个格子的盖子,然后使用赋值语句给这个打开盖子的格子中放入数据元素。
二维数组的取数组元素运算表达式如下所示:
数组名[下标1] [下标2]
在这个表达式中,“下标1”表示的是二维数组中存储的某个一维数组的标号,如图5.6中下方的0到m。“下标2”表示的是一维数组中某个格子的标号,如图5.6中右边的0到n。
按照二维数组的取数组元素运算表达式的表示形式,C语言给二维数组赋值的表示形式如下所示:
数组名[下标1] [下标2] = 数值;
这个赋值语句就把“数值”放到了由“下标1”和“下标2”所确定的数组中的一个格子中了。
例如,定义声明了一个二维数组Matrix。它可以保存4个一维数组元素,每个一维数组元素中可以保存2个整型的数据。C语言表示如下所示:
int  Matrix[4][2] ;
完成了这样的声明定义,计算机就给出了图5.9所示的8个格子。与一维数组相同,二维数组的两个下标都是从0开始的。
 
图5.9  Matrix二维数组
有了声明定义的Matrix数组以后,就可以使用赋值语句给图5.9中的格子放数据了。可以使用下面的代码给Matrix矩阵中每个元素赋值。
#include<stdio.h>

int main()
{
    int Matrix[4][2];
    int i,j;
    int value;

    value = 1;

    for(i=0; i<4; i++)                     //使i(“下标1”)不断循环加1
    {
       for(j=0; j<2; j++)                  //使j(”下标2”)不断循环加1
       {
           Matrix[i][j] = value++;          //用i作”下标1”,用j作”下标2”,给数组ij确定的格子中放入值
       }
    }

   return 0;
}
在这个程序中使用了两个for循环的嵌套。挨个打开数组Matrix中的每一个格子的盖子,然后使用二维数组赋值语句,往数组Matrix中放入了value值,每放入一次将value的值加1。程序执行完以后,数组Matrix的样子如图5.10所示。

36 楼

5.3.5  二维数组的引用
二维数的引用和一维数组类似,也是使用取数组元素运算表达式:
数组名[下标1] [下标2]
例如:
Matrix[1][1]
就相当于打开了数组Matrix中第2个一维数组元素中的第2个格子。打开之后,就可以使用这个格子中所保存的数据进行各种运算或者操作了。用完之后,格子中的数据是会被放回去的,以备下次再用。
可以使用下面的程序对二维数组的初始化、赋值,以及引用的各方面规则予以展示。
#include<stdio.h>

int main()
{
    //二维数组Matrix初始化
    int Matrix[4][2] = {1,2,3,4,5,6,7,8};
    int i,j;

    
    //Matrix数组引用,输出每个格子中的数值
    for(i=0; i<4; i++)
    {
       for(j=0; j<2; j++)
       {
           printf("%d ",Matrix[i][j]);
       }
       printf("\n");
    }

    //给Matrix数组中的每个元素赋值为0
    for(i=0; i<4; i++)
    {
       for(j=0; j<2; j++)
       {
           Matrix[i][j] = 0;
       }
    }

    //Matrix数组引用,输出每个格子中的数值
    for(i=0; i<4; i++)
    {
       for(j=0; j<2; j++)
       {
           printf("%d ",Matrix[i][j]);
       }
       printf("\n");
    }

   return 0;
}
这个程序中每个“//”注释之下的代码完成注释所描述的功能,依次为给数组Matrix初始化->Matrix引用输出->Matrix赋值->Matrix引用输出。Matrix的引用和赋值都是使用两个for循环组成的嵌套循环打开二维数组中的每个格子。
程序的输出如图5.11所示。由于程序的开始使用了二维数组的初始化给Matrix中元素依次初始化为1到8,所以图5.11中先输出1到8,之后程序使用了二维数组赋值将Matrix中元素都赋值为0,接下来输出8个0,如图5.11所示。

37 楼

5.4  多维数组
当数组的维数超过2的时候,就称这样的数组为多维数组。多维数组的C语言表示形式、取数组元素运算、初始化、赋值和引用等等规则和一维二维数组都是类似的,唯一不同的就是它的维数变多了。
对于多维数组,C语言中使用的比较少,一维二维对于基本的表示已经够用了。所以这里不再过于详细的讲解各个多维数组。只给出一个四维数组的例子,其中包含四维数组的表示形式、初始化、取数组元素运算、赋值、引用等方面。相信大家参照这个例子和一维二维数组的对应知识点,就可以得出其他多维数组的使用方式了。
下面就是使用四维数组Matrix进行操作的一个例子。展示了多维数组声明定义、初始化、取四维数组运算表示、赋值和引用等各个方面的C语言表示。
#include<stdio.h>

int main()
{
    //二维数组Matrix初始化
    int Matrix[1][2][3][3] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18};
    int i,j,k,l;


    //Matrix数组引用,输出每个格子中的数值
    for(i=0; i<1; i++)
    {
        for(j=0; j<2; j++)
        {
            for(k=0; k<3; k++)
            {
                for(l=0; l<3; l++)
                {
                   printf("%d ",Matrix[i][j][k][l]);
                }
                printf("\n");
            }
        }
    }

    //给Matrix数组中的每个元素赋值为
    for(i=0; i<1; i++)
    {
        for(j=0; j<2; j++)
        {
            for(k=0; k<3; k++)
            {
               for(l=0; l<3; l++)
               {
                 Matrix[i][j][k][l] = 0;
               }
            }
        }
    }

    //Matrix数组引用,输出每个格子中的数值
    for(i=0; i<1; i++)
    {
        for(j=0; j<2; j++)
        {
            for(k=0; k<3; k++)
            {
                for(l=0; l<3; l++)
                {
                 printf("%d ",Matrix[i][j][k][l]);
                }
                printf("\n");
            }
        }
    }

    return 0;
}
这个例子和本章中“二维数组的引用”一部分的例子实现的功能是一样的,结构也是类似的,唯一不同的就是将数组Matrix从二维变到四维了。展示了一个四维数组的定义声明、初始化、取四维数组运算表示、赋值和引用的各个方面。对于其他多维数组也是类似的,大家照猫画虎就可以了。
程序的输出如图5.12所示。图5.12中的输出也和“二维数组的引用”一部分图5.11类似。图5.12中,由于四维数组初始化,输出了1到18,之后由于四维数组赋值把每个元素的值变成0,输出了18个0。

38 楼

5.4  小结
在本章中接触了数组类型的概念,也是我们接触的第一种高级数据类型。本章的重点就是数组的相关概念和操作,难点就是各维数组的使用。在下一章,将介绍另一种特殊的数组——字符数组。在C语言中这种数组有个专门的称呼,叫字符串。

39 楼

5.5  习题
【题目1】一般情况下,数组的下标都是整数。如果使用一个小数或者一个字符作为数组的下标,会发生什么情况呢?写个程序试验一下!
【分析】在给数组元素赋值和引用数组元素的时候,都是要用到数组下标的,而且这个下标一般情况下都是整型数据。如果我们使用浮点型的话,如果你使用的编译器对于语言检测不是很严格的话,会将浮点型自动转换成整型;如果你使用的编译器对于语言检测比较严格的话会直接报错。如果使用字符型的话,由于字符型的ASCII码是整型数字,所以一般会使用ASCII的整型数字作为下标使用。你可以写段代码检验一下你使用的开发环境的C语言编译器到底是如何处理的。
【核心代码】
 int nums[10] = {0,1,2,3,4,5,6,7,8,9};

 printf(“%d\n”,nums[2.14]);
 printf(“%d\n”,nums[‘\0’]);

【题目2】写一段程序使用一维数组来代替一个int matrix[2][3]的二维数组。
【分析】二维数组的作用就是用来保存一维数组的,matrix[2][3]就是用来保存两个一维int型数组的,每个一维int型数组可以保存3个int型的数据。要想使用一维数组代替matrix[2][3],可以将matrix[2][3]保存的两个一维数组拿出来,分别声明定义,不必保存在matrix这个二维数组中。
【核心代码】
int matrix_2_1[3];
int matrix_2_2[3];

【题目3】计算一下今天是今年的第几天?
【分析】要计算今天是今年的第几天,先得知道今年是闰年还是平年,如果是平年的话二月只有28天,闰年的话就有29天了。判断是平年还是闰年以后,就可以使用一个二维数组来保存每个月的天数,这样方便计算。
【核心代码】
int year;
int  month;
int day;

int lp;
int i;
int  days = 0;
int day_tab[12][13] = { {0,31,28,31,30,31,30,31,31,30,31,30,31},
                                  {0,31,29,31,30,31,30,31,31,30,31,30,31}};


//判断是否是闰年
lp = year%4 == 0 && year%100 != 0 || year%400 == 0;
for(i= 1; i <month; i++)
{
     days += day_tab[lp][i];
}
days += day;


【题目4】魔术游戏:魔术师拿出一副牌中的13张黑桃,然后,告诉观众“我不看牌,只用数数就可以知道每张牌是什么”,他数1,翻开这张牌是黑桃A,他将黑桃A放在座子上。然后顺序从上到下数手上的余牌,第二次数1、2,将第一张牌放在这迭牌的下面,将二张牌翻开,是黑桃2,将黑桃2放在桌子上。第三次数1、2、3,将前两张牌放在这迭牌的下面,翻开第三张牌是黑桃3,将黑桃3放在桌子上。这样依次进行找出了13张牌。问魔术师手中的牌原始的次序是怎样的?
【分析】要解决这个问题,其实就是还原牌序,我们可以逆向思维:在桌子上方13个空盒子排成一圈,从1开始顺序编号,将黑桃A放在1号盒子中,从下一个空盒子开始对空的盒子计数,当数到第二个空盒子时,将黑桃2放在空盒子中,然后再从下一个空盒子开始对空盒子计数,顺序放入3、4、5…,直到放入全部13张牌。注意在计数时要跳过非空的盒子,只对空盒子计数。最后盒子中牌的顺序,就是魔术师手中原来牌的顺序,整个过程如图5.13所示。
 
图5.13  魔术牌排序
【核心代码】
int a[14]={0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int i, n, j =1;
for(i=1; i<13; i++)
{
       n =1;
       do
{
           if(j >13) j=1;    //从头开始
           if(a[j])  j ++;   //跳过已经有牌的位置
           else
          {
               if(n==i) a[j] = i;   //将牌放在合适的位置
               j++;
               n++;
}
} while(n<=i);
}

for(i=1; i<=13; i++)
   printf(“%d”,a[i]);

40 楼

有用的东西很多,是一本不错的好书。























SIGNATURE:------------------------------------
The devil knows many things because he is old.
[url=http://www.outletfrees.com/men-nike-free-run-2-c-35.html]nike free run 2[/url]   ,    [url=http://www.outletfrees.com/air-max-2012-men-c-49.html]air max 2012[/url]   ,    [url=http://www.outletfrees.com/nike-lunar-eclipse-2-men-c-65.html]nike lunareclipse 2[/url]

我来回复

您尚未登录,请登录后再回复。点此登录或注册