• 《c程序设计(谭浩强)》读书笔记


    第1章~第3章

    1.关于scanf和printf的格式问题:

    1 scanf("%d,%d", &a, &b);
    View Code

    上面的语句分析:"%d,&d"指定输入的数据按照什么格式输入, &是地址符, &a的含义是“变量a的地址”,整个语句的作用是:从键盘读入两个整数,送到变量a和b的地址出,然后把两个整数分别赋予a和b。

    scanf(格式控制,地址列表);

    printf(格式控制,输出列表);

    a=12;b=34;

    printf("a=%5d b=%4d ",a,b); 

    输出:(口表示空格)

    口口口12

    口口34

    2.结构化程序设计方法:

    强调程序设计风格和程序结构的规范化,提倡清晰的结构。

    常用方法:

    (1)自顶向下、逐步细化:将问题求解由抽象逐步具体化的过程。

    (2)模块化设计:当程序复杂是非常有必要。根据程序的模块的功能将它划分为若干子模块,子模块再细分,这个过程是自顶向下的。程序中的子模块常用函数实现。

    (3)结构化编码:就是将设计好的一个结构化的算法用程序语言表示,用3个基本的结构语句(if-else,while,for语句)实现。

    3.指数形式的常量:

    12.34e-8:代表12.34*10^8  因为无法表示指数符号,所以用e或者E代表以10为地鼠的指数,注意e或E前面必须要有数字,且指数必须为整数。

    4.注意c中的转义字符及其作用:转义字符常以“”开头。

    5.标识符:数字、字母和下划线组合而成,不能以数字开头。

    6.不同类型数据间的混合运算:

     自动进行类型转换再运算。通常是向精度高的类型转换。

    7.强制类型转换:

    (类型名) 表达式

    例子:

    1 double x;
    2 int a;
    View Code

    a=(int)x ;

    把x强制类型转换为int型,得到一个临时的中间值,再把中间值赋给a;注意x的值和类型都没有变化。

     第4章 选择结构程序设计

     选择结构和条件判断:

     (1)if-else语句:实现两个分支的选择结构

     (2)switch语句:实现多分支的选择结构

    第5章 循环结构程序设计

    (1)while语句:

    (2)do-while语句:

    (3)for语句:

    用break语句跳出循环。

    用continue语句提前结束本次循环,进入下一次循环条件检查。

    第6章  数组

    1.定义一维数组:

    类型符  数组名[常量表达式];

    常量表达式中可以包含常量和符号常量,但不能包含变量。数组的大小一依赖于程序运行过程中变量的值。

    说明:可变长数组

    void fun(int n)

    {
        int a[n];  //合法,数组大小由形参n传入,函数调用过程n的大小不变,数组的长度是固定的。

    }

    2.定义二维数组:

    类型符  数组名[常量表达式1][常量表达式2];

    二维数组中元素的排列顺序是按行存放的,在内存中先存放第一行的元素,接着存放第二行的元素。。。

    3.字符数组:

    字符数组结束的标志:''

    char c[]={"china"};

    c h i n a

     

    4.字符串处理函数:

    包含在头文件中:

    #include<string.h>

    说明:库函数不是c语言本身的组成部分,而是c语言编译系统为方便用户使用而提供的公共函数。不同的编译系统可能有微小差别,使用时可以查询库函数手册。

    (1)puts函数:输出字符串的函数

    用法:puts(字符数组);

    char str[]={"china beijing"};

    puts(str);

    输出结果:

    china

    beijing

    (2)gets函数:输入字符串的函数

    用法:gets(字符数组);

    gets(str);  //str是已定义的数组

    (3)strcat函数:字符串连接函数

    用法:strcat(字符数组1,字符数组2);

    printf("%s",strcat(str1,str2));

    (4)strcpy和strncpy函数:字符串复制函数

    用法:

    strcpy(字符数组1,,字符数组2); 将字符数组2复制到字符数组1中去。

    strncpy(字符数组1,,字符数组2,n);将字符数组2中最前面的n个字符复制到字符数组1中,取代字符数组1中最前面的n个字符.

                                                  n不大于字符数组中原有字符个数(不包括结束标志符)。

    strcpy(str1,str2);

    strncpy(str1,str2,n);

    (5)strcmp函数:字符串比较函数

    strcmp(字符串1,字符串2);

    相等返回0,str1>str2返回正数,str1<str2返回负数

    strcmp(str1,str2);

    (6)strlen函数:测量字符串长度的函数

    strlen("china"); //值是5,不包含结束标志符

    (7)strlwr函数:将字符串中的大写字母转换为小写字母

           strupr函数:转换为大写

        strlwr(str);

        strupr(str);

     

    第7章  用函数实现模块化程序设计

    函数就是功能,每一个函数实现一个特定的功能,函数名应反映函数所代表的功能。

    1.函数定义:包括函数声明和函数实现

    类型名  函数名(形参列表)

    {

      函数体

    }

    (1)定义空函数:

    类型名 函数名()

    {   }

    在程序设计过程中,往往根据需要确定若干个模块,分别由一些函数实现。在第一阶段往往只涉及最基本的模块,在需要扩充的地方定义一个空函数,函数暂时没写好,只是先占一个位置,以后再用一个编写好的函数代替它。这样做,使程序结构清晰,可读性好,扩充功能也方便。

    (2)c程序设计人员有一个习惯,就是把全局变量的首字母大写。例如  float Max=0; 同名的全局变量会被局部变量 屏蔽。

    在不必要时尽量不用全局变量:原因有

    (1)空间消耗多

    (2)通用性降低

    (3)降低程序的可读性和清晰性,容易出错。

    2.静态局部变量(static局部变量):(注意:在c和c++中是下面的情况,但在java中不是这样的!!)

    静态局部变量的值在函数调用结束后不消失而继续保留原值,其占用的存储单元不释放。下一次再调用这个函数时,该变量已经有值(上一次函数调用结束时的值)。static变量在整个程序运行过程中都不释放,在函数调用结束后仍然存在,但只有创建它的函数能引用它,不能被其他函数引用。

    用法:若非必要,不要多用静态局部变量,因为调用时不知道当前static变量的值是什么,是否被修改过。

     

    3.寄存器变量(register变量):一般变量是存放在内存中的,存取速度较慢。如果需要频繁存取的,可以定义为寄存器变量,用关键字register声明。

    register int pi;

    使用:现在计算机优化的编译系统能识别使用频繁的变量,自动将它们放到寄存器中,不再需要程序设计者指定。

    4.变量有3种存储位置:

    (1)动态存储区:动态的局部变量

    (2)静态存储区:静态局部变量(即static变量),还有全局变量(即外部变量)

    (3)寄存器:register变量 

    5.用extern关键字做“外部变量声明”,扩展外部变量的作用域。 

    例子:

     1 int main()
     2 {
     3    extern int A,B,C;  //把外部变量A,B,C的作用域扩展到此处
     4    scanf("%d%d%d",7A,&B,&C);
     5    printf(max());
     6 }
     7 int A,B,C; //定义外部变量A,B,C
     8 int max()
     9 {
    10   int m=A>B?A:B;
    11   return m>C? m:C;
    12 }
    View Code

    将外部变量声明放在引用它的所有函数之前,可以避免使用extern关键字声明。

    上面的代码和下面的代码是等价的:

     1 int A,B,C; //定义外部变量A,B,C
     2 
     3 int main()
     4 {
     5    scanf("%d%d%d",7A,&B,&C);
     6     printf(max());
     7 }
     8 int max()
     9 {
    10   int m=A>B?A:B;
    11   return m>C? m:C;
    12 }
    View Code

     (1)将外部变量的作用域扩展到其他文件

    使用:其他文件要引用另一个文件中已定义的外部变量。

    1 //file1.c
    2 #include<stdio.h>
    3 int A ; //定义外部变量
    4 
    5 //file2.c
    6 extern A; //把file1文件中已定义的外部变量的作用域扩展到本文件
    View Code

    (2)将外部变量的作用域限制在本文件中

     1 //file1.c
     2 #include<stdio.h>
     3 static int A;  
     4 int main()
     5 {
     6 ......
     7 }
     8 
     9 //file2.c
    10 extern A;
    11 void fun(int n)
    12 {
    13    A=A+n;  //error,A的作用域被限制在文件file1中!
    14 }
    View Code

    使用注意:在程序设计过程中,每个人各自完成不同模块,可能使用同名的外部变量,只须在每个文件中定义外部变量时加上static即可!

    (3) static声明一个变量的作用:

     1.对局部变量用static声明,把它分配到静态存储区,在整个程序执行过程不释放。

     2.对外部变量用static声明,是把该外部变量的作用域限制在本文件中。

     (4)关于变量的声明和定义

           定义:建立存储空间的声明称为定义。

           声明:不需要建立存储空间的声明称为声明。

    (5)内部函数和外部函数

    1.内部函数:一个函数只能被本文件中的其他函数所调用,则这个函数称为内部函数。在定义内部函数时,用static修饰符修饰。

          static int fun();//函数fun只能被本文件调用

    用法:通常把只能由本文件使用的函数和外部变量放在文件的开头,前面都冠以static使之局部化,其他文件不能引用,提高程序可靠性。

    好处:内部函数又称为静态函数,使用内部函数,可以把函数的作用域只局限于所在文件。这样子在不同文件中即使具有同名的函数也互不干扰。在一个大工程中,在各人编写自己的文件模块时,使用内部函数,可以不必担心所用函数是否会与其他文件模块的函数同名。

    2.外部函数: 在定义函数时,在函数首部的最左端加挂念子extern修饰,在此函数是外部函数,可以供其他文件调用。省略extern则默认为外部函数。

    extern int  fun();//函数fun可以被其他文件调用。

     第8章  指针

    指针是很灵活但也很容易出错的工具,初学者不易学会,要谨慎使用~~

    1.指针指向内存地址。

    2.指针引用数组,也是指向数组的首地址,而不是整个数组。

    3.指针引用字符串,也是指向字符串第一个字符的地址。

    1 char *string;               //定义个char*型变量
    2 string="I love China!"; //把字符串第1个元素的地址赋给字符指针变量string
    3 
    4 //这里的string被定义为一个指针变量,基类是字符型,它只能指向一个字符型数据。

    如果再对指针变量赋值,如:

    1 string="I am a student";

    这时候string就指向了新的字符串。
    执行语句:

    1 printf("%s
    ",string); //输出字符串string

    输出结果如下:
    I am a student

    说明:

    通过字符数组名或者字符指针变量可以输出一个字符串,但对于一个数值型数组,只能逐个元素输出。

    数组名做函数参数,只是把数组的首地址传给形参,函数里修改值会影响传入数组的实参的值。

    第9章   结构体变量struct

     

     1.用关键字struct声明用户自定义的结构体类型。

     struct 结构体名

    {

      类型名 成员名1;

      类型名 成员名2; 

      类型名 成员名3;

      ...

    };

    先声明结构体类型,然后定义该类型的变量。

     使用方式1:

    1 struct student
    2 {
    3  int id;
    4   char name[8];
    5   char sex;
    6   int age;
    7 };
    8 student stu1,stu2;
    View Code


    使用方式2:

    1 struct student
    2 {
    3  int id;
    4   char name[8];
    5   char sex;
    6   int age;
    7 }stu1,stu2;
    View Code

    结构体类型也可以和基本数据类型一样,使用结构数组、结构指针等,是一种用户自定义的非常灵活的类型。


    2.用关键字union定义联合类型(共用体):

     1 union Data //声明共用体类型
     2 
     3 {
     4 
     5  int i;
     6 
     7  char c;
     8 
     9  float f;
    10 
    11 };
    12 
    13 Data a; //定义变量
    View Code

    联合类型的所有成员变量共享一块内存,内存长度取决于所有成员中占用内存最长的一个成员。比如上面的Data的实例变量a占用4个字节(float类型占用4个字节)。
    union在某个时刻只能有一个值,起作用的成员是最后一次被赋值的成员。

    不能引用实例变量名,只能用点运算符(.)操作成员。

     3.枚举类型用关键字enum声明:

    enum     Weekday  {sun,mon,tue,wed,thu,fri,sat};


     关键字   枚举变量名   0         1   2     3     4    5   6 (每一个元素默认代表一个整数,从0开始。不能对枚举元素赋值!)

    4.用typedef关键字声明新类型名。在c++里是typename。

     

     《c程序设计(第四版)学习辅导》第二部分  深入学习c程序设计

     

     第11章  预处理指令

     

     c程序中,在正式编译之前,要先对源码中一些“预处理指令”进行“预处理”,把预处理指令转换成相应的代码段。这项工作由c预处理器完成。

    1.c提供的预处理功能包括有以下三种:

    (1)宏定义

    (2)文件包含

    (3)条件编译

    这些指令以“#”开头,指令后没有分号。

    (1)宏定义

    ①宏定义: 

    #define 标识符  字符串

    #define PI 3.1415926

    说明:宏定义只是用宏名简单替代一个字符串,只是简单的置换,不做正确型检查。

     ②带参数的宏定义: 

    #define 宏名(参数表) 字符串

    #define s(a,b) a*b

    ......

    area=s(3,2); //用3*2代替s(3,2)

    带参数的宏定义展开置换:从左到右替换,如果宏定义中的字符不是参数字符,则保留。(例如上面的*号)。宏定义对空格非常敏感,一定要谨慎使用空格。

     使用宏的次数多时,宏展开后源代码会变长,函数调用不会使代码变长。

    宏替换不占用运行时间,只占用预处理时间,函数调用占用运行时间。

    一般用宏代表简短的表达式比较适合。

    (2)文件包含

    ①文件包含指令

    #include<...>     //标准方式,系统到存放c库函数头文件的目录中寻找包含的文件

    #include"..."       //系统先在用户当前目录中寻找包含的文件,如找不到,再按照标准方式寻找。

     (3)条件编译

    在满足某条件时对某一组语句进行编译,当条件不满足时则编译另一组语句。

    使用形式:(else语句可以缺省)

    ①:

    1 #ifdef 标识符    //如果指定的标识符已经被宏定义过
    2     程序段1
    3 #else
    4       程序段2
    5 #endif
    View Code

    ②:

    1 #ifndef 标识符  //指定的标识符没有被定义过
    2     程序段1
    3 #else
    4       程序段2
    5 #endif
    View Code

    ③:当指定的表达式值为真(非0)事就编译程序段1,否则编译程序段2

    1 #if 表达式
    2     程序段1
    3 #else
    4       程序段2
    5 #endif
    View Code


    第12章  位运算

    运算符 含义 运算规则 常用功能
    & 按位与 0&0=0,0&1=0,1&1=1 清零,取一个数中某些指定位,保留某些位
    | 按位或 0|0=0,0|1=1;1|1=1  
    ^ 按位异或 0^0=0,0^1=1;1^0=1;1^1=0 使特定位反转,交换两个值而不用临时变量
    ~ 按位取反 0变1,1变0  
    << 左移 二进制数向左移位,高位左移后溢出丢弃,低位补0  
    >> 右移 二进制数向右移位,高位补0,低位被丢弃  

     

     

     

     

     说明:

    1.位运算符中,只有~取反是单目运算符,其他都是双目运算符,需要2个操作数。

    2.参与位运算的对象只能是整型或者字符型的数据,不能为实型数据。

    3.不同长度的数据进行位运算,系统将二者按右端对齐,正数额左侧补满0,负数的左侧补满1,无符号整数则左侧补满0.

    4.还与一个位段的概念,就是把一个多字节数据分成多位段。

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

  • 相关阅读:
    SpringBoot HATEOAS用法简介
    犀函
    dubbo 相关面试题 有用(转)
    想使用消息队列,先考虑下这些问题!
    appium在Mac上环境搭建
    3. SOFAJRaft源码分析— 是如何进行选举的?
    Redis相关知识
    替代微信ipad协议(转)
    c#面试题(1)(转)
    例题6-5 Boxes in a line uVa12657
  • 原文地址:https://www.cnblogs.com/zhiaiyaya/p/3205479.html
Copyright © 2020-2023  润新知