zoukankan      html  css  js  c++  java
  • C语言程序设计-现代方法(笔记2)

    第七章 基本类型

    1、整数类型(7.1)

      有符号整数如果为正数或零,那么最左边的位(符号位)为0;如果是负数,则符号位为1.

      默认情况下,C语言中的整型变量都是有符号的。

      十进制常量包含0-9的数字,但不能以零开头;八进制常量只包含0-7,必须要以零开头;十六进制常量包含0-9数字和a-f字母,并且总以0x开头。

      为了强制编译器把常量作为长整数来处理,需在后面加字母L(或l),例如:15L,0x7fffL.

      为了指明是无符号常量,可以在常量后面加字母U(或u),例如:15U,0x7fffU.

      有符号整数溢出,程序行为是未定义的;无符号整数溢出,结果是有定义的:一般是0。

    2、浮点类型(7.2)

      C语言提供三种浮点类型:float(单精度浮点数),double(双精度浮点数),long double(扩展精度浮点数)。float和double对于大部分程序都够用。

      float精度为6个数字,double精度为15个数字。浮点常量必须包含小数点或指数,例如:57.0,5.7e+1。

    3、字符类型(7.3)

      在C中,字符和整数之间的关联非常强,字符常量事实上是int类型而不是char类型。

      有符号(signed)字符取值范围:-128-127;无符号(unsigned)字符取值范围:0-255。

      可移植性技巧:不要假设char类型默认为signed或unsigned。如果有区别,用signed char 或unsigned char代替char.。

      转义序列共有两种:字符转义序列和数字转义序列。字符转义序列,例如:a, , 等。数字转义序列,例如:x1b,33等。

      字符处理函数:小写字符转换成大写字母,ch = toupper(ch),需要包含#include <ctype.h>

      用scanf和printf函数也能读/写字符:

    do {
      scanf("%c",&ch);
    } while (ch != '
    ')

      getchar()返回的是一个int类型值,而不是char类型值。getchar()的惯用法。第一个用于检测是不是换行符,第二个用于检测空格。

    while (getchar() != '
    ')
        ;
    
    while ((ch = getchar()) == ' ')
        ;

    4、类型转换(7.4)

      当算术表达式或逻辑表达式中操作数的类型不相同时;当赋值运算符右侧表达式的类型和左侧变量的类型不匹配时;当函数调用中的实参类型与其对应的形参类型不匹配时;当return语句中表达式的类型和函数返回值的类型不匹配时。

      任一操作数的类型是浮点类型,需要将float提升为double;两个操作数类型都不是浮点类型,需要将int提升为unsigned int或long int。

      C语言会把赋值运算右边的表达式转换成左边变量的类型。

      强制类型转换:(float)dividend / divisior;将变量dividend强制转换为float,编译器也会将divisior转换为float类型。

    5、类型定义(7.5)

      使用typedef对类型进行定义,例如,typedef int Bool;

      类型定义更加易于理解,类型定义可以更好的编写可移植的程序。

      可以移植性的技巧:为了更大可移植性,可以考虑使用typedef定义新的整数类型名。

    6、sizeof运算符(7.6)

      sizeof (类型名),返回的值是一个无符号整数,代表存储类型名的值所需的字节数。

      sizeof也可以用于常量,变量和表达式,比如sizeof(i+j)

    第八章 数组  

    1、一维数组(8.1)

      数组是含有多个数据值的数据结构,并且每个数据值具有相同的数据类型。

      数组常见操作 

    for (i = 0; i < N; i++)
        a[i] = 0;                    //初始化数组
    
    for (i = 0; i < N; i++)
        scanf("%d", &a[i]);        //将数据读入数组
    
    for (i = 0; i < N; i++)
        sum += a[i];                 //对数组中元素求和

      数组初始化:int a[10] ={0};初始化完全为空是非法的,所以要在大括号内放一个0,其他值会默认初始化为0。

      C99中指定初始化:int a[15] = { [2] = 29, [9] = 7, [14] =48}

      可以用sizeof计算数组元素的大小,比如数组是a[10],用数组的大小除以数组元素的大小:sizeof(a) / sizeof(a[0])

      数组赋值除了用下面的方法,也可以用memcpy函数进行赋值,需要将头文件string.h包含,一般memcpy比较高效。

    for (i = 0; i < N; i++)
      a[i] = b[i];

    2、多维数组(8.2)

      C语言中的数组是按照行主序存储的,也就是从第0行开始,接着第1行,以此类推。

      多维数组不建议省略掉内层的花括号。

      常量数组(声明前加const)好处:首先,表明程序不会改变数组(方便别人阅读程序),然后,有助于编译器发现错误(告诉编译器不会修改)。

      变长数组优点:程序员不必再构造数组时给定一个长度,程序可以在执行时计算所需元素个数。

      变长数组限制:没有静态存储限制,没有初始化。

    第九章 函数

    1、函数的定义和调用(9.1)

      函数不能返回数组,但关于返回类型没有其他限制;返回类型是void类型说明函数没有返回值;省略返回类型C89默认为int类型,C99中是不合法的。

      如果返回类型很冗长,可以把返回类型单独放在一行,这很有用。

      C89中变量声明必须出现在语句之前;C99中,变量声明和语句可以混在一起,只要变量在第一次使用之前进行声明就行。

      没有时间完成函数,预留下空间,以待后续完成编写函数体。

      printf函数返回显示的字符个数。

      一个函数中可以声明与另一个函数中的变量同名的变量。因为这两个同名的变量在内存中地址不同,所以给其中一个变量赋新值不会影响另一个变量。

    2、函数调用(9.2-9.3)

      在调用前声明每个函数。

      在C语言中,实际参数是通过值传递额:调用函数时,计算出每个实际参数的值并且把它赋值给相应的形式参数。

      在函数执行过程中,对形式参数的改变不会影响实际参数的值,因为形式参数中包含的是实际参数值的副本(copy).

      一维数组型实际参数

    //sum_array函数原型
    int sum_array(int a[], int n);
    //sum_array函数定义
    int sum_array(int a[], int n)
    {
      int i, sum = 0;
      for (i = 0; i < n; i++)
        sum += a[i];
     
      return sum;      
    }

      如果return语句中表达式的类型和函数的返回类型不匹配,系统将会把表达式的类型隐式转换成返回类型。

    3、程序终止(9.5)

      return语句和exit函数之间差异:不管哪个函数调用exit函数都会导致程序终止,return语句仅当由main函数调用时才会导致程序终止。

      如果函数调用它本身,那么此函数就是递归的。

    第十章 程序结构

    1、局部变量(10.1)

      函数体内声明的变量成为该函数的局部变量。局部变量有自动存储期限和块作用域两种性质。

      局部变量的块作用域不能延伸到其他函数,只能在所属函数内部。

      静态局部变量有永久的存储单元(静态存储期限),在整个程序执行期间都会保留变量的值。

      形式参数拥有和局部变量一样的性质,即自动存储期限和块作用域。

    2、外部变量(10.2)

      外部变量是声明在任何函数体外的。外部变量有静态存储期限和文件作用域(从变量被声明的点开始一直到所在文件的末尾)。

      使用外部变量的缺点:1.容易造成程序的耦合;2.外部变量赋值错误,很难查找;3.不方便函数的复用。

      使用外部变量时,要确保它们都拥有有意义的名字。

    3、程序块和作用域(10.3-10.4)

      程序块包括:{多条声明 多条语句}。声明在程序块中的变量存储期限是自动的。

      当程序块内的声明命名一个标识符时,如果此标识符已经是可见的,新的升明明临时“隐藏”了旧的声明,标识符获得了新的含义。

    4、构建C程序(10.5)

    •   单个文件程序的构建:构建程序的编排顺序。
    •   #include指令;
    •   #define指令;
    •   类型定义(typedef int Bool;);
    •   外部变量的声明;
    •   除main函数之外的函数的原型;
    •   main函数的定义;
    •   其他函数的定义。

      建议:在每个函数定义前需要进行注释,已给出函数名、描述函数的目的、讨论每个形式参数的含义、返回值和副作用等信息。

    第十一章 指针

    1、指针变量(11.1)

      可执行程序由代码和数据两部分组成。程序中每个变量占有一个或多个字节内存,把第一个字节的地址称为是变量的地址。

      指针就是地址,而指针变量就是存储地址的变量。

      C语言要求每个指针变量只能指向一种特定类型的对象。

    2、取地址运算符和间接寻址运算符(11.2)

      使用&(取地址)运算符,可以找到变量的地址。使用*(间接寻址)运算符,可以获得指针所指向对象的内容。

      通过使用&运算符把某个变量的地址付给指针变量

    int i, *p;
    p = &i;

      一旦指针变量指向了对象,可以使用*(间接寻址)运算符访问存储在对象中的内容。

      只要p指向i,*p就是i的别名。*p不仅拥有和i相同的值,而且对*p的改变也会改变i的值。

    3、指针赋值(11.3-11.5)

      假设如下声明,对指针初始化后,p=&i。可以进行q=p,这是指针赋值,p和q都指向i。而*q = *p,是赋值语句,将p指向的值复制到q指向的对象中。

    int i, j, *p, *q;

      指针可以作为参数,传递地址给实际参数,实际参数和形参通过指针建立联系,改变形参内容即改变实参内容。

      函数可以返回指针,同时函数也可以返回指向外部变量或指向声明为static的局部变量的指针。

      永远不要返回指向局部变量的指针,返回后局部变量就不存在了。

    第十二章 指针和数组  

    1、指针的算术运算(12.1)

      当指针指向数组元素时,可以通过3中算术运算访问数组内的其他元素:指针加上整数,指针减去整数,两个指针相减。

      指针加上整数:p原先指向的元素向后j个位置。如果p指向元素a[i],则p+j指向a[i+j]。

      指针减去整数:p原先指向的元素向前j个位置。如果p指向数组元素a[i],则p-j指向a[i-j]。

      两个指针相减:指针之间距离。如果p指向a[i],q指向a[j],那么p-q就等于i-j。只有两个指针指向同一个数组时,相减才有意义。

    2、指针用于数组处理(12.2)

      *运算符和++运算符的组合:

      a[i++] = j;先将值存入一个数组元素中,然后前进到下一个元素。

      *p++ = j;类似于a[i++] = j。因为++优先级高于*,也可以看成*(p++) = j;因为p++的值是p,所以p只有在表达式计算出来后才可以自增。因此*(p++)的值是*p,即p指向当前对象的值。

      (*p)++:这个表达式返回p指向的对象值,然后对对象进行自增(p本身是不变化的)。

    表达式 含义
    *p++或*(p++)  
    (*p)++  
    *++p或*(++p)  
    ++*p或++(*p)  

      最频繁用到的是*p++。

    3、用数组名作为指针(12.3)

      可以用数组的名字作为指向数组第一个元素的指针。

      a[i]等价于*(a+i),可以把数组的取下标操作看成是指针算术运算的一种形式。  

    for (p = &a[0]; p < &a[N]; p++)
      sum += *p;
    // 简化循环后,用a替换&a[0],同时用a+N替换&a[N]
    for (p = a; p < a + N; p++)
      sum += *p;

      许多程序员认为把形式参数声明为*a更准确,因为它会提醒我们传递的仅仅是指针而不是数组的副本。实践中,*a比a[ ]更常用。

    4、指针和多维数组

      C语言按行主序存储二维数组。即,先是0行的元素,接着是1行的,以此类推。

            

      处理多维数组的行,处理多维数组的列,用多维数组名作为指针。

  • 相关阅读:
    nagios高可用性设置
    絮叨--接上篇
    絮叨一下最近的那些人那些事
    记录一个小有意思的改变路径的问题
    nagios-解决监控页面上的乱码
    唠叨唠叨最近
    nagios监控远程主机服务可能出现的问题
    nagios监控远程主机端口
    nagios监控linux设置
    絮叨絮叨看护机房之监控
  • 原文地址:https://www.cnblogs.com/chengabc/p/12076814.html
Copyright © 2011-2022 走看看