函数与数组.由于时间和精力有限,故不能像谭浩强谭老那样把C语言讲的细致入微, 但我想简单易懂的讲解对初学者来说还是有很大帮助的.
函数:
几乎所有的C语言教材都把函数部分单列一章, 可见函数在C语言中是十分重要的.当一位初学者试图编写一则上百行的程序时, 他会很快就被数不清的变量搞得晕头转向, 再看各条语句的逻辑关系, 恐怕连自己也看不懂了吧, 更不用说别人读你的程序了. 这时你所需要的就是把一个较大的程序分为若干个程序模块, 每一个模块实现一个特定的功能. 所有函数都是平行的, 即在定义函数时是互相独立的, 一个函数并不从属于另一个函数, 即函数不能嵌套定义. 就是这样一个一个平行关系的小模块, 将一个复杂的程序分生了多个简单的小程序. 这样做可以使程序的条理更加的清晰, 不仅方便了程序员的工作, 也便于其他人对程序的阅读.
从用户使用的角度看,函数有两种(以下援引谭老的话,不好意思,毕竟谭老的经验要更丰富嘛^0^):
(1).标准函数, 即库函数. 这是由系统提供的, 用户不必自己定义这些函数, 可以直接使用他们. 应该说明, 不同的C系统提供的库函数的数量和功能不同, 当然有一些基本的函数是共同的.
(2).用户自己定义的函数, 用以解决用户的专门需要.
从函数的形式看,函数分两类:
(1).无参函数.例如:
printstar();
print_message();
main()
{
printstar();
print_message();
printstar();
}
printstar()
{
printf("************n");
}
print_message()
{
printf("*green food*n");
}
运行结果如下:
(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/bianchengyuyan/)************
* green food *
************
其中printstar和print_message都是无参函数.在调用无参函数时,主调函数并不将数据传送给被调用函数.无参函数可带回或不带回函数值.
(2)有参函数. 在调用函数时,在主调函数与被调函数之间有数据传递. 也就是说主调函数可以将数据传递给被调函数使用, 被调函数的数据也可以传回来共主调函数使用. 例如:
#include
print_add();
main()
{
printf("the add is: %d",print_add());
}
print_add()
{
int a=1, b=2, c;
c=a+b;
return c;
}
运行结果如下:
(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/bianchengyuyan/)the add is: 3
以上我们对函数有了大致的了解, 下面我向大家介绍一下形式参数和实际参数.
首先从定义入手, 形式参数即在定义函数时函数后面括弧中的变量名. 而实际参数则是指在主调函数中调用一个函数时, 函数名后面括弧中的参数.(可以是一个表达式) 具体见下例:
#include
print_add(int, int);
main()
{
int a, b, c;
scanf("%d%d",&a,&b);
c=print_add(a,b);
printf("the add is :%d",c);//实际参数
}
print_add(int x, int y)//形式参数
{
int z;
z=x+y;
return(z);
}
需要注意的几点问题:
(1) 实参可以是常量,变量, 或表达式, 但必须要有确切的值.
(2) 在被定义的函数中, 必须指定形参的类型.
(3) 形参与实参的类型应相同或赋值兼容.
函数需要讲的东西还有很多, 这里只是一个简略的介绍. 还有很多的内容没有涉及到, 推荐大有时间可以看看谭浩强的书. 关于函数部分谭老的书要比老Delitel写的有条理的多.(也许是翻译工作做的不好)希望大家在看了上面的文章后, 能有所帮助. 有问题可以给我写信, 我的邮箱是:ck0243@sina.com.
数组:
数组在C语言中也是十分重要的一部分, 要展开讲大概说上几天也没完, 所以这里我们只从一些基础概念入手, 分析一些基本的问题.
数组即是一组相关的存储单元, 这些存储单元具有相同的名字和数据类型. 要引用数组的某个特定的存储单元(元素)需要说明数组名和该特定元素在数组中的序号. 见下例:
#include
main()
{
int i, c [3] ={1,2,3};//可以在声明数组时初始化数组
for(i=0;i=2;i++)
printf("%5d",c[i]);
}
运行结果如下:
(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/bianchengyuyan/)1 2 3
(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/bianchengyuyan/)数组的声明问题: 数组占用内存空间. 程序员声明了数组元素的类型和个数后计算机才能为该数组保留合适的内存数量. 如上例中的int c[3] 即告知计算机保留了3个整形元素的空间. 除了int 形外, 还可以把数组定义为其他数据类型, 如类型为char的数组可用来存储一个字符串. 在初始化数组时应注意, 初始化列表中的初始化值个数不能多于数组元素的个数.
预处理程序#define的用法: 先见下例:
#include
#define SIZE 3//符号常量
main()
{
int i, c [SIZE];
for(i=0;i=SIZE-1;i++)
{
c [i] =i+1;
printf("%5d",c[i]);
}
}
运行结果如下:
(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/bianchengyuyan/)1 2 3
(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/bianchengyuyan/)这个例子与上一道例题有相同的运行结果, 但用了预处理程序后, 可以方便的对程序进行修改. 例如需要打印1 2 3 4 5时, 只需将#define SIZE 3改为#define SIZE 5 即可实现. 要注意的是, 预处理程序不是C语言的一部分, 他只是对文本操作的程序, 所以万不可用分号结束. 还要注意符号常量名都用大写字母书写. 这种写法突出了程序中的符号常量, 同时也提醒程序员符号常量不是变量.
数组的排序: 数组的排序法有很多, 这里只介绍冒泡排序法. 见下例:
# include
# define SIZE 10
main()
{
int a [SIZE] = {2,6,4,8,10,12,89,68,45,37};
int i, pass, hold;
printf("Data items in oraginal ordern");
for(i=0; i=SIZE-1; i++)
printf("%4d", a[i]);
for(pass=1; pass=SIZE-1; pass++)
for(i=0; i=SIZE-2; i++)
if(a[i]a[i+1])
{
hold=a[i];
a[i]=a[i+1];
a[i+1]=hold;
}
printf("nData items in ascending ordern");
for(i=0; i=SIZE-1; i++)
printf("%4d", a[i]);
printf("n");
return 0;
}
运行结果如下:
(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/bianchengyuyan/)Data items int oraginal order
2 6 4 8 10 12 89 68 45 327
Data items in ascending order
2 4 6 8 10 12 45 68 89 327
由上例可见, 合理的利用数组可以简化许多问题。 这里就不一一介绍了, 有兴趣的同学可以参见H.M.Deitel的书, 其中还介绍了许多有趣的例题。 大家可以共同探讨研究。
关于多维数组的介绍, 我想以二维数组为例, 重点介绍一下二维数组的应用。 二维数组实际就是有两各下标的数组, 但要特别注意的是第一个下标表示元素所在的行, 第二个下标表示元素所在的列。(注意千万不可颠倒)和一维数组一样, 二维数组也能在声明时被初始化。 例如:
int a [2] [2] = {{1,2}, {3,4}};
如果某行没有足够的初始化值, 则该行中的剩余元素都被初始化为零, 这点要特别注意。对二维数组来说, 第一个下标有时是不必要的, 但一定要给出第二个下标, 编译器用第二个下标确定元素在内存中的位置。 幻方是二维数组应用的一个很典型的例子, 见下例:
#define N 5
void setmagic(int [][N]);
void outmagic(int [][N]);
main()
{
int s[N][N] = {0};
setmagic(s);
outmagic(s);
}
void setmagic(int s[][N])
{
int i, j, tryi, tryj, k;
k = 1;
i = 0;
j = N / 2;
s[i][j] = k;
k++;
while(k = N*N)
{
tryi = i - 1; tryj = j - 1;
if(tryi == -1) tryi += N;
if(tryj == -1) tryj += N;
if(s[tryi][tryj] != 0 || (tryi == -1 && tryj == -1))
i = i + 1;
else {
i = tryi; j = tryj;
}
s[i][j] = k;
k++;
}
}
void outmagic(int s[][N])
{
int i, j;
for(i = 0; i N; i++) {
for(j = 0; j N; j++)
printf("%4d", s[i][j]);
printf("n");
}
}
运行结果如下:
(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/bianchengyuyan/)15 8 1 24 17
16 14 7 5 23
22 20 13 6 4
3 21 19 12 10
9 2 25 18 11
关于二维数组的讨论就暂告一段落吧, 还是推荐大家如果要看理论知识可以看谭浩强的C语言设计第二版, 一些例题可以参H.M.Deitel的C程序设计教程。