C语言简明教程(六):字符串、常量和格式化输入输出实例详解

接上一节C语言基本数据类型完整详解

本文主要讨论C语言中的格式化输入输出scanf和printf函数,这两个函数是C语言函数中较为特殊的函数,因为需要使用到相关的转换说明或修饰符,相对高级语言来说这两个输入输出函数使用也并不方便。另外讨论一下字符串和常量的相关概念和简单实用实例,关于字符串,这里主要介绍一些核心概念,关于字符串的操作,后面会有更详细的讨论。

C语言格式化输入输出和字符串

一、C语言常量

常量指的是在程序运行过程中不会改变的数据,这时候应该使用常量的形式存储这些数据,C语言定义常量有两种方式:使用#define宏定义定义一个符号常量,使用const创建一个只读变量

#define是一个预处理命令,这个命令在预处理阶段进行处理,编译器将其定义的符号作替换处理,定义格式为:#define 符号名称 符号值,#define宏定义没有=等号,也没有分号结束。宏定义和符号常量在C开发中被大量使用,其名称一般都是使用大写,要习惯使用符号常量,不然大量符号常量可能会觉得莫名其妙,这里举几个GCC提供的包含宏定义符号常量的头文件,这些符号常量一般称为宏(Macro)。

头文件limits.h中定义整数类型的大小限制,float.h文件定义浮点数的大小限制,这两个头文件内容都是宏定义,访问这些宏需要使用#include命令包含进来,然后就能访问了。

下面是使用宏定义创建常量以及访问编译器提供的宏的例子:

#include <stdio.h>
#include <limits.h> // 定义整型的大小限制

// 使用宏定义创建一个整型常量
#define CONSTANT 123456

int main() {
    printf("%d\n", CONSTANT); // 预处理阶段会进行宏替换
    printf("max int: %d\n", INT_MAX); // limits.h中的宏定义,输出最大的整数值
    printf("max char: %d\n", CHAR_MAX); // 最大的char值
    printf("max short: %d\n", SHRT_MAX); // 最大的short值
    printf("max long: %ld\n", LONG_MAX); // 最大的long值
    printf("min int: %d\n", INT_MIN); // 最小整型值
    printf("max unsigned int: %u\n", UINT_MAX); // 最大无符号整数
    return 0;
}

定义常量的另一个方式是使用const修饰符,使用const创建一个变量,该变量只可读不可写,注意const修饰的是变量,修饰变量执行的数据不可变,const定义变量实例如下:

const float PI = 3.1415f;
// PI = 9; 重新赋值,不允许修改const变量
printf("%.4f\n", PI);

二、C语言字符串

字符串形如:”string”,C语言的字符串实际上是由一个字符类型的数组存储,数组由连续的存储单元组成,这些存储单元存储的数据都是相同类型的,数组的创建形式:类型说明符
变量名[元素个数],例如char
str[10],创建一个名为str的字符数组,即一个字符串,该数组存储10个字符。

字符数组同样由连续存储单元组成,每个存储单元存储字符串中的一个字符,并且额外存储一个空字符’\0’作为字符串结束,注意’\0’不是0,它是一个非打印字符,它的ASCII码为0。

注意:字符的表示一般表示形式形如:’A’,字符串的一般表示形式形如:”string”,单引号和双引号的作用只是为了让编译器识别单引号括起来的是字符,而双引号括起来的是字符串,此外单引号和双引号并没有什么奇异的特性,C语言字符的存储结构如下:

C语言字符串存储结构

打印一个字符串的转换说明符为%s,使用string.h文件中的strlen()函数可以获取字符串的长度,sizeof可以获取字符数组的空间大小。

定义一个字符串的方式有两种:使用宏定义定义字符串、使用字符数组和字符指针的形式,字符数组和字符指针的方式是常用的方式,sizeof在计算宏定义字符串和字符数组有差别,具体看下面的完整实例:

#include <string.h>

#define TEXT "shall we talk"

int main() {
    char title[48] = "lonely christmas";
    char *singer = "Eason";

    // strlen()函数用于输出字符串的长度,sizeof操作符输出字符串所在空间的大小
    printf("%-4d %-4u %s\n", strlen(TEXT), sizeof(TEXT), TEXT); // => 13 14,sizeof连结束的空白字符也计算在内
    printf("%-4d %-4u %s\n", strlen(title), sizeof(title), title); // => 16 48,分别计算字符串长度,数组的大小
    printf("%-4d %-4u %s\n", strlen(singer), sizeof(singer), singer); // => 5 4,注意这里的sizeof计算的是指针的大小
    return 0;
}

三、格式化输入输出

scanf格式化输入

scanf的一个参数是格式字符串,第二个是接受输入的变量地址,函数读取成功返回读取的项数,读取失败返回0项或者返回EOF(=-1,在stdio.h中),其中第一个参数格式字符串由字面字符和转换说明组成,但是一般scanf函数一般只需转换说明就够了,scanf会持续读取输入,遇到第一个不符合的字符则直接跳过,停止读取并返回,暂停读取的标识一般是空格、制表符和换行符。

注意使用转换说明%c会读取所有字符,包括空白和换行符。

printf格式化输出

printf()函数的第一个参数为格式字符串,之后的参数为待打印的变量,变量的数量要和格式字符串中的转换说明一一对应,printf打印函数打印成功返回字符的个数,失败返回负值。注意,打印float类型的数据会自动转为double,C中一般float都会默认转为double处理。

转换说明

转换说明就是格式字符串,由%开始标识,例如%s和%d,转换说明的实质是将二进制数据翻译成目标数据的形式,printf中是将原始数据按照转换说明进行输入,scanf中是将输入数据按照转换说明进行读入,常见的转换说明如下:

转换说明 说明
%c 单个字符
%d 有符号十进制数
%e 浮点数,e记数法
%f 浮点数,十进制数
%p 指针
%s 字符串
%u 无符号十进制数

转换说明修饰符

转换说明修饰符用于控制输出外观样式,转换说明修饰符主要有最小字段宽度、最小小数位和字段内布局,字段宽度用于控制输出左对齐和右对齐,可以在所有转换说明中使用字段宽度,小数位控制输出的小数位个数。例如%10.3f,表示输出的浮点数最小位宽为10位,左边不足补空,即右对齐,小数位为3位。另外还有一个*修饰符,该修饰符可以动态控制修饰符。

实例代码如下:

char message[40];
int count;
int bit = -12;
scanf("%s%d", message, &count); // 格式化输入
printf("message: %*s\n", bit, message); // 格式化输出
printf("  count: %-12d\n", count);

四、C语言与机器相关的底层类型

在这里顺便也讨论一下C语言的底层类型,底层类型是与机器相关的数据类型,主要定义在stddef.h文件中。

size_t是与机器相关的unsigned类型,sizeof返回的就是size_t数据类型,size_t即size type,记录大小的无符号整数类型。

wchar_t是宽字节字符类型,定义形式如 wchar_t c = ‘A’;

ptrdiff_t是指针距离数组类型,用以计算指针之间元素的个数。

简单的使用实例如下:

char str[20] = "shall we talk";
size_t size = sizeof(size_t);
wchar_t ch = L'A';
ptrdiff_t count = &(str[6]) - str;
printf("size: %u\n", size); // => 4
printf("%c\t%u\n", ch, sizeof(wchar_t)); // A  2
printf("count: %d\n", count); // 6
微信公众号
手机浏览(小程序)
0
分享到:
没有账号? 忘记密码?