美文网首页
C语言学习笔记(三)

C语言学习笔记(三)

作者: 心田的雨滴 | 来源:发表于2020-03-04 23:24 被阅读0次

99. C语言中,一直用int类型的变量表示真/假值,C99针对这种类型的变量新增了_Bool类型。_Bool类型的变量只能存储1或0,其他的非零数值赋值给_Bool类型的变量,该变量会被设置为1。C99提供了stdbool.h头文件,该头文件让bool成为_Bool的别名,并把true和false分别定义为1和0的符号常量。

100. 逗号运算符并不局限于在for循环中使用,它有两个性值,首先,它保证了被它分隔的表达式从左往右求值。其次,整个逗号表达式的值是右侧项的值。

101. 缓存分为两种:完全缓冲I/O和行缓冲I/O。完全缓冲输入指的是当缓冲区被填满时才刷新缓冲区,通常出现在文件输入中。缓冲区的大小与系统有关,通常为512B或4196B。行缓冲I/O指的是在出现换行符时刷新缓冲区。键盘输入通常是行缓冲输入。

102. ANSI C和后续的C标准都规定输入是缓冲的,但最初K&R把这个决定权交给了编译器。

103. 从较低层面上说,C可以使用主机操作系统的基本文件工具直接处理文件,这种直接调用操作系统的函数,被称为底层I/O。但计算机系统各不相同,所以不可能为普通的底层I/O函数创建标准库。从较高层面上来说,C还可以通过标准I/O包来处理文件,此时,具体的C实现负责处理不同系统的差异。

104. 计算机操作系统要判断文件的开始和结束,检测文件结尾是第一种方式,一些系统使用内嵌的Ctrl+Z字符标记文件结尾。第二种方式则是存储文件大小的信息。C语言中,用getchar()和scanf()检测到文件结尾时,将返回一个特殊的值,即EOF(-1)。它定义在stdio.h文件中。

105. 如果没有声明函数的返回值类型,旧版本的C编译器会假定函数的返回值类型为int,这一惯例源于早期的绝大多函数的返回值都是int类型。而C99标准不再支持int类型函数这种假定设置。

106. 函数的前置声明可以放在主调函数外面,也可以放在主调函数里面。

107. 在ANSI C标准之前,声明函数的方案有缺陷,因为只需声明函数的返回类型,不用声明任何参数。

108. 只存储单个值的变量有时也成为标量变量。

109. 从ANSI C开始,支持用逗号分隔的值列表形式来初始化数组。不支持ANSI的编译器会将此种形式的初始化识别为语法错误,在数组的前边加上关键字static可解决此问题。

110. 当数组初始化列表中的值少于数组元素个数的时候,编译器会将剩余的元素都初始化为0。当初始化列表中的项数多于数组元素的个数时,编译时会出错。方括号里面的数字可以省略,此时编译器会根据初始化列表的元素个数自动匹配数组的大小。

111. C99新增了一个特性,指定初始化器。利用该特性可以初始化指定的数组元素。形式如下。int arr[6] = {[5] = 212};如果指定初始器后面有更多的值,那后面这些值将被用于初始化指定元素后面的元素。如果再次初始化指定的元素,那么最后的初始化会取代之前的初始化。

112. 编译器不会检查数组下标是否使用得当,在C标准中,使用越界下标的结果是未定义的。

113. 在C99标准之前,声明数组只能在方括号中使用整型常量表达式,所谓的常量表达式,是由整型常量构成的表达式。C99标准允许创建一种新型的数组,即变长数组。

114. 函数传参时,数组传递的其实是它的地址,可以在函数原型和函数定义声明形参的时候,使用关键字const。需要注意的是,此处利用const修饰的是形参,实际传参时,并不要求实参必须是const类型的。

115. const int *p和int * const p以及const int* const p。第一个指针表示它所指向的地址的变量值是不可以改变的。第二个代表指针指向的地址是不可改变的。第三个代表指针指向的地址以及地址所在的变量值,均不可以改变。

116. 用双引号括起来的内容称为字符串字面量,也叫做字符串常量。从ANSI C标准起,如果字符串字面量之间没有间隔,或者用空白字符分隔,C会将其视为串联起来的字符串字面量。如char greeting[50] = “Hello,and” “How are” “you” “today”;

117. 如果要在字符串内部使用双引号,必须在双引号前面加一个反斜杠。字符串常量属于静态存储类别,这说明在函数中使用字符串常量,该字符串只会被存储一次。用双引号括起来的内容被视为指向该字符串存储位置的指针。

118. 初始化数组把静态存储区的字符串拷贝到数组中,而初始化指针,只把字符串的地址拷贝给指针。某些编译器允许指向字符串常量的非const指针修改字符串,但是这种行为在C语言中属于未定义行为。因此,建议在把指针初始化为字符串常量的时候,使用const限定符。

119. int (*pz)[2]和int *pz[2]的区别。需要注意的是,[]运算符的优先级高于*。第一个表示指向指向一个内含两个元素的指针。第二个表示一个内含两个指针元素的数组,每个元素是指向一个int类型的指针。

120. C和C++中const的用法相似,但是不完全相同。区别在于,C++允许在声明数组的时候,使用const整数,而C不允许。另一点在于,C++的指针赋值检查更严格。C++不允许将const指针赋值给非const指针,但是C则允许如此,只不过这种行为是未定义的。

121. 函数的形参为多维数组时,第一个方括为空。空的方括号代表该形参是一个指针。例如void func(int pt[][4]);

122. C99新增了变长数组,允许使用变量表示数组的长度。但是变长数组有一些限制,首先变长数组必须是自动存储类型,意味着不能使用static或者extern存储类别说明符。其次,不能在声明中初始化。最终,C11将变长数组作为一个可选项,而非强制实现的特性。需要注意的是,变长数组不能改变数组大小,仅仅是创建数组时,可以用变量指定数组长度。

123. 声明一个带二维变长数组的函数,int func(int rows,int cols,int ar[rows][cols]);因为在变长数组里面需要使用到前两个参数,所以这两个参数必须在变长数组之前声明。C99/C11标准规定,可以省略函数原型里面的形参名,但是对于变长数组这种情况,必须用星号来代替省略的维度。Int func(int,int,int arr[*][*]);

124. 对于在声明数组时,使用const变量,C90标准不允许(也可能会允许,因为C实现可以扩大整形常量表达式的范围,但是这种代码很可能无法移植)。C99/C11标准允许在声明变长数组时,使用const变量,该数组的定义必须是声明在块中的自动存储类别数组。

125. 复合字面量一般指数组类型和结构类型的字面量形式。创建数组的复合字面量时,形式和初始化数组相似。前面用括号括起来的是类型名,例如(int [10]){10,20}。数组的复合字面量也可以省略数组大小,编译器会根据参数列表自动计算。复合字面量是匿名的。因此可有以下操作:int *p = (int[]){1,2,3,4};复合字面量是C99新增的特性。

相关文章

网友评论

      本文标题:C语言学习笔记(三)

      本文链接:https://www.haomeiwen.com/subject/xcqtchtx.html