news 2026/5/2 12:40:23

0基础积C语言跬步之C语言数据类型和变量

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
0基础积C语言跬步之C语言数据类型和变量

首先声明,此博客不照搬抄袭,存在自己的见解,我所使用的编译器是VS2022

目录

1. 数据类型介绍

2. signed和unsigned

3. 数据类型的取值范围

4. 变量

5. 算术操作符:+、-、*、/、%

6. 赋值操作符:=和复合赋值

7. 单⽬操作符:++、--、+、-

8. 强制类型转换

9. scanf和printf介绍


1. 数据类型介绍

首先,C语言中每个数据都强烈建议需要初始化,未初始化可能会导致程序出bug

它们都有一个格式:数据类型+数据名=初始化值,如int a=0;float b=0.0f;char c=‘*’;

C语言中每个数据都有类型,整数有整数的类型,叫做整型(int);小数有小数的类型,叫浮点型(float);字符有字符的类型,叫做字符型(char);还有一个bool类型,用于判断对错

今天我们主要来介绍一下内置类型:

首先是字符型,顾名思义,用于存放字符数据的数据类型例如‘/0’ , '/n' , 'a' , b' , '\060'

char a=‘a’; [signed] char //有符号的 unsigned char //⽆符号的

然后是整型,用于存放整数数据的数据类型例如1,2,3

int a=0; //短整型 short [int] [signed] short [int] //有符号短整型 unsigned short [int] //无符号短整型 //整型 int [signed] int //有符号整型 unsigned int //无符号整型 //⻓整型 long [int] [signed] long [int] //有符号长整型 unsigned long [int] //无符号长整型 //长长整型 long long [int] [signed] long long [int] //有符号长长整型 unsigned long long [int] //无符号长长整型

接下来是浮点型,用于存放浮点数的数据类型例如3.14 , 6.18

float a=0.0f //浮点型 float //单精度浮点型 double //双精度浮点型 long double //长双精度浮点型

接下来是布尔类型,布尔类型比较特殊,其内容只存true或者false,是专门用来判断对错的类型

但使用布尔类型需要注意,要包含头文件#include <stdbool.h>

#include <stdbool.h> _Bool flag = true; bool flag = false; //布尔类型 _Bool bool

注意!!!

使用_Bool 的时候不需要头文件#include <stdbool.h>,不需要任何头文件,就能使用

但使用bool的时候必须要头文件#include <stdbool.h>

再注意!!!

注意区分:#include <stdio.h>是库函数输入输出的头文件,stdio> = Standard Input & Output,使用输入输出函数时才是需要用这个头文件

而使用char,float,double,int,_Bool时都是不需要使用头文件的,因为这些都是语言本身自带的关键字,编译器一出生就认识,不需要头文件告诉它这是什么

各种数据类型的长度

数据类型的长度就是此数据类型可以储存数据大小的长度范围

sizeof操作符

此时我们需要一个操作符:sizeof,用于计算数据类型长度的大小,单位是字节(byte)

sizeof(数据类型)

sizeof 表达式

1.sizeof 的操作数如果不是数据类型,是表达式的时候,是可以省略掉后边的括号的。

sizeof 后边的表达式是不真实参与运算的,根据表达式的类型,类型计算来得出对应的大小。

sizeof 的计算结果是 size_t 类型的。size_t就是无符号整型的意思,打印用%zu占位符最准确,%zu专为sizeof服务,也可以用%zd,%zd用于打印有符号整数

#include <stdio.h> int main() { int a = 10; printf("%zu\n", sizeof(a)); printf("%zu\n", sizeof a);//a是变量的名字,可以省略掉sizeof后边的() printf("%zu\n", sizeof(int)); printf("%zu\n", sizeof(3 + 3.5));//3是int整型,3.5是double双精度浮点型,int+double-->double return 0; }

其中sizeof(3+3.5)并没有真实去计算表达式的结果,就是没有计算3+3.5=6这个结果,而是计算的表达式的类型,其中3是int整型,3.5是double双精度浮点型,int+double-->double

下面给出类型的计算公式:

一、整数 + 整数:

  • char + char →int
  • char + short →int
  • char + int →int
  • short + int →int
  • int + int →int
  • int + long →long
  • long + long →long

二、整数 + 浮点数

  • char + float →float
  • short + float →float
  • int + float →float
  • char + double →double
  • short + double→double
  • int + double →double
  • long + double →double

三、浮点数 + 浮点数

  • float + float →float
  • float + double →double
  • double + double →double

四、包含 _Bool(C99 布尔)

  • _Bool + char →int
  • _Bool + int →int
  • _Bool + float →float
  • _Bool + double →double

总结:(记住以下的规律就好)

  • 比 int 小的类型(char/short/_Bool)运算,一律先转 int
  • 有 float 没 double → 结果 float
  • 只要有 double → 结果一定是 double
  • 整数 + 浮点数 → 结果是浮点数

其实也很好理解,3+3.5结果是小数,所以结果会提升至double类型,这是必然滴

以后在写代码时遇到:

int a = 5; float b = 2.2f; double c = 3.3; int ret = a + c; // 本来是double,强行塞进int❌ double ret =a + c; //int + double的类型应该是double✅

这三个数,不知道这些数据类型的相加规则,就会像上述这样结果本来是double类型,最后却强行塞进int,导致警告:

注意!!!

在 C 语言里,_Bool本质就是个只能存 0 或 1 的整数类型,所以它归在整数家族里。

底层就是整数

  • true→ 就是整数1

  • false→ 就是整数0

数据类型长度

下面给出内置类型数据类型的计算写法与长度:

#include <stdio.h> int main() { printf("char=%zu\n", sizeof(char));//char 1 printf("_Bool=%zu\n", sizeof(_Bool));//_Bool 1 printf("short=%zu\n", sizeof(short));//short 2 printf("int=%zu\n", sizeof(int));//int 4 printf("long=%zu\n", sizeof(long));//long 4 在64位下long 8 printf("long long=%zu\n", sizeof(long long));//long long 8 printf("float=%zu\n", sizeof(float));//float 4 printf("double=%zu\n", sizeof(double));//double 8 printf("long double=%zu\n", sizeof(long double));//long double 8 return 0; }

2. signed和unsigned

signed和unsigned在C语言中是专门用来修饰int整型和char字符型的

signed的意思是有符号的,包含正负整数

unsigned的意思是无符号的,只包含正整数和0

在C语言中,int类默认就是带有符号的,所以signed int就等于int,所以signed一般省略不写,如:

注意[ ]表示里面的内容表示可以省略

[signed] int a;

signed [int] a;

unsigned [int] a;

整数变量用unsigned声明的好处是,可以表达或在内存中存储的最大整数值可以扩大一倍,⽐如,16位的 signed short int 的取值范围是:-32768~32767,最⼤是32767;⽽ unsigned short int 的取值范围是:0~65535,最⼤值增⼤到了65,535。

short类型占两个字节,16个bit位,所以是16位

char字符也可以设置signed和unsigned类型:

signed char c; // 范围为 -128 到 127

unsigned char c; // 范围为 0 到 255

但要注意的是:char在C语言中是有符号还是无符号的,是靠编译器来决定的,每个编译器下,char可能是有符号的,也可能是无符号的,所以signed char!=char,所以在用这两个关键字描述char时不能像int一样省略不写

3. 数据类型的取值范围

每个数据类型都有自己所能存储的最大值和最小值,当我们知道了最大值和最小值时,我们就能更好的在场景下更准确的使用我们的数据类型

limits.h ⽂件中说明了整型类型的取值范围

float.h 这个头⽂件中说明浮点型类型的取值范围

可以转到文档进去查看

常见类型取值范围:

类型字节取值范围
char1-128~127 或 0~255(看系统)
signed char1-128~127
unsigned char10~255
short2-32768~32767
unsigned short20~65535
int4-2147483648~2147483647
unsigned int40~4294967295
float4±10⁻³⁸~±10³⁸
double8

±10⁻³⁰⁸~±10³⁰⁸

4. 变量

在C语言中,创建变量时都需要初始化,例如int a=0;把变量a初始化为0

变量初始化的公式:数据类型+变量名=初始化值

4.1变量的分类

变量分为全局变量和局部变量

• 全局变量:就是在主函数main()函数之外设置或者说在大括号外部定义的变量就是全局变量

全局变量变量可以在整个工程中使用,直到工程结束才销毁

局部变量:在所有函数的大括号里设置的变量就叫做局部变量

局部变量只能在创建此变量的括号内使用,出了此括号便不能使用,因为出了此括号就会被销毁!!!

有一种情况,局部变量和全局变量同名时,该是什么情况呢?

#inlcude <stdio.h> int a=10; int main() { int a=5; printf("%d",a);//会打印5 return 0; }

上述代码会打印5因为当局部变量和全局变量同名的时候,局部变量优先使用

变量不初始化的后果:

全局变量如果不初始化,比如int a;会自动初始化为0

局部变量如果不初始化,比如int a;会初始化为随机垃圾值

5. 算术操作符:+、-、*、/、%

就是完成加减乘除操作的,他们都是双目操作符,双目就是有两个操作数

#include <stdio.h> int main() { int a=20; int b=10; int ret1=0;int ret2=0;int ret3=0;int ret4=0;int ret5=0; ret1=a+b;//加法 ret2=a-b;//减法 ret3=a*b;//乘法 ret4=a/b;//除法 ret5=a%b;//求余 return 0; }

但要注意的是除法(/)这个操作符

除法操作符/

#include <stdio.h> int main() { float x = 6 / 4; printf("%f\n", x); // 输出 1.000000 return 0; }

如上图所示,尽管x已经设置成了float类型,但打印时用%f并不会打印出正确的小数这是为什么?

这是因为在C语言中的整数除法是整除,只会返回整数部分,丢弃小数部分,想要得到正确小数的结果,那么在两个运算数中,必须有一个浮点数,才会进行浮点数运算

例如:

#include <stdio.h> int main() { float x = 6.0 / 4; // 或者写成 6 / 4.0 printf("%f\n", x); // 输出 1.500000 printf("%.2f\n",x); //输出1.50 return 0; }

当只用%f时,默认输出六位小数;

如果想要控制小数的位数,那么可以在%f中加入.2,也就是%.2f表示限制小数点位数只输出两位

再给出一段代码便于理解除法浮点数的运算:

#include <stdio.h> int main() { float a = 10.0f; int b = 5; float ret = a / b; //其中a为浮点数的值,所以会进行浮点数运算 printf("%f\n", ret); //结果为2.000000 return 0; }

求模(余)操作符%

有个要注意的点:求模(余)操作符%的两个操作数都只能是整数,用于整数运算,不能用于浮点数,而且此操作符的结果的正负号是由第一个操作符的符号来决定的,下面给出一些例子:

#include <stdio.h> int main() { printf("%d\n", 11 % -5); // 1 printf("%d\n",-11 % -5); // -1 printf("%d\n",-11 % 5); // -1 return 0; }

6. 赋值操作符:=和复合赋值

赋值赋值操作符=

赋值操作符顾名思义:用于给变量赋值的操作符(=)如:int a=0;

当然赋值操作符也是可以进行连续赋值运算的,

例如:

#include <stdio.h> int main() { int a = 2; int b = 5; int c = b = a + b;//连续赋值 printf("%d\n", c);//结果是7 return 0; }

连续赋值运算的规则是,从右到左计算,例如上述,是先计算b=a+b,把a+b等于7的值赋给了b,此时b==7,然后再计算int c=b,所以c的值就是7

复合赋值操作符

a=a+b可以简化成a+=b

a=a-b可以简化成a-=b

下面给出复合赋值操作符的表格

运算符写法等价于
+=a += ba = a + b
-=a -= ba = a - b
*=a *= ba = a * b
/=a /= ba = a / b
%=a %= ba = a % b

7. 单目操作符:++、--、+、-

+ -

首先+就是表示整数的,例如+5,一般省略不写

而-就是表示负数的,可以把正数变为负数,也可以把负数变正数

++ --

分为前置++(--)和后置++(--)

前置的意思就是放在操作数的前面,如:++a,意思是先加后使用

后置的意思就是放在操作数的后面,如:a++,意识是先使用后加

8. 强制类型转换

强制类型转换的语法是:(转化类型)数据,如(int)3.14,(float)b

#include <stdio.h> int main() { int a = 5, b = 2; double c = a / b; // 5/2 是整数除法 → 2 printf("%d\n",c); //c打印出来是2 double d = (double)a / b;// 先把 a 转 double → 5.0/2=2.5 printf("%d\n",d); //d打印出来是2.5 return 0; }

以上代码(double)a会把a强制转化为浮点数5.0从而进行小数的除法运算,最终得出正确结果5.0/2等于2.5

9. scanf和printf介绍

scanf是用于在屏幕上输入数值的库函数

printf是用于在屏幕上打印数值的库函数

它们都需要占位符来打印所想要打印的数值

printf函数

pirntf("%d\n",10);//%d就是用来打印整数的占位符

printf函数中有n个占位符,就有n+1个参数,例如上述中的:一个占位符%d,两个参数:"%d\n"和10

还有很多常用的占位符如下表所示:

占位符作用示例输出
%d输出int 十进制整数printf("%d", 123);123
%ld输出long 长整型printf("%ld", 123456L);
%lld输出long longprintf("%lld", 123LL);
%u输出unsigned 无符号整数printf("%u", -1);
%c输出单个字符printf("%c", 'A');A
%s输出字符串printf("%s", "hello");hello
%f输出float /double 浮点数printf("%f", 3.14);3.140000
%lf输入用 double,printf 里同 % fscanf("%lf", &x);
%.2f保留2 位小数printf("%.2f", 3.1415);3.14
%x小写十六进制输出printf("%x", 26);1a
%X大写十六进制输出printf("%X", 26);1A
%o八进制输出printf("%o", 8);10
%p输出指针地址printf("%p", &a);
%%输出一个百分号本身

printf("%%");%

printf里的一些占位符用法说明

在占位符%d中加入数字,可以限制数字输出在屏幕上的格数,如下方代码所示:

#include <stdio.h> int main() { printf("%5d\n", 123); //表示限制最小宽度为五个格子,并且右对齐: 123 printf("%-5d\n", 123);//表示限制最小宽度为五个格子,并且左对齐:123 printf("%-5d\n", 123456);//如果要打印的数超出限制范围,则正常打印,不用管左对齐还是右对齐:12345 return 0; }

运行截图:

对于%f,在其中加数字则是限制最小宽度,如%5.2f

#include <stdio.h> int main() { float a=3.1415926f;//%f,规定就固定打印六位小数 printf("%5f\n",a); //会打印3.141593,最小宽度是5,当打印值超过最小宽度时会正常打印 printf("%f\n",a); //会打印3.141593,因为%f默认输出 6 位小数,不够补0,多了四舍五入。 printf("%5.2f\n",a); //会打印 3.14,最小宽度是5,小数的占两位,右对齐 printf("%-5.2f\n",a); //会打印3.14 ,最小宽度是5,小数的占两位,左对齐 return 0; }

运行截图:

对于%d,%+d表示总是显示正负号

一般来说,正数是不会显示正号的,只有负数会显示负号,但当我们再d前加个+时,就表示总是显示正负号

#include <stdio.h> int main() { printf("%+d\n", 12); // 输出 +12 ,只有在d前加+号,才可以达到总是显示正负号的效果 printf("%d\n", +12); // 输出 12 ,尽管在12前加+号,输出时也不会显示正号 printf("%+d\n", -12); // 输出 -12 printf("%d\n", -12); // 输出 -12 return 0; }

运行截图:

%s是用来输出字符串的,%.5s贼可以限制输出的个数,只输出前五个字符,而%5s表示至少输出5个字符的长度,不够补空格。和%d一样,%5s右对齐,%-5s左对齐。也可以%10.5s,表示总宽度为10,而只截取前五个字符,不够补空格

int main() { printf("%.5s\n", "hello world");//只输出hello printf("%5s\n", "hello world");//要输出的字符超过了最小限制宽度,所以正常打印 printf("%8s\n", "hello");//输出的字符个数不够8位,只有5位,且右对齐,所以会在左边补三个空格 printf("%-8s\n", "hello");//输出的字符个数不够8位,只有5位,且左对齐,所以会在右边补三个空格 printf("%8.5s\n", "hello world");//.5限制只取前五个字符hello,%8.5是右对齐,至少输出8个宽度 return 0; }

运行截图:

在C语言中,最小宽度和限制小数的值都可以用*来代替,并在printf中的参数写出来

#include <stdio.h> int main() { printf("%*.*f\n", 6, 2, 0.5);//原本是printf("%6.2f\n");6,2,可以用*代替 return 0; }

运行截图:

scanf函数

基本用法

scanf函数就是用于输入变量的数值的函数,用scanf输入后便可以用printf输出

给出一段简单代码来说明scanf的用法

#include <stdio.h> int main() { int score = 0; printf("请输⼊成绩:"); scanf("%d", &score); //输入成绩 printf("成绩是:%d\n", score); //打印成绩 return 0; }

运行截图:

注意!!!

scanf函数里的参数必须是地址,所以在使用scanf时都会在变量前加入取地址符号&

如上图代码scanf("%d", &score); 只有当要输入的值本身就是地址时才不需要&,比如输入字符串数组的值

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

int main() { int i = 0, j = 0; float x = 0.0f; double y = 0.0; //上面初始化int i = 0, j = 0; 等同于int i=0;int j=0; scanf("%d%d%f%lf", &i, &j, &x, &y); printf("%d %d %f %lf",i,j,x,y); return 0; }

补充:初始化int i = 0;int j = 0 ;可以简化成 int i=0,j=0;

运行截图:

scanf会自动过滤空白字符,包括空格、制表符、换行符,如上图我1跟-20之间输入了换行符,-20和3.14之间输入了空格,3.14和-4.0e3之间输入了两个制表符,但都自动过滤忽略,不影响scanf解读,下方正常打印

补充:-4.0e3采用的是科学计数法,计算为-4.0 × 10³,结果为-4000.0,如果是3e3,计算为3 × 10³,结果为3000.0,为double类型的小数。

打印结果为六位小数是因为% f 和 % lf 和%Lf,都默认打印6 位小数。

记住:只要是小数、或带 e 的科学计数法,默认都是 double 类型

上面的示例中,scanf每读取一个数据后,遇到了会自动过滤的字符,就会自动过滤,直到读取到下一个占位符所对应的数值,存到对应的变量中,然后又遇到会自动过滤的字符,再次自动过滤,直到继续读取到下一个占位符所对应的数值,并存入占位符相对应的变量中

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

比如输入 123abc时,scanf("%d%c",&n,&ch),刚开始输入的时候,是把123abc都放在缓存区里,%d会读取整数,把123读走放入变量n,因为下个字符a不属于整型字符,不符合占位符的条件,所以%d读取结束,此时缓存区还剩下abc和隐藏的\0,%c会读取一个字符a,放入变量ch中,剩下的bc将不会被读取,依然放在缓存区里,直到再使用scanf继续读取,下面给出代码

#include <stdio.h> int main() { int n; char ch; // 输入:123abc scanf("%d%c", &n, &ch); printf("n = %d\n", n); printf("ch = [%c]\n", ch); return 0; }

运行截图:

scanf的返回值

scanf () 的返回值是一个整数,表示成功读取的变量个数。如果没有读取任何项,或者匹配失败,则返回 0。如果在成功读取任何数据之前,发生了读取错误或者遇到文件结尾,则返回常量 EOF (-1)。EOF——end of file文件结束标志

下面给出代码演示:

#include <stdio.h> // 清空输入缓存关键,多次连续使用 scanf 时,必须清空输入缓存,否则会互相干扰! // 除非上一个scanf把缓存区的内容读完了,那么就不需要了 void flush() { while (getchar() != '\n'); } int main() { int a=0, b=0; int ret=0; // ------------- 测试1:输入 10 20 printf("输入两个整数(如:10 20):"); ret = scanf("%d%d", &a, &b); printf("scanf返回值:%d\n\n", ret); flush(); // 清空缓存,避免影响下一次输入 // ------------- 测试2:输入 abc printf("输入字母(如:abc):"); ret = scanf("%d", &a); printf("scanf返回值:%d\n\n", ret); flush(); // 清空缓存 // ------------- 测试3:触发 EOF printf("输入时按 Ctrl+Z 再回车(EOF):"); ret = scanf("%d", &a); printf("scanf返回值:%d(即 EOF = %d)\n", ret, EOF); return 0; }

运行截图:

测试1中:scanf读取了两个整型的数值放入变量中,返回2

测试2中:scanf本来要读取整型数值,却输入了字符类型的数值,%d无法读取,所以一个数值都没有读取到,返回0

测试3中:我们输入三个(ctrl+z+回车),主动触发文件结束,返回EOF(-1)

解读一下:

void flush()

{
while (getchar() != '\n')

{

;

}
}

此函数是用于,清空输入缓存关键,多次连续使用 scanf 时,必须清空输入缓存,否则会互相干扰!除非上一个scanf把缓存区的内容读完了,那么就不需要了

getchar的作用是每次读取一个字符,此函数循环内部内容为空,表示什么都不做,只读取,读取完就丢,直到读取完\n后,就结束循环,而我们scanf的输入,当输入数值字符在缓存区时,最终都是以\n(回车)结尾,才能输入到程序中去,此循环刚好把\n及\n之前的无用缓存字符全部清空,防止了scanf之间的互相干扰,以来到达可以正确输入读取的效果

scanf中的占位符

scanf的占位符与printf基本一致,但用读取规则稍有不同,比如%c,%s

scanf有个占位符printf里没有:%[ ]

下面我来逐一讲解一下:

%c

%c不忽略空白字符,总是返回当前第一个字符,无论该字符是否为空格。如果要强制跳过字符前的空白字符,可以写成 scanf(" %c", &ch) ,即 %c 前加上⼀个空格,表示跳过零个或多个连续的空白字符。%s前加一个空格也能达到这种效果:scanf(" %s",&ch);

#include <stdio.h> void flush() { while (getchar() != '\n') ; } int main() { char ch[10] = { '\0' }; //测试一:输入( abc),不会跳过空白字符 printf("请输入 abc\n"); scanf("%3c",ch); printf("打印结果:%s\n\n", ch); flush(); //测试一:输入( a b c),只会跳过最前方的连续的空白字符,跳过之后,连续读取三个字符,读取过程中如果再遇到空白字符,无法再跳过 printf("请输入 a b c\n"); scanf(" %3c", ch); printf("打印结果:%s\n\n", ch); flush(); return 0; }

运行截图:

%3c在scanf中的效果是:连续读取 3 个字符(包括空格、回车!),存入数组 ch

测试一:输入( abc),不会跳过空白字符,%3c只读取前三个字符,所以会打印( ab)

测试二:输入( a b c),只会跳过最前方的连续的空白字符,跳过之后,连续读取三个字符,读取过程中如果再遇到空白字符,无法再跳过,所以此处跳过了a前面的三个空格,然后从a开始读取,%3往后读取三个字符(a b),所以最后会打印(a b)

%s

它的规则是: 从当前第一个非空白字符开始读起,直到遇到空白字符(即空格、换行符、制表符等)为止。和上述( %3c)c有点像,不同之处在于%s前不需要加空格,就可以跳过开头的空白字符,但当%s遇到下一个空白字符的时候,就会自动停止,比如输入Hello world,只会读取Hello,遇到空白字符就不读了

#include <stdio.h> int main() { char ch[100] = { '\0' }; scanf("%8s", ch); //输入Hello world printf("%s\n", ch); //打印 Hello return 0; }

运行截图:

如图所示,开头自动忽略了连续的空格,后续使用了%8s来限制读取前8位字符,但当后续遇到空白字符时,就会停止读取,并在读取的字符串末尾自动添'\0'用于结束字符串的读取,所以只打印Hello

%[ ]

%[ ]只读取[匹配字符集]内的字符一旦遇到不在集合内的字符,会立即停止读取。

可以完美的解决%s遇到空白字符就会停止读取的限制,如%[^\n]

^

  • 写在代码表达式里:^异或运算符
  • 写在%[ ]里:^排除符号,表示非、除了
  • %[^\n]表示除了'\n',遇到的字符全部读取

比如:

#includ <stdio.h> int main() { char ch[100] = { 0 }; scanf("%[^\n]s", ch); //输入Hello world printf("%s\n", ch); //打印 Hello world return 0; }

运行截图:

scanf赋值忽略符%*

有时,用户输入的格式不符合规定的格式,如:

#include <stdio.h> int main() { int year = 0;int month = 0; int day = 0; scanf("%d-%d-%d", &year, &month, &day); //输入2026-4-4 printf("%d %d %d\n", year, month, day); //打印2026 4 4 return 0; }

运行截图:

但当用户输入别的格式时,如2026/4/4,scanf就会解析错误,结果如下:

运行截图:

本来应该读取的-,现在输入的是/,scanf读取错误,解析错误,会直接停止工作,后续month和day的值都为初始化的0,所以会有此结果

此时!!!

我们可以使用scanf赋值忽略符%*,来忽略这些打错的格式

%*的作用是该占位符读取后不会返回值,解析后就将值丢弃,不会存储于变量中

下图代码展示其作用,如:

#include <stdio.h> int main() { int year = 0;int month = 0;int day = 0; scanf("%d%*c%d%*c%d", &year, &month, &day); printf("%d %d %d\n", year, month, day); return 0; }

运行截图:

上面示例中,%*c 就是在占位符的百分号后面,加入了赋值忽略符 * ,表示这个占位符没有对应的变量,解读后不必返回,然后继续解读下一个占位符对应的数据

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/2 12:39:36

WorkshopDL终极指南:无需Steam客户端快速下载创意工坊模组

WorkshopDL终极指南&#xff1a;无需Steam客户端快速下载创意工坊模组 【免费下载链接】WorkshopDL WorkshopDL - The Best Steam Workshop Downloader 项目地址: https://gitcode.com/gh_mirrors/wo/WorkshopDL 你是否厌倦了为了下载几个模组而必须安装庞大的Steam客户…

作者头像 李华
网站建设 2026/5/2 12:36:33

猫抓浏览器扩展:3分钟掌握免费下载网页视频的终极解决方案

猫抓浏览器扩展&#xff1a;3分钟掌握免费下载网页视频的终极解决方案 【免费下载链接】cat-catch 猫抓 浏览器资源嗅探扩展 / cat-catch Browser Resource Sniffing Extension 项目地址: https://gitcode.com/GitHub_Trending/ca/cat-catch 你是否曾经遇到过想要保存在…

作者头像 李华
网站建设 2026/5/2 12:33:30

【无标题】核心组件大换血:Backbone与Neck魔改篇:YOLO26引入Swin Transformer V2:解决高分辨率图像检测的全局视野痛点

写在前面 2026年,目标检测领域的竞争已经进入深水区。YOLO系列凭借极致的实时性能持续引领工业落地,但在遥感检测、无人机航拍、医学影像、工业质检等高分辨率应用场景中,原生YOLO的纯卷积架构正面临“全局视野缺失”的根本性困境。 本文将从底层原理出发,系统阐述为什么…

作者头像 李华
网站建设 2026/5/2 12:31:33

体验Taotoken多模型聚合带来的稳定与低延迟API调用

体验Taotoken多模型聚合带来的稳定与低延迟API调用 1. 多模型调用的实际挑战 在日常开发中&#xff0c;我们经常需要调用不同的大模型来完成各类任务。传统方式下&#xff0c;开发者需要为每个模型单独维护API密钥、处理不同的接入协议&#xff0c;并面对单一服务波动带来的中…

作者头像 李华