【《C Primer Plus》读书笔记】第4章:字符串和格式化输入/输出

4.1 字符串

字符串是一个或多个字符的序列,储存在char类型的数组中。

4.1.1 ‘\0’

在这里插入图片描述
‘\0’就是8位的00000000,因为字符类型中并没有对应的这个字符,所以这么写。’\0’就是 字符串结束标志。

空字符(Null character)又称结束符,缩写 NUL,是一个数值为 0 的控制字符,\0 是转义字符,意思是告诉编译器,这不是字符 0,而是空字符。

C语言用’\0’标记字符串的结束,'\0’占据一个存储单元。

4.1.2 字符串与字符的区别

字符’a’占一个存储空间。

字符串"a"占两个存储空间,因为末尾自带’\0’。

4.2 strlen()

size_t strlen(const char *str)

C 标准库 - <string.h> 中,计算字符串 str 的长度,直到空结束字符,但不包括空结束字符。

参数:str – 要计算长度的字符串。

返回值:该函数返回字符串的长度。

下面的实例演示了 strlen() 函数的用法。

#include <stdio.h>
#include <string.h>

int main ()
{
   char str[50];
   int len;

   strcpy(str, "This is runoob.com");

   len = strlen(str);
   printf("|%s| 的长度是 |%d|\n", str, len);
   
   return(0);
}

让我们编译并运行上面的程序,这将产生以下结果:

|This is runoob.com| 的长度是 |18|

菜鸟教程:C 标准库 - <string.h>

4.3 sizeof

sizeof 是一个关键字,它是一个编译时运算符,用于判断变量或数据类型的字节大小。

sizeof 运算符可用于获取类、结构、共用体和其他用户自定义数据类型的大小。

使用 sizeof 的语法如下:

sizeof (data type)

其中,data type 是要计算大小的数据类型,包括类、结构、共用体和其他用户自定义数据类型。

size_t 是 sizeof 返回的类型(C99),打印用 %zd。

请尝试下面的实例,理解 C++ 中 sizeof 的用法。复制并黏贴下面的 C++ 程序到 test.cpp 文件中,编译并运行程序。

#include <iostream>
using namespace std;
 
int main()
{
   cout << "Size of char : " << sizeof(char) << endl;
   cout << "Size of int : " << sizeof(int) << endl;
   cout << "Size of short int : " << sizeof(short int) << endl;
   cout << "Size of long int : " << sizeof(long int) << endl;
   cout << "Size of float : " << sizeof(float) << endl;
   cout << "Size of double : " << sizeof(double) << endl;
   cout << "Size of wchar_t : " << sizeof(wchar_t) << endl;
   return 0;
}

当上面的代码被编译和执行时,它会产生下列结果,结果会根据使用的机器而不同:

Size of char : 1
Size of int : 4
Size of short int : 2
Size of long int : 4
Size of float : 4
Size of double : 8
Size of wchar_t : 4

4.4 #define

#define 是预处理器的一种。

#define 预处理指令用于创建符号常量。该符号常量通常称为宏,指令的一般形式是:

#define macro-name replacement-text 

例如:

#define MAX_ARRAY_LENGTH 20

编译程序时,这个指令告诉 CPP 把所有的 MAX_ARRAY_LENGTH 替换为 20,称为编译时替换,这样定义的常量称为明示常量。使用 #define 定义常量来增强可读性。

菜鸟教程:C 预处理器

4.5 const

C90 标准新增了 const 关键字,用于限定一个变量为只读。

例如:

const int MONTHS = 12;// MONTHS 在程序中不可修改,值为12

const 用起来比 #define 更灵活。

4.6 明示常量

C头文件 limits.h 头文件决定了各种变量类型的各种属性。定义在该头文件中的宏限制了整数类型(比如 char、int 和 long)的值。

这些限制指定了变量不能存储任何超出这些限制的值,例如一个无符号可以存储的最大值是 255。

描述
CHAR_BIT8定义一个字节的比特数。
SCHAR_MIN-128定义一个有符号字符的最小值。
SCHAR_MAX127定义一个有符号字符的最大值。
UCHAR_MAX255定义一个无符号字符的最大值。
CHAR_MIN0定义类型 char 的最小值,如果 char 表示负值,则它的值等于 SCHAR_MIN,否则等于 0。
CHAR_MAX127定义类型 char 的最大值,如果 char 表示负值,则它的值等于 SCHAR_MAX,否则等于 UCHAR_MAX。
MB_LEN_MAX1定义多字节字符中的最大字节数。
SHRT_MIN-32768定义一个短整型的最小值。
SHRT_MAX+32767定义一个短整型的最大值。
USHRT_MAX65535定义一个无符号短整型的最大值。
INT_MIN-2147483648定义一个整型的最小值。
INT_MAX2147483647定义一个整型的最大值。
UINT_MAX4294967296定义一个无符号整型的最大值。
LONG_MIN-9223372036854775808定义一个长整型的最小值。
LONG_MAX9223372036854775807定义一个长整型的最大值。
ULONG_MAX1.8446744e+19定义一个无符号长整型的最大值。

菜鸟教程:C 标准库 - <limits.h>

C 标准库的 float.h 头文件包含了一组与浮点值相关的依赖于平台的常量。

下面的值是特定实现的,且是通过 #define 指令来定义的,这些值都不得低于下边所给出的值。

描述
FLT_MANT_DIGfloat类型的尾数位数
FLT_DIGfloat类型的最少有效数字位数(十进制)
FLT_MIN_10_EXP基数为 10 时的指数的float类型的最小负整数值
FLT_MAX_EXP基数为 10 时的指数的float类型的最大正整数值
FLT_MAX最大的float类型浮点值
FLT_MIN保留全部精度的float类型最小正数
FLT_EPSILONfloat类型可表示的最小有效数字

示例:

#include <stdio.h>
#include <float.h>

int main()
{
   printf("The maximum value of float = %.10e\n", FLT_MAX);
   printf("The minimum value of float = %.10e\n", FLT_MIN);

   printf("The number of digits in the number = %.10e\n", FLT_MANT_DIG);
}

让我们编译和运行上面的程序,这将产生下列结果:

The maximum value of float = 3.4028234664e+38
The minimum value of float = 1.1754943508e-38
The number of digits in the number = 7.2996655210e-312

菜鸟教程:C 标准库 - <float.h>

4.7 printf()

C 库函数 int printf(const char *format, …) 发送格式化输出到标准输出 stdout。

printf()函数的调用格式为:

printf("<格式化字符串>", <参量表>);

菜鸟教程:C 库函数 - printf()

4.7.1 printf()中的标记

标记含义
待打印项左对齐
+有符号值若为正,则在值的前面显示加号;若为负,则在值前面显示减号
空格有符号值若为正,则在值的前面显示前导空格(不显示任何符号);若为负,则在值前面显示减号
#把结果转换为另一种格式,#保证对任何浮点数打印一个小数点字符
0对于数值格式,用前导0代替空格填充字段宽度

4.7.2 printf()中的参数传递

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
int main(void)
{
    float n1 = 3.0;
    double n2 = 3.0;
    long n3 = 2000000000;
    long n4 = 1234567890;

    printf("%ld %ld %ld %ld\n", n1, n2, n3, n4);

    system("pause");
    return 0;
}

假设我们在32位系统中执行上述程序,程序把传入的值放入栈中。

32位系统中,float占4字节,double占8字节,long占4字节。

在这里插入图片描述
参数传递的过程中,float自动转换成double,所以n1占8字节,n2占8字节,n3和n4各占4字节。而在32位系统中,long占4字节, 所以%ld表明printf()一次读取4字节。因此,四次读取的分别是:n1的前半部分,n1的后半部分,n2的前半部分,n2的后半部分。虽然n3和n4用对了转换说明,但是printf()没有读取到n3和n4。

4.7.3 printf()的返回值

一般而言,prinf()返回打印字符的个数。

如果有输出错误,printf()则返回一个负值。

4.8 scanf()

C 库函数 int scanf(const char *format, …) 从标准输入 stdin 读取格式化输入。

下面是 scanf() 函数的声明。

int scanf(const char *format, ...)

菜鸟教程:C 库函数 - scanf()

除了%c,其他转换说明都会自动跳过待输入值前面的所有空白。

scanf()的实质是字符串匹配

4.8.1 转换说明

假设有如下输入行: -13.45e12# 0。(注意-前有个空格)

  • 如果转换说明是%d,则读取-13,.作为下一次输入的首字符
  • 如果转换说明是%f,则读取-13.45e12,并存储在float类型的目标变量中
  • 如果转换说明是%s,则读取-13.45e12#,并存储在目标字符数组中,末尾加上’\0’
  • 如果转换说明是%c,则读取空格

4.8.2 scanf()的返回值

scanf()返回成功读取的项数。

如果没有读取任何项,且需要读取一个数字而用户却输入一个非数值字符串,scanf()便返回0。

当 scanf() 检测到“文件结尾”时,会返回EOF(一般用#define指令设为-1)。

4.9 printf()和scanf()的*修饰符

printf()和scanf()都可以使用*修饰符来修改转换说明的含义。

在printf()中,可以用*修饰符代替字段宽度,这需要用一个参数告诉函数字段宽度应该是多少。

示例:

/*varwid.c -- 使用变宽输出字段*/
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
int main(void)
{
    unsigned width, precision;
    int number = 256;
    double weight = 242.5;

    printf("Enter a field width:\n");
    cin >> width;
    printf("The number is :%*d:\n", width, number);
    printf("Now enter a width and a precision:\n");
    cin >> width >> precision;
    printf("Weight = %*.*f\n", width, precision, weight);

    system("pause");
    return 0;
}

测试:
在这里插入图片描述
在scanf()中,把*放在%和d之间,会使得scanf()跳过相应的输出项。

示例:

/*skiptwo.c -- 跳过输入中的前两个整数*/
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
int main(void)
{
    int n;
    cout<<"Please enter three integers:"<<endl;
    scanf("%*d %*d %d",&n);
    cout<<"The last integer was "<<n<<endl;

    system("pause");
    return 0;
}

测试:
在这里插入图片描述

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

UestcXiye

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值