首页 > 代码库 > C程序设计语言阅读笔记

C程序设计语言阅读笔记

预处理器 -》.i  编译器 》.s 汇编器 》.o 链接器  --可执行文件  

------------------

math.h头文件包含各种数学函数的声明,所有函数都返回一个double类型的值

-------------------

文本流:是由多行字符构成的字符序列,而每行字符则由0个或多个字符组成,行末是一个换行符。标准库是每个输入输出流都能遵守这一模型

 

1.在c语言中,所有的函数的参数都是‘通过值’传递的,即传递给被调用函数的参数值存放在临时变量中,而不是存放在原来的变量中,传值调用的利大于弊,在被调用函数中,参数可以看作是便于初始化的局部变量,因此额外使用的变量更少,这样程序可以更紧凑简洁。当数组名用作参数时,传递给函数的值是数组起始元素的位置或地址,它并不复制数组元素本身,在被调用函数中,可以通过数组下标访问或修改数组元素的值

2.c语言提供了四种基本数据类型int char float double

float 4个字节,精确到6位小数

double 8个字节 ,精确到15位小数

任何数只要有小数点就是double类型 除非加了f,

 

宽字符类型:wchar_t=L‘a‘;(在标准头文件<stddef.h>,需要include)

布尔类型:

_Bool vaild=1;

bool valid=true;(需要#include<stdbool.h>)

 

3.双引号可起来的标志为一个字符串,而单引号仅标示一个字符 . 所以双引号的内容不能直接比较, char cn[8]="12345",cn1[8]="1234"; 要判断字符是否相等可以用=,如if(cn[1]==‘2‘); 要判断字符串是否相等则需用函数strcmp();

4.从技术角度看,字符串常量就是字符数组。字符串的内部表示使用一个空字符‘\0’,作为串的结尾,因此存储字符串的物理存储单元数比在双引号中的字符数多一个。标准库函数strlen(s)可以返回字符串的s的长度,但长度不包括‘\0’

5.枚举常量enum names(枚举标记){name(枚举器)=val,name},枚举为建立常量值与名字之间的关联提供了一种便利方式,

情景:希望变量存储一组肯能值的一个,例如一个变量存储一个表示当前月份的值。

每个枚举器都用唯一名称来指定,编译器会把int类型的整数值赋予每个名称,

枚举是一个整数类型,因为指定的枚举器对应不同的整数值,这些整数默认从0开始,每个枚举器都比它之前的枚举器大1

 

6.类型转换:当一个运算符的几个操作数类型不同时,就需要通过一些规则把他们转换为某种共同的类型。自动转换是指把‘比较窄的’操作数转换为‘比较宽的’操作数。显示转换要从低的类型朝高的类型转换

7.为了保证程序的可移植性,如果要在char类型的变量中存储非字符数据,最好制定signed和unsigned限定符

8.即使调用函数的参数为char或float类型,我们也把函数参数声明为int或double类型

8.在任何表达式中都可以使用强制类型转换的一元运算符强制进行显示类型转换 (类型名)表达式。强制类型转换

只是生成一个指定类型的n的值,n本身的值没有改变

9.在不需要使用任何具体值且仅需要递增变量的情况下,前缀和后缀的自增和自减运算符的效果相同

10.外部变量:如果两个函数必须共享某些数据,而这个两个函数互不调用对方,这种情况下最方便的方式是把这些共享数据定义为外部变量,而不是作为函数参数传递。

11.名字的作用域:指的是程序中可以使用该名字的部分。对于函数开头声明的自动变量来说,其作用域是声明该变量的函数,不同函数中声明的具有相同名字的各个局部变量之间没有任何关系。函数的参数也是这样,实际上可以就将它看作是局部变量

外部变量或函数的作用域从声明他的地方开始,到其所在的(待编译的)文件的末尾结束

如果要在外部变量的定义之前使用该变量,或者外部变量的定义与变量的使用不在同一个源文件中,则必须在相应的变量声明中强制性地使用关键字extern

外部变量的声明与定义严格区分,声明用于说明变量的属性(主要是变量的类型),定义除此之外还将引起存储器的分配

在一个源程序的所有源文件中,一个外部变量只能在某个文件中定义一次,而其他文件可以通过extern声明来访问它。外部变量的定义中必须指定数组的长度。但extern声明则不一定指定数组的长度

外部变量的初始化只能出现在其定义中


12.static声明限定外部变量与函数,可以将其后声明的对象的作用域限定为被编译源文件的剩余部分。通过static限定外部对象,可以达到隐藏外部对象的目的。外部的static声明通常用于变量,也可以用于函数。如果函数声明为static类型,则该函数除了对该函数声明所在的文件可见外,其他文件都无法访问。

static也可以用于声明内部变量。与自动变量不同的是不管其所在的函数是否调用,它一直存在。即static类型的内部变量是一种只能在某个特定函数中使用但一直占据存储空间的变量

13.寄存器变量register  声明告诉编译器,它所声明的变量在程序中使用频率较高,其思想是将redister变量放在机器的寄存器中,这样可以使程序更小、执行速度更快。但编译器可以忽略此项

register声明只适用于自动变量以及函数的形式参数p68

14.初始化:在不显式初始化的情况下,外部变量和静态变量都将初始化为0,而自动变量和寄存器变量的初值则没有定义(即初值为无用的信息)

定义标量变量时,可以在变量名后紧跟一个等好和一个表达式来初始化变量

对于外部变量与静态变量来说,初始化表达式必须是常量表达式,且只初始化一次(从概念上讲是在程序开始执行前进行初始化)

对于自动变量与寄存器变量,则在每次进入函数或程序块时都将被初始化

15.预处理器:从概念上讲,预处理器是编译过程中执行的第一个步骤

#include 用于在编译期间把指定文件的内容包含进当前文件中

形如#include "文件名" 或 #include <文件名>的行都将被替换为由文件名指定的文件的内容。如果文件名用引号引起来,则在源文件所在的位置查找该文件;如果该位置没有找到文件,或者如果文件名是用尖括号<>括起来的,则根据相应的规则查找该文件,这个规则同具体的实现有关。被包含的文件本身也可以包含#include指令

#define 名字 替换文本 这是一种简单的宏替换,后续所有出现名字记号的地方都将被替换为替换文本。#define指令定义的名字的作用域从其定义点开始,到被编译的源文件的末尾处结束。替换只对记号进行,对括在引号的字符串不起作用,替换文本可以是任意的。

宏定义也可以带参数盘p72,看起来像函数调用,但宏调用是直接将替换文本插入到代码中。形式参数的每次出现都将被替换成对应的实际参数(具有一定的缺陷,当参数表达式具有副作用时,以及没有适当使用括号)

如果对各种类型的参数的处理是一致 的,则可以将同一个宏定义应用于任何数据类型,而无需针对不同的数据类型需要定义不同的函数

条件包含:使用条件语句对预处理本身进行控制,这种条件语句的值实在预处理执行的过程中进行计算,这种方式为在编译过程中根据计算的条件值选择性地包含不同代码提供了一种手段

**指针与数组

指针:存放一个地址的一组存储单元

一元运算符& 取一个对象的地址,只能应用于内存中的对象,即变量与数组元素,不能作用于表达式 常量 或register类型的变量

一元运算符* 是间接寻址或间接引用运算符。作用于指针时,将访问指针所指向的对象。声明指针变量

每个指针都必须指向某种特定的数据类型(void类型的指针可以存放任何类型的指针,但不能间接引用其自身)

指针参数使得被调用函数能够访问和修改主调函数中的对象的值

数组:P79数组类型的变量或表达式的值是该数组第0个元素的地址,数组名所代表的就是该数组最开始的一个元素的地址。

一个通过数组和下标实现的表达式可等价地通过指针和偏移量实现

数组名一指针有一个不同之处,指针是一个变量,数组名不是变量(指针pa=a和pa++都是合法的,数组名a=pa和a++不合法)

当把一个数组名传递给一个函数时,实际上传递的是该数组的第一个元素的地址

在函数定义中,形式参数char s[]和char *s;是等价的。后者比前者更直观地表明了该参数是一个指针

将数组名传递给函数,函数可以根据情况判定是按照数组处理还是按照指针处理

也可以将指向子数组起始位置的指针传递给函数,这样就将数组的一部分传递给了函数p81

地址算数运算:

指针与整数之间不能相互转换,但0是唯一的例外:常量0可以赋值给指针,指针也可以和常量0进行比较,程序中常用符号常量NULL代替常量0,这样便于清晰地说明常量0是指针的一个特殊值

指针算数运算:比较(指针p和q指向同一个数组的成员比较才有意义)、和整数加减

指针运算具有一致性,所有指针元算都会自动考虑它所指向的对象的长度

p85

 

 

C程序设计语言阅读笔记