LinMao's Blog
学习科研记录与分享!

《C语言程序设计》

书名:《C语言程序设计》(第二版)

作者:刘明军 韩玫瑰 主编

出版社:电子工业出版社

之前的C语言学的不够系统,有很多知识盲区,这两天看了看《C语言程序设计》这本书,感觉这本书挺不错的,全书主要是以C语言的数据类型为主线展开讲的,把指针结构体这些以前认知很模糊的知识讲的很清楚,所以我以C语言数据类型为主要回顾全书。

C语言程序基础

基础知识

运行过程:

编辑(源代码)-> 编译(目标程序”.obj”)-> 连接(连接目标程序和库函数,解决函数调用)-> 执行(运行上一步的生成的程序)

  • C语言规定只要参与计算的值中有一个是实型,结果为double型。

stopselect条件运算符"? :"

格式化输入输出

scanf()如果格式控制部分只包含格式控制字符,则输入的时候数据之间可以有任意个空格;负责应该严格按格式控制部分格式输入。如:

常用格式:

格式字符 含义
%d(或%i) 带符号十进制数
%x(或%X) 无符号十六进制数(不输出前导符0x)
%o 无符号八进制数(不输出前导符0)
%u 无符号十进制数
%f 十进制实数(隐含输出6位小数)
%e(或%E) 指数形式输出实数(隐含输出6位小数)
%g(或%G) 自动以%f或%e输出宽度较短的实数,不输出无意义的0
%c 输出单个字符
%s 输出字符串
%% 输出%

变量的作用域和存储类型

  1. 作用域,变量的有效区域局部变量,在定义的局部有用(一对花括号之间)全局变量,所有函数都可以使用,声明在函数外部全局变量分为文件内全局变量和文件间全局变量,文件内部全局变量被文件中的函数共享;文件间全局变量是指将全局变量声明为extern,以供多个源程序文件访问,这样就将全局变量的作用域范围扩大了。
  2. 存储类型
    auto:C语言的默认存储类型
    register:寄存器变量,使用时不访存直接从寄存器中读取(循环控制变量可考虑)
    static:静态局部变量在程序执行之前创建
    extern:外部变量,常见于大项目中在头文件中声明常量和函数时用

预处理命令

  1. 宏定义

    宏定义行末不加分号,加了就连分号一起置换

    宏定义必须在函数意外,作用域为定义开始到源程序结束,如果提前结束使用#undef命令

  2. 文件包含(#include)可以将另一个源文件的全部内容都包含进来,它是一个编译预处理命令,编译预处理是在编译之前进行的。#include <>表示直接到指定的标准包含文件目录中寻找包含文件#include “”表示先在当前目录中找,若找不到再到标准包含文件目录中找,并且”“中可以加路径#include 预处理命令可以包含传递,a包含b,b包含c,则a包含c
  3. 条件编译,源程序在编译时有选择的编译,有三种形式:

函数

库函数

每个库函数对应一个头文件,头文件包含了所有函数的函数原型,以及这些函数所需的各种数据类型和常量定义,头文件一般命名为”.h”。通过预处理命令#include调用。

常用库函数:

math.h::数学函数

stdio.h:输入/输出函数

ctype.h:字符函数

string.h:字符串函数

time.h:时间函数

stdlib.h:其它函数,都是标准库函数都是不容易归到前面某一类中

malloc.h/mallo.h:动态内存分配函stopselect数如下:

函数原型与声明

C语言为保证一致性,在函数调用之前对函数进行声明,指出函数返回值类型和参数类型和个数。函数声明一般形式:

函数声明的位置:一种是在主调用函数中对被调用函数进行函数声明;另一种是在所有函数外部进行函数声明(推荐使用)。

数组

普通数组

一维数组的定义:

C语言编译系统不检查越界错误,所以要始终注意数组是不是越界了。

一维数组初始化:

多维数组和一维数组基本相似,二维数组在C语言中一般是按行优先存储的。

字符数组 VS 字符串

C语言中没有字符串变量,字符串存放在字符数组中。C语言规定用空操作符’\0’作为字符串结束标志,所以字符串最后一个字符为’\0’。程序在定义的时候会自动在字符串后加上’\0’,并且’\0’不计入字符串长度;但是’\0’会占用一个字符空间,所以在定义字符数组是大小应该是字符串长度+1。

初始化:

字符串的输入输出

用scanf()输入时,空格和回车都会作为字符串分隔符,所以输入的内容不能包括回车和空格;输入有空格字符串时可以使用gets()函数,它可以读取空格直到遇到回车为止;

用%s格式输入字符串时,输入项是字符数组名,而不是数组元素也不是数组名前夹取地址符;

用printf()的%s格式输出是输入项是字符数组名,不是数组元素名;例如:

常用字符串库函数(都包含在头文件string.h中)

复杂构造数据类型

结构体

同种类型的数据可以用数组来描述,在描述同一个对象中不同数据类型时可以用结构体数据类型。

定义

结构体类型在使用之前应先定义其类型结构,在定义该类型变量才能使用。

定义结构体类型变量方法

  1. 先定义结构体再定义结构体变量
  2. 在定义结构体类型的同时定义变量
  3. 直接定义结构体类型变量

结构体类型变量的引用

一般结构体不直接引用变量,而是引用某个成员变量。

成员变量引用方式:

结构体变量通常不能整体使用,不能整体输入输出,只能对单个成员变量引用。但结构体变量作为函数参数或者赋初始值时,可以整体使用。

共用体

有时候发现两个结构体类型中只有一个或者少数的成员不同,其他大部分成员都是一样的,这是时候如果使用两个结构体会出现大量的代码重复,所以提供一种新的结构类型——共用体类型。

共用体的定义和引用:

共用体和结构体定义方式类似,但是结构体的成员分别占据不同的内存单元,是同时存在的;而共用体的所有成员共同占用同一段内存,某一时刻只能有一个成员存在,所以使用共同体时注意存放的是那个成员。另外,结构体所占内存空间为所有成员类型所占内存空间之和,而共同体所占内存空间是占内存最多的那个成员变量类型所占内存大小。

枚举型

实际中有些问题数据的取值是有限的,比如星期,季节。C语言中,用枚举类型定义一些具有赋值范围的变量。枚举类型属于简单基本数据类型,但是用方法和结构体类型相似。

枚举类型定义和引用:

枚举类型的引用和普通变量的引用一样,但是要注意枚举类型不能取表中罗列意外的值。

说明:

  1. 枚举类型安常量处理,系统自动复制,比如枚举元素sun值为0,mon为1,以此类推。
  2. 接上一条,值可认为指定,如:
  3. 枚举值可以做判断比较

指针

C语言中变量一旦被定义系统就为其分配确定的地址,通过两种方式存取该值,一是通过变量名;二是通过变量地址。不同变量占用不同的内存单元,并且所占内存单元一定是连续的。在知道变量数据类型(数据占内存单元数)和数据首地址(指针)就可以完整存取变量,所以指针变量也有类型,只是该类型指的是指向数据的类型。

定义形式:

指针运算符:

*用在表达式中(而非定义中)表示的是指针运算符表示取地址中的内容;在变量前加符号&表示该变量的地址。

指针+数组

数组名表示数组在内存中的首地址,因此数组名可以理解为一个指针,不过数组名是一个指针常量,不能改变。可以用数组名赋值给指针变量,找到数组首地址从而找到数组每个元素。

指针变量的加法:

使用指针表示数组注意:

对于一个二维数组

指针+函数

一个例子说明(交换a,b值):

指针+字符串

188用字符指针处理字符串直接是指针+1指向下一个字符,指针处理连续的内存单元很方便。

当用%s格式输出时,会一直打印内存知道遇到’\0\’结束。

字符指针于字符数组的区别

  1. 字符数组一旦定义存储空间就是固定的可通过数组名访问;字符指针变量只是地址,改变后不指向原来的内容。
  2. 字符数组只能各个元素单独赋值;字符指针可以整体赋值。
  3. 字符数组定义的时候分配内存单元有确定的地址;字符指针定义没有确定的地址值,使用前应该先指定,如:

将字符串作为函数参数

将字符串从一个函数传到另一个函数,可以用传地址的方法,也就是用字符数组名或者直线该字符串的指针作为参数。在被调用的函数中,可以改变字符串的内容,在调用函数中可以得到改变的字符串。

指针+结构体

定义结构体的指针p以后,*p相当于结构体变量,引用成员变量是可以用"(*p).成员名"表示,也可以用"p->成员名"来表示。

引用结构体变量的成员变量三种方式:

对于指针始终要注意两点,第一是指针当前指的位置;第二是指针的类型。知道当前指的位置就知道指针在内存中的位置,知道指针的类型,就知道指针在内存中位置和接下来的几个单元的内容表示该指针表示的内容。(所以在此有感而发:说指针是指向地址的地址不准确,应该是指向地址的地址和连续单元的数量)例如:

文件系统

常用文件操作函数

赞(0) 打赏
转载请注明出处:LinMao's Blog(林茂的博客) » 《C语言程序设计》

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

LinMao's Blog(林茂的博客)

了解更多联系我们

觉得文章有用就打赏一下作者吧~

支付宝扫一扫打赏

微信扫一扫打赏