博文

[068] 函数的返回值(2006-11-19 16:02:00)

摘要:《C程序设计第二版》(谭浩强)
<1> 函数的返回值是通过函数中的return语句获得的。return z 与 return(z)等价。 <2> 定义函数时应指明函数值的类型。C语言规定,凡不加类型说明的函数,一律自动按整形处理。 <3> 如果函数值的类型和return语句中表达式的值不一致,则以函数类型为准。对数值型数据,可以自动进行转换。即函数值决定返回值的类型。 <4> 如果被调用函数中没有return语句,并不带回一个确定的、用户所希望得到的函数值,但实际上,函数并不是不带回值,只是不带回有用的值,带回的是一个不确定的值。即如果将一个没有返回值的函数赋值绐一个变量是合法的,只是没有什么实际意义而已。(P149) <5> 为了明确表示“不带回值”,可以用“void”定义“无类型”(或“空类型”)。这样系统就能保证不使函数带回任何值,即禁止在调用函数中使用被调用函数的返回值。此时如果将函数赋值绐一个变量就是错误的。

......

阅读全文(3249) | 评论:3

[067] 关于形参与实参的说明(2006-11-19 15:41:00)

摘要:《C程序设计第二版》(谭浩强) <1> 在定义函数中指定的形参,在未出现函数调用时,它们并不占内存中的存储单元.只有在发生函数调用时,函数中形参才被分配内存单元.在调用结束后,形参所占的内存单元也被释放。

<2> 实参可以是常量、变量或表达式,如:max(3, a+b); 但要求它们有确定的值。在调用时将实参的值赋绐形参(如果形参是数组名,则传递的是数组首地址而不是数组的值。)

<3> 在被定义的函数中,必须指定形参的类型。

<4> 实参与形参的类型应相同或赋值兼容。类型不相同时,按赋值运算时的类型转换规则进行转换([064] 不同类型数据转换规则)。

<5> C语言规定,实参变量对形参变量的数据传递是“值传递”,即单向传递,只由实参传绐形参,而不能由形参传回来绐实参,这是和fortran不同的。在内存中,实参单元与形参单元是不同的单元。 调用函数时,绐形参分配内存单元,并将实参对应的值传递绐形参,调用结束后,形参单元被释放,实参单元仍保留并维持原值。因此在执行一个被调用函数时,形参的值如果发生改变,并不会改变主调用函数的实参的值。 ......

阅读全文(5169) | 评论:1

[066] 筛选法求素数(2006-11-18 22:39:00)

摘要:《C程序设计第二版》(谭浩强)
关于素数的判定,参见: [031] 判断m是否是素数。 所谓“筛选法”指的是“埃拉托色尼(Eratosthenes)筛法”。他是古希腊的著名数学家。他采取的方法是,在一张纸上写上1到100全部整数,然后逐个判断它们是否是素数,找出一个非素数,就把它挖掉,最后剩下的就是素数。 具体做法如下:
<1> 先将1挖掉(因为1不是素数)。
<2> 用2去除它后面的各个数,把能被2整除的数挖掉,即把2的倍数挖掉。
<3> 用3去除它后面的各数,把3的倍数挖掉。
<4> 分别用4、5…各数作为除数去除这些数以后的各数。这个过程一直进行到在除数后面的数已全被挖掉为止。例如找1~50的素数,要一直进行到除数为47为止(事实上,可以简化,如果需要找1~n范围内素数表,只需进行到除数为n^2(根号n),取其整数即可。例如对1~50,只需进行到将50^2作为除数即可。) 如上算法可表示为:
<1> 挖去1;
<2> 用刚才被挖去的数的下一个数p去除p后面各数,把p的倍数挖掉;
<3> 检查p是否小于n^2的整数部分(如果n=1000, 则检查p<31?),如果是,则返回(2)继续执行,否则就结束;
<4> 纸上剩下的数就是素数。 #include <stdio.h>
#include <math.h> int main(void)
{
    int i;
    int j;
    int a[101];                // 为直观表示,各元素与下标对应,0号元素不用     for (i = 1; i <= 100; i++) // 数组各元素赋值
        ......

阅读全文(9858) | 评论:9

[065] 赋值运算中的类型转换(2006-11-11 21:28:00)

摘要:    如果赋值运算符两侧的类型不一致,但都是数值型或字符型时,在赋值时要进行类型转换。 <1> 将实型数据(包括单、双精度)赋值绐整型变量时,舍弃实数的小数部分。如i为整型变量,执行“i=3.56”的结果是使i的值为3,在内存中以整数型式存储。 <2> 将整型数据赋绐单、双精度变量时,数值不变,但以浮点数形式存储到变量中,如将23赋值绐float变量f,即f=23,先将23转换成23.00000,再存储在f中。如将23赋绐double型变量d,即d=23,则将23补足有效位数字为23.00000000000000,然后以双精度浮点形式存储到d中。 <3> 将一个float型数据赋绐double变量时,数值不变,有效位数扩展到16位,在内存中以64位(bit)存储。将一个double型数据赋绐float变量时,截取其前面7位有效数字,存放到float变量的存储单元(32位)中。但应注意数值范围不能溢出。如:
float f;
double d = 123.456789e100;
f = d;
就出现溢出的错误。 ★ 为了验证是否真的会溢出,写如下程序试验: #include <stdio.h>
#include <string.h>
int main()
{
    float f;
    double d = 123.456789e100;
    f = d;
    printf("%f\n", f);
    return 0;
} 在TC(Win-TC)中运行会溢出,程序会自动退出,无任何显示( TC中欲使结果窗口停留,需在最后加一句getch(); )。而在VC中运行可以得到如下结果: =================================================================================
1234567890000000100000000000000......

阅读全文(5802) | 评论:0

[064] 不同类型数据转换规则(2006-11-10 22:55:00)

摘要:高↑  double ← float
  ㄧ    ↑
  ㄧ   long
  ㄧ    ↑
  ㄧ  unsigned
  ㄧ    ↑
低ㄧ   int ← char,short


向左箭头表示必定的转换,如字符数据必定先转换为整数,short型转换为int型,float型数据在运算时一律选转换成双精度型,以提高运算精度(即使是两个float型数据相加,也先都化成double型,然后再相加)。

纵向箭头表示当运算对象为不同类型时转换的方向。如int型与double型数据进行运算,先将int型的数据转换成double型,然后在两个同类型(double型)数据间进行运算,结果为double型。注意箭头方向只表示数据类型级别的高低,由低向高转换。比如一个int型数与一个double型数据运算,是直接将int型转成double型,而不是经过中间的unsigned和long后再转为double。

《C程序设计(第二版)》
......

阅读全文(4311) | 评论:0

[063] C语言整型变量所占内存字节数(2006-11-08 22:19:00)

摘要:    C标准没有具体规定各类整型数据所占内存字节数,只要求long型数据长度不短于int型,short型不长于int型。具体如何实现,由各计算机系统自行决定。如在微机上,int型和short都是16位,而long是32位。在VAX 750上,short是16位,而int和long都是32位,一般以一个机器字(word)存放一个int数据。前一阶段,微机的字长一般为16位,故以16位存放一个整数,但整数的范围太小,往往不够用,故将long型定为32位。而VAX的字长为32位,以32位存放一个整数,范围可达正负21亿,已足够用了,不必再将long型定为64位。所以将int和long都定为32位。通常的做法是:把long定为32位,把short定为16位,而int可以是16位,也可以是32位。这主要取决于机器字长。在微机上用long型可以得到大范围的整数,但同时会降低运算速度,因此除非不得已,不要随便使用long型。

ANSI标准定义的整数类型
┌───────────┬────┬─────────────────────┐
ㄧ        类型          ㄧ 比特数 ㄧ                 数值范围                 ㄧ
├───────────┼────┼─────────────────────┤
ㄧ [signed] int         ㄧ   16   ㄧ     -32768~32767   &......

阅读全文(9166) | 评论:1

[061] 一个字符串是否包含另一个字符串(2006-06-03 13:51:00)

摘要:《C程序设计》(夏宝岚) 习题6.13 检查一个字符串中是否包含另一个字符串

#include <stdio.h>
#include <string.h>
void main ()
{
    int i = 0;
    int j = 0;     int k = 0;    /* 偏移量&&累计已经匹配的长度 */     int flag = 0; /* 是否有匹配的字符串标志位, 1为真, 0为假 */     char m[50];
    char s[50];     printf("Mother string: ");
    gets(m);
    printf("Son    string: ");
    gets(s);
   
    for(i = 0; i < (int)strlen(m); i++)
    {
        for(j = 0; j < (int)strlen(s); j++)
        {
            if(s[j] == m[i + k]) /* 若匹配则记录已经匹配的个数k */
           &......

阅读全文(5764) | 评论:3

[060] 连接两个字符串(2006-06-02 22:26:00)

摘要:《C程序设计》(夏宝岚) 6.9 编写程序,实现将两个字符串连接起来(不允许用strcat函数)。

思路:定义三个数组a[], b[], c[],a.b用于存放将要连接的两个字符串,c用于保存a,b连接后的串。主要就是通过对字符串结束标志'\0'的判断分别将两串合并。第一次循环用控制变量i将串a复制到c中,第二次循环由于b串要从0开始,所以引入另一控制变量j由0开始,继续写入c时控制量i要延续第一次循环的值,最后将串c结束标志'\0'写入即可。如下:

#include <stdio.h>
void main ()
{
    int i = 0;
    int j = 0;     char a[50];
    char b[50];
    char c[50];     printf("First  string: ");
    gets(a);
    printf("Second string: ");
    gets(b);        while(a[i] != '\0') /* 将a串中内容copy到c中 */
    {
        c[i] = a[i];
        i++;
    }
    while(b[j] != '\0') /* 将b串中内容继续copy到c中 */
    {
        c[i] =......

阅读全文(5360) | 评论:4

[062] 杨辉三角的多种解法(2006-06-07 12:21:00)

摘要:《C程序设计》(夏宝岚) 习题6.5 编写程序,打印杨辉三角形(即二项式系数表)

在网上搜了一下关于杨辉三角的介绍,才知道原来这个数学三角并不是杨辉提出的,而是由一个叫做贾宪的人提出,大约在1050年他使用这个三角进行高次开方运算。南宋数学家杨辉在《详解九章算法》(1961年)记载并保存了“贾宪三角”,故称杨辉三角。杨辉在书中很确凿地载明:此图“出释锁算书,贾宪用此术”,所以后来都改称“贾宪三角”了。他所说的图叫做"开方作法本源图", 关于其详细介绍,见 贾宪三角一文。

杨辉三角的形式如下:

                              1
                           1     1
                        1     2     1
                     1     3 &nb......

阅读全文(7427) | 评论:10

[059] C语言中动态分配数组(一维)(2006-05-28 17:52:00)

摘要:    当初学Pascal的时候就想过这个问题:如何动态的定义及使用数组呢?记得一般用数组的时候都是先指定大小的。当时问老师,老师说是不可以的。后来又问了一位教C++的老师,他告诉我在C++里用new可以做到,一直不用C++,所以也不明白。今天在逛论坛时终于找到了C语言中的用法(看原贴):

    int *a;
    int N;
    scanf("%d", &N);
    a = (int *) malloc(N * sizeof(int));
    ....
    free(a);

    这样就动态分配了数组a[N]。数组的长度N可输入确定,也可用程序中的变量确定。但要注意程序结束后要用free()将其释放,否则内存会泄漏。 验证一下:

#include <stdio.h>
#include <stdlib.h>
int main()
{
    int i = 0;     int *a;
    int N;     printf("Input array length: ");
    scanf("%d", &N);
    printf("\n");     a = (int *) malloc(N * sizeof(int));
    
    for(i = 0; i < N; i++)
    {
        a[i......

阅读全文(12129) | 评论:10