[博主公告]

“linux大棚”是一个以Linux技术专题为主的博客。
本博客为了保证读者的浏览体验,决定不刊登任何广告信息。

专题

文章发布时间日历

September 2010
M T W T F S S
« Aug    
 12345
6789101112
13141516171819
20212223242526
27282930  
    <<返回主页

  • 25Oct

    真正深入学习C语言已经3年有余了。不过还是有很多知识点没有记下来,在此总结一下,也帮助C语言新手度过新手难关。

    如果你已经认真阅读过谭浩强C,那么复习如下知识大约需要1个小时,而且保证包括大部分易错知识点:)

    本篇是《帮你度过C语言新手阶段》系列的第二篇。

    第二十关:

    定义函数时,有传统方式和现代方式。

    现代方式:

    int max(int x,int y){

    }

    传统方式:

    int max(x,y)

    int x;

    int y;

    {

    }

    第二十一关:

    函数的定义和声明不是一回事。

    定义是对函数功能的确立,包括指定函数名、函数值类型、形参以及其类型、函数体等,它是一个完整的、独立的函数单位。

    声明的作用是把函数的名字、函数的类型以及形参的类型、个数和顺序通知编译系统,以便在调用该函数时系统按此进行对照检查。

    在函数的声明中完全可以不写形参名,而只写形参的类型。如:float add(float,float);

    旧版本的C语言中,函数声明可以只声明函数名和函数返回类型,如int add();

    如果在函数调用之前,没有对函数做声明,则编译系统会把第一次遇到的该函数形式作为函数的声明,并将函数返回类型默认为int。所以如下的程序,虽然没有事先声明max函数,但仍可以侥幸通过:

    int main()

    {

    int c=max(2,5);

    }

    max(int x,int y)

    {

    int z;

    z=x>y?x:y;

    return z;

    }

    可见,没有定义函数类型(即函数返回类型)的函数,都会默认为int型。

    上述程序能侥幸通过的原因是return z中的z是int型。如果z是其他任何类型,程序都会报错,即使是相兼容的short、long、char或unsigned int都不行!

    第二十二关:

    形参数组可以不指定大小,且在形参中int a[]和int a[131212]和int *a是等价的!

    形参多维数组的话,只能省略第一维的数组,其他维必须按照正确的值来填写。

    第二十三关:

    用户存储空间包括:

    (1)程序区

    (2)静态存储区

    (3)动态存储区

    全局变量全部放在静态存储区。

    动态存储区存放以下数据:

    1 函数形参

    2 自动变量,即未使用static声明的局部变量

    3 函数调用的现场保存和返回地址

    在C语言中,每个变量有两个属性:

    1 数据类型

    2 数据存储类型

    第二十四关:

    函数中的局部变量,如果不专门声明为static存储类型,则默认都为auto存储类别,都会被分配到动态存储区。auto是一个默认关键字。即int a;等价于auto int a;

    静态存储类别的变量,被分配在静态存储区,在程序整个运行期间都不释放。静态局部变量在编译时赋初值,且只赋初值一次,如果用户不指定,则为0。(auto类型变量的话,如果用户不指定初值,则初值是一个不确定的值)

    第二十五关:

    为了提高效率,C语言允许将局部变量放在CPU中的寄存器里,这种变量叫做“寄存器变量”,如register int a;

    只有局部自动变量和形参变量可以作为寄存器变量。

    局部静态变量不能作为寄存器变量。

    第二十六关:

    extern用于声明外部变量,如extern char a,b;

    注意,除非引用的外部变量是int型,否则必须写上数据类型,而且和外部变量的数据类型必须完全一致。

    第二十七关:

    使用#define定义的宏,可以用#undef来取消。

    如#define G 9.8,可以用如下命令取消:

    #undef G

    C程序中,用双引号括起来的部分,不会被宏所代替。

    定义计算圆面积的宏,应该注意要加上括号,即:

    #define PI 3.14

    #define S(r) PI*(r)*(r)

    宏名是无类型的,而且它的参数也是没有类型的。

    宏替换不占运行时间,只占编译时间。

    第二十八关:

    头文件,使用.h后缀只是为了表明文件性质。所以,即使没有.h也是没问题的。

    头文件里应该可以函数原型、宏定义、结构体类型定义以及全局变量定义。

    第二十九关:

    &和*的优先级相同,且结合性是自右至左。(单目运算符的结合性是右结合)

    *pointer++,由于++和*为同一优先级,而结合性又是自右至左,所以相当与*(pointer++)

    第三十关:

    使用指针来引用数组,可以提高目标程序质量(占内存少,运行速度快)。

    main()

    {

    int a[10];

    int *p,i;

    for(i=0;i<10;i++)

    scanf(“%d”,&a[i]);

    printf(“\n”);

    for(p=a;p<(a+10);p++)

    printf(“%d”,*p);

    }

    此程序会提高程序运行效率,因为像p++这样的指针操作是比较快的。

    数据名是数组首元素的地址,它是一个指针常量。它的值在程序运行期间是不变的。

    第三十一关:

    当在形参中要引用一个数组时,往往C语言专业人员喜欢用指针变量做形参。如,专业人员

    更喜欢f(int *arr,int n);

    不太喜欢f(int arr[], int n);

    第三十二关:

    对于int a[3][4]={{1,3,5,7},{9,11,13,15},{17,19,21,23}};

    a[0],a[1],a[2],每一个元素又是一个一维数组。

    a+1代表第一行的首地址,而a+1就代表第二行的首地址。

    *(a[i]+j)和*(*(a+i)+j)是二维数组元素a[i][j]的值。

    a和a[0]的值虽然相同,但其指针类型不同,a指向一维数组,a[0]指向a[0][0].

    第三十三关:

    int (*p)[4],p是一个指针变量,它指向包含4个整型元素的一维数组。注意*p两侧的括号不能缺少,因为[]的优先级高于*,所以如果写成*p[4],那就变成了*(p[4]),这个表示一个含有4个元素的一维数组,其中每个元素都是一个指针变量。

    第三十四关:

    用字符指针做形参来实现字符串的复制:

    void copy_string(char *from, char *to)

    {

    for(;*from!=’\0′;from++,to++) *to=*from;

    *to=’\0′;

    }

    此代码可以改进为:

    void copy_string(char *from,char *to)

    {

    while((*to++=*from++)!=’\0′);

    }

    此代码还可以改进,由于’\0′可以用0代替,且条件里0即代表假,所以代码可修改为:

    void copy_string(char *from,char *to)

    {

    while(*to++=*from++);

    }

    对于C语言熟练之后,这种形式的使用是非常多的,读者应该逐渐熟悉它,掌握它。

    over~

    我猜您对这些文章感兴趣:

    Posted by rocrocket @ 9:42 am

    Tags: , , ,

    1,037人阅读过了这篇文章。

    如果您还满意我的文章,请您订阅我的博客。点击“我要订阅”即可。谢谢:)

  • <<返回主页

One Response

WP_Cloudy

Leave a Comment

Please note: Comment moderation is enabled and may delay your comment. There is no need to resubmit your comment.