C语言:基础知识

创作不易,友友们给个三连吧

一、C语⾔的基本概念与发展历史

1.1 人和计算机进行交流的语言

        通常,我们使用英语、中文等语言来进行两个人之间的交流。这意味着当我们想要和他人进行交流时,我们需要一种语言来表达自己的感受。同样的,当我们想要和计算机进行交流时,我们也需要一种语言,可以通过该语言向计算机提供信息,传达指令,我们称该语言为计算机语言。 

       然而C语言只不过是众多语言中的一种,像C++/Java/Go/Python都是计算机语⾔。

1.2 C语言的辉煌和历史

C 语⾔最初是作为 Unix 系统的开发⼯具⽽发明的。

类似的操作系统还有:windows、linux、macos(苹果)……

 1.3“C生万物,编程之本”

C语言的四大领域:

游戏:目前很多游戏客户端都是基于C++开发的,除了一些网页游戏可能不是,所以如果想从事游戏开发行业学好C++是没错的。

服务器端开发:很多互联网公司的后台服务器程序都是基于C++开发的,而且大部分是linux,unix等类似操作系统。如果你想从事这样的工作,需要熟悉linux操作系统及其在上面的开发,熟悉数据库开发,精通网络编程。

数字图像处理:现在市面上有很多VC++图像处理的书籍,可见在这个领域的应用软件开发也是占了很大比重,需要深入学习数字图像处理和模式识别等课程。

虚拟现实仿真:这个也是发展很快的计算机领域,目前各种数字地球,数字城市,虚拟地理环境什么的,出现了这方面的大量应用

        C语言出现时间较早,其他语言基本都是在C语言之后出现,或者在C语言的基础上进行创造,比如Java,C++是两门很有代表性的语言。

        并且 学习了之后,语言的通用性还是存在的,所以在学习其他的语言的时候,学习起来就相对会简单一点。

        TIOBE网站上可以查到每年编程语言的使用排名,其中c语言常见保持前3,

网址:https://www.tiobe.com/tiobe-index/

二、编译器的选择和使用方法

2.1 编译和链接

        C语⾔是⼀⻔编译型计算机语⾔C语言源代码都是文本文件,文本文件本身无法执行,必须通过编译器翻译和链接器的链接,生成二进制的可执行文件,可执行文件才能执行。(计算机识别的是二进制指令) C语⾔代码是放在 .c 为后缀的⽂件中的,要得到最终运⾏的可执⾏程序,中间要经过编译和链接2个过程。

       ⼀个工程⼀般都会有多个源文件组成,如下图所示,演示了源程序经过编译器和链接器处理的过程。

.c→.obj→.exe

​⼀个工程⼀般都会有多个源文件组成,如下图所示,演示了源程序经过编译器和链接器处理的过程。

1. 每个源文件(.c)单独经过编译器处理⽣成对应的目标⽂件(.obj为后缀的⽂件)

2. 多个⽬标⽂件和库文件经过链接器处理⽣成对应的可执行程序(.exe⽂件)

 2.2 编译器对比和选择

         C语⾔是⼀⻔编译型的计算机语⾔,需要依赖编译器将计算机语⾔转换成机器能够执⾏的机器指令。

         那我们常⻅的C语⾔编译器都有哪些呢? ⽐如:msvc、clang、gcc 就是⼀些常⻅的编译器,当然也有⼀些集成开发环境如:VS2022、 XCode、CodeBlocks、DevC++、Clion等。

集成开发环境(IDE):⽤于提供程序开发环境的应⽤程序,⼀般包括代码编辑器、 编译器 、 调试器 和 图形⽤⼾界⾯ 等⼯具。 集成了代码编写功能、分析功能、编译功能、调试功能等⼀体化的开发软件服务套。

VS2022 集成了MSVC(安装报包较⼤⼀些,安装简单,⽆需多余配置,使⽤起来⾮常⽅便)

XCode 集成了clang(苹果电脑上的开发⼯具)

CodeBlocks 集成了gcc(这个⼯具⽐较⼩众,需要配置环境,不太推荐)

DevC++ 集成了gcc(⼩巧,但是⼯具过于简单,对于代码⻛格的养成不好,⼀些竞赛使⽤)

Clion 是默认使⽤CMake,编译器是可以配置的(⼯具是收费,所以暂时推荐⼤家使⽤)

VSCode 具有强大的插件系统,可安装各种插件,来搭建c/c++的开发环境(不推荐新手使用)

新手推荐使用VS2022社区版本,免费并且使用方便。

 2.3 VS的优缺点和下载方法

优点:

• VS2022 是⼀个主流的集成开发环境,企业中使⽤较为普遍

• VS2022 包含了:编辑器+编译器+调试器,功能强⼤

• 直接安装即可使⽤,基本不⽤额外配置环境,上⼿容易

• 默认界⾯是中⽂的,初学者友好

缺点:

• 功能丰富,安装包⼤,占⽤空间多。

下载方法:https://visualstudio.microsoft.com/zh-hans/downloads/

安装教程:https://www.bilibili.com/video/BV11R4y1s7jz/

2.4 VS项目和源文件、头文件介绍

在项⽬中就可以添加源⽂件和头⽂件。

C语⾔把 .c 为后缀的⽂件称为源⽂件,把 .h 为后缀的⽂件称为头⽂件。

2.5 在VS上创建新项目

2.5.1 写代码的前的步骤

1、创建项目(代码是在项目中管理的)

2、创建.c文件

3、写C语言代码,邀严格按照C语言的语法来写!!

2.5.2 项目名称

1、项目名称最好有自己的实际意义

2、项目名称最好不要使用后中文

3、不要使用特殊字符

2.5.3 项目存储路径 

1、代码的位置邀自己找一个熟悉的路径维护起来

2、这个代码的路径不要包括空格、特殊字符、中文字符

三、main函数

每个 C 语⾔程序不管有多少⾏代码,都是从 main 函数开始执⾏的, main 函数是程序的⼊⼝, main 函数也被叫做:主函数。 main 前⾯的 int 表⽰ main 函数执⾏结束的时候返回⼀个整型类 型的值。所以在 main 函数的最后写 return 0; 正好前后呼应。

• main函数是程序的入口

• main函数有且仅有⼀个

• 即使⼀个项⽬中有多个.c⽂件,但是只能有⼀个main函数(因为程序的入口只能有⼀个)

• main函数可以出现在任意位置,若在主函数中调用的哪些函数,则必须在main函数之前对所调用的函数进行声明,或者包含其被调用函数的头文件

• 一般约定返回0,在c语言中正常在返回0,异常会返回非0

int main()
{
printf("hello C\n");
return 0;
}

在VS2022上运⾏代码的快捷键: Ctrl+f5 

四、关键字介绍

      C语⾔中有⼀批保留的名字的符号,⽐如: int 、 if 、 return ,这些符号被称为保留字或者关键 字。

      • 关键字都有特殊的意义,是保留给C语言使用的

      • 程序员自己在创建标识符的时候是不能和关键字重复的

      • 关键字也是不能自己创建的。 C语言的32个关键字如下:

注:在C99标准中加⼊了 inline 、 restrict 、 _Bool 、 _Comploex 、 _Imaginary 等关键字。 ⼀些关键字⼤家可以去了解⼀下,不过使⽤最多的还是上⾯的32个关键字。

注:https://zh.cppreference.com/w/c/keyword(C语⾔关键字的全部介绍)

注: difine不是关键字,他是编译器实现的用来定义宏的预处理指令,不是c语言中的内容。

五、字符和ASCII编码

         在键盘上可以敲出各种字符,如:a,q,@,#等,这些符号都被称为字符,C语⾔中字符是⽤单引号 括起来的,如:'a','b','@'。单个字符的打印可以使用%c来指定格式。

        我们知道在计算机中所有的数据都是以二进制的形式存储的,那这些字符在内存中分别以什么样的⼆进制存储的呢?如果我们每个⼈⾃⼰给这些字符中的每个字符编⼀个⼆进制序列,这就叫做编码,为了⽅便⼤家相互通信,不造成混乱,后来美国国家标准学会(ANSI)出台了⼀个标准 ASCII 编码,C语言中的字符就遵循了ASCII 编码的⽅式。

参考:https://zh.cppreference.com/w/cpp/language/ascii

      我们不需要记住所有的ASCII码表中的数字,使⽤时查看就可以,不过我们最好能掌握⼏组特殊的数据:

 • 字符A~Z的ASCII码值从65~90

• 字符a~z的ASCII码值从97~122

• 对应的大小写字符(a和A)的ASCII码值的差值是32

• 数字字符0~9的ASCII码值从48~57 • 换⾏ \n 的ASCII值是:10

• 在这些字符中ASCII码值从0~31 这32个字符是不可打印字符,无法打印在屏幕上观察

• 字符其实也属于整型家族

比如:可打印字符展示(32-127)

#include <stdio.h>
int main()
{int i = 0;for (i = 32; i <= 127; i++){printf("%c ", i);if (i % 16 == 15)printf("\n");}return 0;
}

  ! " # $ % & ' ( ) * + , - . /
0 1 2 3 4 5 6 7 8 9 : ; < = > ?
@ A B C D E F G H I J K L M N O
P Q R S T U V W X Y Z [ \ ] ^ _
` a b c d e f g h i j k l m n o
p q r s t u v w x y z { | } ~

六、字符串和\0

使用双引号括起来的一串字符就被称为字符串,如:“abcdef”,就是一个字符串。

字符串的打印格式可以使用 %s 来指定,也可以直接打印如下:

#include <stdio.h>
int main()
{printf("%s\n", "hello C");printf("hello c");return 0;
}

        C语⾔字符串中⼀个特殊的知识,就是在字符串的末尾隐藏放着⼀个 \0 字符,这个 \0 字符是字符串 的结束标志。

      为了观察这一现象,我们要在调试中找到监视功能,它在VS2022里面的路径是:【调试】->【窗口】->【监视】,但当我们打开此路径,我们并没有找到监视的功能。

原因是:监视必须是代码在调试的条件下进行,所以按下ctrl+F10,开始调试程序,此时再来到刚才的路径,就能找到监视的窗口了。

左边出现箭头即为进入调试阶段

      在进入调试状态后,比如想要监视某一个变量,添加本代码变量于监视窗口中添加完待监视项后,按f10 代码会一步一步运行,待监视项便也随着代码运行进行改变。

       我们可以发现对于字符串"abcdef",我们实际上看到了6个字符:a,b,c,d,e,f,但是实际上在末尾还隐藏⼀个 \0 的 转义字符, \0 是字符串的结束标志。所以我们在使⽤库函数 printf() 打印字符串或者 strlen() 计算字符串⻓度的时候,遇到 \0 的时候就⾃动停⽌了。

监视窗口的优点:

1.便于理解代码,对代码工作原理运行顺序的理解都很有帮助

2.可以方便地在大型工作表中检查、审核或确认公式计算及其结果。. 使用“监视窗口”,无需反复滚动或定位到工作表的不同部分。

注:C语⾔中也可以把⼀个字符串放在⼀个字符数组中,我们在这里利用下⾯的代码验证⼀下 \0 的功能。

#include<stdio.h>
int main()
{char arr1[] = { 'a', 'b', 'c' };//arr1数组中存放3个字符char arr2[] = "abc"; //arr2数组中存放字符串printf("%s\n", arr1);//不含有/0,所以没有停止的标志,会一直输出下去,会出现一些随机值printf("%s\n", arr2);//含有/0,所以会输出到停止return 0;
}

abc烫烫烫烫烫烫烫烫烫烫烫烫烫烫蘟bc
abc

       我们可以看到, arr1 字符数组在打印的时候,打印了 a 、 b 、 c 后还打印了⼀些随机值,这就是 因为 arr1 在末尾的地⽅没有 \0 字符作为结束标志,在打印的时候没有停⽌。

       但是 arr2 的打印就是完全正常的,就是因为 arr2 数组是使⽤字符串常量初始化的,数组中有 \0 作为技术标志,打印可以正常停⽌。

 如果我们在arr1数组中单独放⼀个 '\0' 字符呢?

#include<stdio.h>
int main()
{char arr1[] = { 'a', 'b', 'c' ,'\0'};//arr1数组中存放3个字符char arr2[] = "abc"; //arr2数组中存放字符串printf("%s\n", arr1);printf("%s\n", arr2);return 0;
}

abc
abc

      则我们可以发现打印的结果是⼀样的了,都是打印到 \0 的时候就停⽌了,由此可以说明\0的作用以及重要性。

七、转义字符

也许在前⾯的代码中你看到 \n , \0 很纳闷时啥。其实在字符中有⼀组特殊的字符是转义字符,转义 字符顾名思义:转变原来的意思的字符。

C语⾔中像这样的转义字符,具体如下:

• \? :在书写连续多个问号时使⽤,防⽌他们被解析成三字⺟词,在新的编译器上没法验证了。

• \' :⽤于表⽰字符常量'(想打印单引号时用\将'转换成字符)

• \" :⽤于表⽰⼀个字符串内部的双引号(想打印双引号时用\将'转换成字符)

• \\ :⽤于表⽰⼀个反斜杠,防⽌它被解释为⼀个转义序列符。(相当于\\=1个\)

• \a :警报,这会使得终端发出警报声或出现闪烁,或者两者同时发⽣。

• \b :退格键,光标回退⼀个字符,但不删除字符。(覆盖前面那个字符)

• \f :换⻚符,光标移到下⼀⻚。在现代系统上,这已经反映不出来了,⾏为改成类似于 \v 。

• \n :换⾏符。

• \r :回⻋符,光标移到同⼀⾏的开头。

• \t :制表符,光标移到下⼀个⽔平制表位,通常是下⼀个8的倍数。(让输出的内容更美观和可读)

• \v :垂直分隔符,光标移到下⼀个垂直制表位,通常是下⼀⾏的同⼀列。

下⾯2种转义字符可以理解为:字符的8进制或者16进制表⽰形式

• \ddd :d d d表⽰1~3个⼋进制的数字。 如: \130 表示字符X(字符八进制的表示形式)

• \xdd :d d表⽰2个⼗六进制数字。 如: \x30 表示字符0(字符十六进制的表示形式)

• \0 :null 字符,代表没有内容, \0 就是 \ddd 这类转义字符的⼀种,⽤于字符串的结束标志,其 ASCII码值是0.

注: 关于转义字符我们首先要了解,然后要能在字符串中识别出来。(求字符串长度时,转义字符只占一个字节)

题型:求复杂字符串的长度

int main()
{printf("%zd\n", strlen("c:\test\130\test.c"));
}

13       因为\t和\130都只算1个字符 

转义字符参考:https://zh.cppreference.com/w/c/language/escape

八、语句和语句分类

8.1空语句

   空语句是最简单的,⼀个分号就是⼀条语句,是空语句。

#include <stdio.h>
int main()
{;//空语句return 0;
}

        空语句⼀般出现的地⽅是:这⾥需要⼀条语句,但是这个语句不需要做任何事,就可以写⼀个空语句。

8.2表达式语句

       表达式语句就是在表达式的后边加上分号。如下所⽰:

#include <stdio.h>
int main()
{int a = 20;int b = 0;b = a + 5; //表达式语句return 0;
}

8.3函数调用语句

函数调⽤的时候,也会加上分号,就是函数调⽤语句。

#include <stdio.h>
int Add(int x, int y)
{return x+y;
}int main()
{printf("hehe\n");//函数调⽤语句int ret = Add(2, 3);//函数调⽤语句 return 0;
}

8.4复合语句

复合语句其实就是前⾯讲过的代码块,成对括号中的代码就构成⼀个代码块,也被称为复合语句

#include <stdio.h>
void print(int arr[], int sz) //函数的⼤括号中的代码也构成复合语句
{int i = 0;for(i=0; i<sz; i++){printf("%d ", arr[i]);}
}
int main()
{int i = 0;int arr[10] = {0};for(i=0; i<10; i++) //for循环的循环体的⼤括号中的就是复合语句{arr[i] = 10-i;printf("%d\n", arr[i]);}return 0;
}

8.5控制语句

        控制语句⽤于控制程序的执⾏流程,以实现程序的各种结构⽅式(C语⾔⽀持三种结构:顺序结构、选择结构、循环结构),它们由特定的语句定义符组成,C语⾔有九种控制语句。

可分成以下三类:

1. 条件判断语句也叫分⽀语句:if语句、switch语句

2. 循环执⾏语句:do while语句、while语句、for语句

3. 转向语句:break语句、goto语句、continue语句、return语句。

九、注释

注释是对代码的说明,编译器会忽略注释,也就是说,注释对实际代码没有影响。

注释是给程序员⾃⼰,或者其他程序员看的。

好的注释可以帮我们更好的理解代码,但是也不要过度注释,不要写没必要的注释。

当然不写注释可能会让后期阅读代码的⼈抓狂。 写注释⼀定程度上反应了程序作者的素质,建议⼤家写必要的注释,在未来找⼯作的时候,写代码时 留下必要的注释也会给⾯试官留下更好的印象。

第⼀种⽅法是将注释放在 /*...*/ 之间,内部可以分⾏。

注:这种注释⼀定不能忘记写结束符号 */ ,否则很容易导致错误。

注:/* */ 的这个注释不⽀持嵌套注释, /* 开始注释后,遇到第⼀个 */ 就认为注释结束了。

第⼆种方法是将注释放在双斜杠 // 后⾯,从双斜杠到⾏尾都属于注释。这种注释只能是单⾏,可以 放在⾏⾸,也可以放在⼀⾏语句的结尾。这是 C99 标准新增的语法。

注:不管是哪⼀种注释,都不能放在双引号⾥⾯。 双引号⾥⾯的注释符号,会成为字符串的⼀部分,解释为普通符号,失去注释作⽤。

注:编译时,注释会被替换成⼀个空格,所以(min/*    这⾥是注释   */Value) 会变成 min Value ,而不是 minValue 。

十、数据类型

C语⾔提供了丰富的数据类型来描述⽣活中的各种数据。

使⽤整型类型来描述整数,使⽤字符类型来描述字符,使⽤浮点型类型来描述⼩数。

        所谓“类型”,就是相似的数据所拥有的共同特征,编译器只有知道了数据的类型,才知道怎么操作 数据。

10.1 字符型

char
[signed] char
unsigned char

10.2 整型

//短整型
short [int]
[signed] short [int]
unsigned short [int]
//整型
int
[signed] int
unsigned int
//⻓整型
long [int]
[signed] long [int]
unsigned long [int]
//更⻓的整型
//C99中引⼊
long long [int]
[signed] long long [int]
unsigned long long [int]

10.3 浮点型

float
double
long double

10.4 布尔类型

C 语⾔原来并没有为布尔值单独设置⼀个类型,⽽是使⽤整数 0 表⽰假,⾮零值表⽰真。

在 C99 中也引⼊了 布尔类型 ,是专门表示真假的。

_Bool

布尔类型的使⽤需要包含头⽂件<stdbool.h> 

布尔类型变量的取值是:true或者false

10.5 自定义类型 

C语言:自定义类型——结构体-CSDN博客

C语言:自定义类型——联合和枚举-CSDN博客

10.6 数据类型的长度

10.7 signed 和 unsigned 

C 语⾔使⽤ signed 和 unsigned 关键字修饰字符型和整型类型的。

signed 关键字,表⽰⼀个类型带有正负号,包含负值;

unsigned 关键字,表⽰该类型不带有正负号,只能表⽰零和正整数。

整数变量声明为 unsigned 的好处是,同样⻓度的内存能够表⽰的最⼤整数值,增⼤了⼀倍。

C 语言规定 char 类型默认是否带有正负号,由当前系统决定。

所以 char 不等同于 signed char ,它有可能是 signed char ,也有可能是 unsigned char 

这⼀点与 int 不同, int 就是等同于 signed int 。

十一、变量

类型是⽤来创建变量的。C语⾔中把经常变化的值称为变量,不变的值称为常量。

data_type name;| || |
数据类型 变量名

11.1 变量初始化

变量在创建的时候就给⼀个初始值,就叫初始化。

int age = 18;
char ch = 'w';
double weight = 48.0;
unsigned int height = 100;

11.2 变量的分类

• 全局变量:在⼤括号外部定义的变量就是全局变量

全局变量的使⽤范围更⼴,整个⼯程中想使⽤,都是有办法使⽤的。

• 局部变量:在⼤括号内部定义的变量就是局部变量

局部变量的使⽤范围是⽐较局限,只能在⾃⼰所在的局部范围内使⽤的。

int global = 2023;//全局变量
int main()
{int local = 2018;//局部变量printf("%d\n", local);printf("%d\n", global);return 0;
}

注意:局部变量和全局变量同名的时候,局部变量优先使⽤。 

11.3 变量的命名规则和规范

1.一个变量名称可以由数字、字母、下划线、美元符号($) 组成

2.严格区分大小写

3.不能由数字开头,不要使用中文汉字命名

4.不能是保留字或者关键字

5.不要出现空格

十二、printf详细介绍

12.1 基本用法

printf() 的作⽤是将参数⽂本输出到屏幕。它名字⾥⾯的 f 代表 format (格式化),表⽰可以 定制输出⽂本的格式。头文件<stdio.h>

int main(void) 
{printf("Hello World");return 0;
}

Hello World 

     printf() 不会在自动在行尾添加换行符,运⾏结束后,光标就停留在输出结束的地⽅,不会⾃动换行。 为了让光标移到下⼀行的开头,可以在输出文本的结尾,添加⼀个换行符 \n 。 

12.2 占位符列举

• %a :⼗六进制浮点数,字⺟输出为⼩写。

• %A :⼗六进制浮点数,字⺟输出为⼤写。

• %c :字符。 • %d :⼗进制整数。

• %e :使⽤科学计数法的浮点数,指数部分的 e 为⼩写。

• %E :使⽤科学计数法的浮点数,指数部分的 E 为⼤写。

• %i :整数,基本等同于 %d 。

• %f :⼩数(包含 float 类型和 double 类型)。

• %g :6个有效数字的浮点数。整数部分⼀旦超过6位,就会⾃动转为科学计数法,指数部分的 e 为⼩写。

• %G :等同于 %g ,唯⼀的区别是指数部分的 E 为⼤写。

• %hd :⼗进制 short int 类型。

• %ho :⼋进制 short int 类型。

• %hx :⼗六进制 short int 类型。

• %hu :unsigned short int 类型。

• %ld :⼗进制 long int 类型。

• %lo :⼋进制 long int 类型。

• %lx :⼗六进制 long int 类型。

• %lu :unsigned long int 类型。

• %lld :⼗进制 long long int 类型。

• %llo :⼋进制 long long int 类型。

• %llx :⼗六进制 long long int 类型。

• %llu :unsigned long long int 类型。

• %Le :科学计数法表⽰的 long double 类型浮点数。

• %Lf :long double 类型浮点数。

• %n :已输出的字符串数量。该占位符本⾝不输出,只将值存储在指定变量之中。

• %o :⼋进制整数。

• %p :指针。

• %s :字符串。

• %u :⽆符号整数(unsigned int)。

• %x :⼗六进制整数。

• %zd : size_t 类型。

• %% :输出⼀个百分号。

12.3 占位符的使用

printf() 可以在输出⽂本中指定占位符。 所谓 “占位符”,就是这个位置可以⽤其他值代⼊。

常⽤的占位符除了 %d ,还有 %s 表⽰代⼊的是字符串。

输出文本里面可以使用多个占位符!!!

int main()
{printf("%s says it is %d o'clock\n", "lisi", 21);return 0;
}

lisi says it is 21 o'clock 。 

      printf() 参数与占位符是⼀⼀对应关系,如果有 n 个占位符, printf() 的参数就应该有 n + 1 个。如果参数个数少于对应的占位符, printf() 可能会输出内存中的任意值。 

12.4 输出格式

printf() 允许限定占位符的最⼩宽度。

12.4.1 限定宽度

int main()
{printf("%5d\n", 123); // 输出为 " 123"return 0;
}

输出结果:“  123” 

上⾯⽰例中, %5d 表⽰这个占位符的宽度⾄少为5位。如果不满5位,对应的值的前⾯会添加空格。 输出的值默认是右对⻬,即输出内容前⾯会有空格;如果希望改成左对⻬,在输出内容后⾯添加空格,可以在占位符的 % 的后⾯插⼊⼀个 - 号。 

int main()
{printf("%-5d\n", 123); // 输出为 "123 "return 0;
}

 输出结果:“123  ” 

对于小数,这个限定符会限制所有数字的最小显示宽度。 

int main()
{printf("%12f\n", 123.45);return 0;
}

"  123.450000" 

上⾯⽰例中, %12f 表⽰输出的浮点数最少要占据12位。由于小数的默认显示精度是⼩数点后6位, 所以 123.45 输出结果的头部会添加2个空格。 

12.4.2 总是显示正负号

默认情况下, printf() 不对正数显⽰ + 号,只对负数显⽰ - 号。如果想让正数也输出 + 号,可 以在占位符的 % 后⾯加⼀个 + 。

int main()
{printf("%+d\n", 12); // 输出 +12printf("%+d\n", -12); // 输出 -12return 0;
}

+12

-12 

上⾯⽰例中, %+d 可以确保输出的数值,总是带有正负号。 

12.4.3 限定小数位数

输出小数时,有时希望限定⼩数的位数。举例来说,希望⼩数点后⾯只保留两位,占位符可以写 成 %.2f 。

int main()
{printf("Number is %.2f\n", 0.5);return 0;
}

Number is  0.50

这种写法可以与限定宽度占位符,结合使⽤。 

int main()
{printf("%6.2f\n", 0.5);return 0;
}

"   0.50" 

最⼩宽度和⼩数位数这两个限定值,都可以⽤ * 代替,通过 printf() 的参数传⼊。 

int main()
{printf("%*.*f\n", 6, 2, 0.5);return 0;
}
// 等同于printf("%6.2f\n", 0.5);

"   0.50"                          上述代码等同于printf("%6.2f\n", 0.5);

12.4.4 输出部分字符串

%s 占位符⽤来输出字符串,默认是全部输出。如果只想输出开头的部分,可以⽤ %.[m]s 指定输出 的⻓度,其中 [m] 代表⼀个数字,表⽰所要输出的⻓度。

int main()
{printf("%.5s\n", "hello world");return 0;
}

 hello                  占位符 %.5s 表⽰只输出字符串“hello world”的前5个字符,即“hello”。

12.5 printf的返回值 

printf的返回值返回的是字符串中字符的数量(和strlen的返回值差不多,但是strlen的返回值是size_t,而printf的返回值是int)

int main()
{int a=printf("hello world\n");printf("%d\n", a);return 0;
}

hello world
12 

十三、scanf详细介绍

13.1 基本用法

scanf() 函数⽤于读取用户的键盘输⼊。

程序运⾏到这个语句时,会停下来,等待⽤⼾从键盘输⼊。

⽤⼾输⼊数据、按下回⻋键后, scanf() 就会处理⽤⼾的输⼊,将其存⼊变量。

它的原型定义也在头⽂件 stdio.h , scanf() 的语法跟 printf() 类似。 

scanf("%d", &i);

        它的其余参数就是存放⽤⼾输⼊的变量,格式字符串⾥⾯有多少个占位符,就有多少个变量。 上⾯⽰例中, scanf() 的第⼀个参数 %d ,表⽰⽤⼾输⼊的应该是⼀个整数。 %d 就是⼀个占位 符, % 是占位符的标志, d 表⽰整数。第⼆个参数 &i 表⽰,将⽤⼾从键盘输⼊的整数存⼊变量 i 。

        变量前⾯必须加上 & 运算符(指针变量除外),因为 scanf() 传递的不是值,⽽是地址, 即将变量 i 的地址指向⽤⼾输⼊的值。 如果这⾥的变量是指针变量(⽐如字符串变量),那就不⽤加 & 运算符。

     scanf() 处理数值占位符时,会⾃动过滤空⽩字符,包括空格、制表符、换⾏符等。

     所以,⽤⼾输⼊的数据之间,有⼀个或多个空格不影响 scanf() 解读数据。另外,⽤⼾使⽤回⻋ 键,将输⼊分成⼏⾏,也不影响解读。 

scanf() 处理⽤⼾输⼊的原理是,⽤⼾的输⼊先放⼊缓存,等到按下回⻋键后,按照占位符对缓存 进⾏解读。 解读用户输⼊时,会从上⼀次解读遗留的第⼀个字符开始,直到读完缓存,或者遇到第⼀个不符合条件的字符为⽌。 

int main()
{int x;float y;// ⽤⼾输⼊ " -13.45e12# 0"scanf("%d", &x);printf("%d\n", x);scanf("%f", &y);printf("%f\n", y);return 0;
}

输入: -13.45e12# 0
输出:-13
          449999994880.000000

        在上⾯⽰例中, scanf() 读取⽤⼾输⼊时, %d 占位符会忽略起⾸的空格,从 - 处开始获取数据,读 取到 -13 停下来,因为后⾯的 . 不属于整数的有效字符。这就是说,占位符 %d 会读到 -13 。 第⼆次调⽤ scanf() 时,就会从上⼀次停⽌解读的地⽅,继续往下读取。这⼀次读取的⾸字符 是 . ,由于对应的占位符是 %f ,会读取到 .45e12 (表示0.45*10^12),这是采⽤科学计数法的浮点数格式。后⾯的 # 不属于浮点数的有效字符,所以会停在这⾥。 

13.2 scanf的返回值 

scanf() 的返回值是⼀个整数,表⽰成功读取的变量个数。 如果没有读取任何项,或者匹配失败,则返回 0 。如果在成功读取任何数据之前,发⽣了读取错误或 者遇到读取到⽂件结尾,则返回常量 EOF。

13.3 占位符的使用 

scanf() 常⽤的占位符如下,与 printf() 的占位符基本⼀致。

• %c :字符。

• %d :整数。

• %f : float 类型浮点数。

• %lf : double 类型浮点数。

• %Lf : long double 类型浮点数。 • %s :字符串。

• %[] :在⽅括号中指定⼀组匹配的字符(⽐如 %[0-9] ),遇到不在集合之中的字符,匹配将会停⽌。

13.3.1 %c

1、上⾯所有占位符之中,除了 %c 以外,都会⾃动忽略起首的空白字符。 %c 不忽略空⽩字符,总是返回当前第⼀个字符,无论该字符是否为空格。

2、如果要强制跳过字符前的空⽩字符,可以写成 scanf(" %c", &ch) ,即 %c 前加上⼀个空格,表⽰跳过零个或多个空⽩字符。 

13.3.2 %s

1、占位符 %s ,它其实不能简单地等同于字符串。它的规则是,从当前第⼀个⾮空⽩ 字符开始读起,直到遇到空⽩字符(即空格、换⾏符、制表符等)为⽌。

2、 因为 %s 不会包含空⽩字符,所以⽆法⽤来读取多个单词,除⾮多个 %s ⼀起使⽤。这也意味着, scanf( ) 不适合读取可能包含空格的字符串,⽐如书名或歌曲名。另外, scanf( ) 遇到 %s 占位符,会在字符串变量末尾存储⼀个空字符 \0 。 

3、 scanf() 将字符串读⼊字符数组时,不会检测字符串是否超过了数组⻓度。所以,储存字符串时, 很可能会超过数组的边界,导致预想不到的结果。为了防⽌这种情况,使⽤ %s 占位符时,应该指定读⼊字符串的最⻓⻓度,即写成 %[m]s ,其中的 [m] 是⼀个整数,表⽰读取字符串的最大场度,后⾯的字符将被丢弃。

int main()
{char name[11];scanf("%10s", name);return 0;
}

上面实例中, name 是⼀个⻓度为11的字符数组, scanf() 的占位符 %10s 表⽰最多读取⽤⼾输⼊ 的10个字符,后⾯的字符将被丢弃,这样就不会有数组溢出的⻛险了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/22144.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

10分钟了解ERP软件系统

ERP&#xff08;Enterprise Resource Planning&#xff0c;企业资源规划&#xff09;软件是一种集成的管理信息系统&#xff0c;旨在通过优化公司内部资源的分配和使用&#xff0c;提高企业的运营效率和管理水平。ERP系统通常包含多个功能模块&#xff0c;这些模块覆盖了企业运…

c语言:自定义类型(枚举、联合体)

前言&#xff1a; c语言中中自定义类型不仅有结构体&#xff0c;还有枚举、联合体等类型&#xff0c;上一期我们详细讲解了结构体的初始化&#xff0c;使用&#xff0c;传参和内存对齐等知识&#xff0c;这一期我们来介绍c语言中的其他自定义类型枚举和联合体的知识。 1.位段 …

微服务:Rabbitmq利用jackson序列化消息为Json发送并接收

消息序列化 Spring默认会把你发送的消息通过JDK序列化为字节发送给MQ&#xff0c;接收消息的时候&#xff0c;再把字节反序列化为Java对象。 我们可以配置JSON方式来序列化&#xff0c;这样体积更小&#xff0c;可读性更高。 引入依赖&#xff1a; <dependency><g…

灯珠对LED显示屏性能的影响

LED显示屏作为现代显示技术的重要组成部分&#xff0c;广泛应用于广告、信息发布、交通指示等领域。灯珠作为LED显示屏的核心组件&#xff0c;对其性能有着决定性的影响。本文将从八个关键方面探讨灯珠对LED显示屏性能的影响。 1. 视角 LED显示屏的视角由灯珠的视角决定。户外显…

UFS协议—新手快速入门(二)【5-6】

目录 五、UFS协议栈 六、UFS技术演进与详解 1、UFS应用层 设备管理器 任务管理器 2、UFS传输层 3、UFS互联层 UFS协议—新手快速入门&#xff08;一&#xff09;【1-4】 五、UFS协议栈 UFS&#xff08;Universal Flash Storage&#xff09;协议是针对固态存储设备&…

渡众机器人自动驾驶小车运行Autoware 实现港口物流运输

Autoware 是一个开源的自动驾驶软件堆栈&#xff0c;提供了丰富的功能和模块&#xff0c;用于实现自动驾驶车辆的感知、定位、规划和控制等功能。北京渡众机器人公司将多款自动驾驶小车在多场景运行Autoware &#xff0c;它可以实现以下功能&#xff1a; 1. 感知&#xff1a;利…

Spark的性能调优——RDD

前言 RDD 是 Spark 对于分布式数据集的抽象&#xff0c;每一个 RDD 都代表着一种分布式数据形态。比如 lineRDD&#xff0c;它表示数据在集群中以行&#xff08;Line&#xff09;的形式存在&#xff1b;而 wordRDD 则意味着数据的形态是单词&#xff0c;分布在计算集群中。 参…

数据挖掘综合案例-家用热水器用户行为分析与事件识别

文章目录 1. 背景与挖掘目标2. 分析方法与过程3. 数据分析3.1 数据探索分析3. 2 数据预处理1. 属性约束2. 划分用水事件3. 确定单次用水事件时长阈值4. 属性构造5.筛选候选洗浴事件 3.3 模型构建3.4 模型检验 4. 思考总结 1. 背景与挖掘目标 随着国内大家电品牌的进入和国外品…

了解CAN功能

了解CAN功能&#xff0c;学习CAN功能&#xff0c;理解CAN和串口的区别&#xff0c;以及它和RS485的相似之处。 1、“多主机”特性 在CAN网络通讯中&#xff0c;无需其它设备同意&#xff0c;每个CAN设备都可以主动向外发送数据&#xff0c;且所有设备都会收到数据&#xff0c…

【面试干货】 非关系型数据库(NoSQL)与 关系型数据库(RDBMS)的比较

【面试干货】 非关系型数据库&#xff08;NoSQL&#xff09;与 关系型数据库&#xff08;RDBMS&#xff09;的比较 一、引言二、非关系型数据库&#xff08;NoSQL&#xff09;2.1 优势 三、关系型数据库&#xff08;RDBMS&#xff09;3.1 优势 四、结论 &#x1f496;The Begin…

孵化器补贴政策提问模板

对于一些需要创业的人来说&#xff0c;找场地是非常非常难的&#xff0c;一个好的场地能够提高创业的成功率&#xff0c;下面这些内容对于孵化器产业园的政策有一个好的提问&#xff0c;可以帮助你们了解这个孵化器合不合适。需要创业的人可以收藏 某孵化器政策示例 提问模板 …

【竞技宝】欧洲杯:德国被乌克兰逼平,27脚射门仍难得分!

欧洲杯前的热身赛已经全面开启,东道主德国队算是打响了热身赛的第一枪,只可惜他们在主场0比0被乌克兰逼平。整场比赛,德国队都占据明显优势,全场比赛轰出27脚射门,可是却无法实现破门。这个时候德国球迷似乎回想到了前两届世界大赛,球队被“锋无力”支配的恐惧。 本场比赛德国队…

如何制作Peppol文件?

Peppol (Pan-European Public Procurement Online) 是一种用于跨境电子采购的标准协议和网络。它允许企业和政府机构以电子方式交换文件&#xff0c;如电子发票、订单和发货单。如果你需要制作Peppol文件&#xff0c;可以参考如下步骤&#xff1a; 准备必要工具和资源 1.Pepp…

Serif Affinity 2.5 (macOS, Windows) - 专业创意软件

Serif Affinity 2.5 (macOS, Windows) - 专业创意软件 Affinity Designer 2, Affinity Photo 2, Affinity Publisher 2 请访问原文链接&#xff1a;Serif Affinity 2.5 (macOS, Windows) - 专业创意软件&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主…

【第二节】C/C++数据结构之线性表

目录 一、线性表基本说明 1.1 基本概念 1.2 抽象数据类型 1.3 存储结构 1.4 插入与删除的区别 1.5 顺序存储和链式存储的优缺点 二、链表 2.1 基本概念 2.2 抽象数据类型 2.3 单链表的定义 2.4 单链表的基本操作 2.5 单链表模板形式的类定义与实现 三、单向循环链…

成功解决“ModuleNotFoundError: No module named ‘tensorflow_datasets‘”错误的全面指南

成功解决“ModuleNotFoundError: No module named ‘tensorflow_datasets’”错误的全面指南 在Python编程和深度学习项目中&#xff0c;tensorflow_datasets&#xff08;通常简称为tfds&#xff09;是一个非常重要的库&#xff0c;它提供了大量现成的数据集&#xff0c;方便…

终于来啦!Stable Diffusion 3将在6月12日正式开源

6月3日晚&#xff0c;著名开源大模型平台Stability AI的联合首席执行官Christian Laforte&#xff0c;在AMD的产品发布会上宣布&#xff0c;文生图模型 Stable Diffusion 3将于6月12日在Hugging Face开源权重。 本次开源的是Stable Diffusion 3的Medium模型&#xff0c;有20亿…

武汉盛势启创科技携手三品软件 EDM系统助力企业图文档数字化

客户简介 武汉盛势启创科技有限公司&#xff08;以下简称“盛世启创”&#xff09;是一家专注于新能源汽车零部件领域的科技型企业&#xff0c;其主要业务涵盖新能源汽车三电系统智能传感器、智能座舱及线控底盘控制器的芯片开发、硬件设计、嵌入式系统开发。以及相关产品的生产…

C++第二十三弹---深入理解STL中list的使用

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】 目录 1、list的介绍 2、list的使用 2.1、构造函数 2.2、赋值操作符重载 2.3、迭代器使用 2.4、容量操作 2.5、元素访问 2.6、修改操作 2.7、其…

从0开始学人工智能测试节选:Spark -- 结构化数据领域中测试人员的万金油技术(三)

分布式计算原理 分布式计算的原理总结一句话就是&#xff1a;分而治之。 把数据分片&#xff0c;存在不同的机器中&#xff0c;解决数据存储的压力。客户端和服务端之间通过相关协议来自动的完成在不同的机器之间进行数据的存取&#xff0c;用户并不感知数据的物理存储结构。 用…