C Primer Plus Notes 09

1、

puts( ) 函数也属于 stdio.h 系列的输入/输出函数。puts( ) 函数只显示字符串,而且自动在显示的字符串末尾加上换行符。

2、

如果字符串字面量之间没有间隔,或者用空白符分隔,C 会将其视为串联起来的字符串字面量。

eg:

char greeting[50] = "Hello, and" " how are" " you"

" today!";

跟下面字符串等价

char greeting[50] = "Hello, and how are you today!";

3、

如果要在字符串内部使用双引号(""),必须在双引号前面加上一个反斜杠(\).

4、

在指定数组大小时,要确保数组的元素个数至少比字符串长度多1(为了容纳空字符 '\0' )。所有未被使用的元素都被自动初始化为 0 ( 0 指的是 char 形式的空字符,不是数字 0 )。

5、

字符串常量属于静态储存类别,用双引号括起来的内容被视为指向该字符串储存位置的指针。这类似于把数组名作为指向该数组位置的指针。

char car[10] = "Tata";

car == &car[0] 、 *car == 'T' 、 *( car + 1 ) == 'a'

下面两个声明等价:

const char *pt1 = "Something is pointing at me.";

const char ar1[ ] = "Something is pointing at me.";

数组形式( ar1[] )在计算机的内存中分配为一个内含 29 个元素的数组(每个元素对应一个字符,还加上一个末尾的空字符 '\0'),每个元素被初始化为字符串字面量对应的字符。通常,字符串都作为可执行文件的一部分储存在数据段中。当把程序载入内存时,也载入程序的字符串。字符串储存在静态存储区( static memory )中。但是,程序在开始运行时才会为该数组分配内存。此时,才将字符串拷贝到数组中。注意,此时字符串有两个副本。一个是在静态内存中的字符串字面量,另一个是储存在 ar1 数组中的字符串。此后,编译器便把数组名 ar1 识别为该数组首元素地址( &ar1[0] )的别名。在数组形式中,ar1 是地址常量。不能更改 ar1 ,如果改变了 ar1,则意味着改变了数组的存储位置(即地址)。可以进行类似 ar1 + 1 的操作,标识数组的下一个元素。但是不允许进行 ++ar1 这样的操作。递增运算符只能用于变量名前,不能用于常量。

指针形式( *pt1 ) 也使得编译器为字符串在静态存储区预留 29 个元素的空间。另外,一旦开始执行程序,它会为指针变量 pt1 留出一个储存位置,并把字符串的地址储存在指针变量中。该变量最初指向该字符串的首字符,但是它的值可以改变。因此,可以使用递增运算符。例如, ++pt1 将指向第二个字符( o )。

6、

fgets( ) 函数的第二个参数指明了读入字符的最大数量。如果该参数的值是 n , 那么 fgets( ) 将读入

n - 1 个字符,或者读到遇到的第一个换行符为止。( fgets( ) 读到一个换行符,会把它储存在字符串中。这与 gets( ) 不同, gets( ) 会丢弃换行符。)fgets( ) 函数的第三个参数指明要读入的文件。如果读入从键盘输入的数据,则以 stdin (标准输入)作为参数,该标识符定义在 stdio.h 中。

puts( ) 函数会在待输出字符串末尾添加一个换行符,而 fputs( ) 不会这样做。

7、

系统使用缓冲的 I/O 。这意味着用户在按下 Return 键之前,输入都被储存在临时存储区(缓冲区)中。按下 Return 键就在输入中增加了一个换行符,并把整行输入发送给 fgets( ) 。 对于输出, fputs( )把字符发送给另一个缓冲区,当发送换行符时,缓冲区中的内容被发送至屏幕上。

8、

空字符(或 '\0')是用于标记 C 字符串末尾的字符,其对应字符编码是 0 。由于其他字符的编码不可能是0,所以不可能是字符串的一部分。空指针(或 NULL)有一个值,该值不会与任何数据的有效地址对应。空字符是整数类型,而空指针是指针类型。他们都可以用数值0来表示。但是两者是不同类型的0.另外,空字符是一个字符,占 1 字节;而空指针是一个地址,通常占 4 字节。

9、

scanf( ) 更像是"获取单词"函数,而不是"获取字符串"函数;scanf( )函数有两种方法确定输入结束。无论哪种方法,都是从第1个非空白字符作为字符串的开始。如果使用%s转换说明,以下一个空白字符(空行、空格、制表符或换行符)作为字符串的结束(字符串不包括空白字符)。如果指定了字段宽度,如%10s,那么scanf( )将读取10个字符或读到第1个空白字符停止(先满足的条件即是结束输入的条件);scanf( )函数返回一个整数值,该值等于scanf( )成功读取的项数或EOF(读到文件结尾时返回EOF)。

10、

①puts( )函数在遇到空字符时就停止输出,所以必须确保打印的字符串中有空字符。

②fputs( )函数的第2个参数指明要写入数据的文件。如果打印在显示器上,可以用定义在 stdio.h 中的 stdout(标准输出)作为该参数。fputs( )函数不会在输出的末尾添加换行符。

/*

gets( )丢弃输入中的换行符,但是puts( )在输出中添加换行符。

fgets( )保留输入中的换行符,fputs( )不在输出中添加换行符。

*/

11、

eg:

printf("I count %d characters.\n", put2("I never would cry old chairs to mend."));

注意:使用 printf( ) 打印 put2( ) 的值,为了获得 put2( ) 的返回值,计算机必须先执行 put2( ) ,因此在打印字符数之前先打印了传递给 put2( ) 函数的字符串。

12、

①strlen函数:

原型:size_t strlen(const char *str);

功能:计算字符串的长度,即从指定的起始地址开始直到遇到第一个空字符('\0')为止的字符个数(不包括空字符本身)。

注意:strlen只能用于以空字符结尾的字符串(即C风格字符串)。如果字符串没有以'\0'结尾,则strlen可能会继续向后查找直到遇到'\0',这可能导致未定义行为(如访问越界)。

②sizeof运算符:

不是函数,而是一个运算符,在编译时计算结果。

功能:计算类型或变量所占内存的字节数。

当用于数组时,sizeof返回整个数组所占的字节数。

当用于指针时,sizeof返回指针本身所占的字节数(通常为4或8,取决于系统)。

当用于字符串字面量时,sizeof会包括末尾的空字符。

13、

①strcmp( ) 函数比较储存在不同大小数组中的字符串。(第1个空字符前面的部分)

②strcmp() 的返回值表示两个字符串的比较结果:

负数 :str1 小于 str2(从不同的字符位置比较 ACSCII 码的值)

零 :str1 等于 str2

正数 :str1 大于 str2(从不同的字符位置比较 ACSCII 码的值)

14、

strncmp( ) 函数在比较两个字符串时,可以比较到字符不同的地方,也可以只比较第3个参数指定的字符数。

15、

①strcpy( )接受两个字符串指针作为参数,可以把指向源字符串的第2个指针声明为指针、数组名或字符串常量;而指向源字符串副本的第1个指针应指向一个数据对象(如,数组),且对象有足够的空间储存源字符串的副本。

②strcpy( )函数的两个属性:

第一,strcpy( )的返回类型是char *,该函数返回的是第1个参数的值,即一个字符的地址。

第二,第1个参数不必指向数组的开始。

16、

strncpy(target, source, n); 把 source 中的 n 个字符或空字符之前的字符(先满足哪个条件就拷贝到何处)拷贝至 target 中。因此,如果 source 中的字符数小于 n , 则拷贝整个字符串,包括空字符。但是,strncpy( ) 拷贝字符串的长度不会超过 n ,如果拷贝到第 n 个字符时还未拷贝完整个源字符串,就不会拷贝空字符。所以拷贝的副本中不一定有空字符。

注:该函数不会拷贝空字符后面的字符。

17、

sprintf( )函数声明在 stdio.h 中,该函数与 printf( ) 函数类似,但是它是把数据写入字符串,而不是打印在显示器上。该函数可以把多个元素组合成一个字符串。sprintf( ) 的第 1 个参数是目标字符串的地址。其余参数和 printf( ) 相同,即格式字符串和待写入项的列表。

18、

char *strncat( char *restrict s1, const char *restrict s2, size_t n );

该函数把 s2 字符串中的 n 个字符拷贝至 s1 字符串末尾。s2 字符串的第 1 个字符将覆盖 s1 字符串末尾的空字符。不会拷贝 s2 字符串中的空字符和其后的字符,并在拷贝字符的末尾添加一个空字符。该函数返回 s1 。

19、

char *strchr( const char *s, int c );

如果 s 字符串中包含 c 字符,该函数返回指向 s 字符串首次出现的 c 字符的指针(末尾的空字符也是字符串的一部分,所以在查找范围内);如果在字符串 s 中未找到 c 字符,该函数则返回空指针。

20、

char *strpbrk( const char *s1, const char *s2 );

如果 s1 字符中包含 s2 字符串中的任意字符,该函数返回指向 s1 字符串首位置的指针;如果在 s1 字符串中未找到任何 s2 字符串中的字符,则返回空字符。

21、

char *strrchr( const char *s, int c );

该函数返回 s 字符串中 c 字符的最后一次出现的位置(末尾的空字符也是字符串的一部分,所以在查找范围内)。如果未找到 c 字符,则返回空指针。

22、

char *strstr( const char *s1, const char *s2 );

该函数返回指向 s1 字符串中 s2 字符串出现的首位置。如果在 s1 中没有找到 s2,则返回空指针。

23、

size_t strlen( const char *s );

该函数返回 s 字符串中的字符数,不包括末尾的空字符。

相关推荐
q***25121 小时前
java进阶1——JVM
java·开发语言·jvm
望眼欲穿的程序猿21 小时前
Win系统Vscode+CoNan+Cmake实现调试与构建
c语言·c++·后端
while(1){yan}21 小时前
线程的状态
java·开发语言·jvm
豐儀麟阁贵21 小时前
8.3 Java常见的异常类
java·开发语言
20岁30年经验的码农21 小时前
Java JVM 技术详解
java·jvm·压力测试
1***815321 小时前
C在游戏中的场景管理
java·jvm·游戏
q***448121 小时前
Java进阶10 IO流
java·开发语言
济宁雪人1 天前
Java安全基础——文件系统安全
java·开发语言·安全
20岁30年经验的码农1 天前
Java RabbitMQ 实战指南
java·开发语言·python
非著名架构师1 天前
极端天气下的供应链韧性:制造企业如何构建气象风险防御体系
大数据·人工智能·算法·制造·疾风气象大模型·风光功率预测