首页 > 其他分享 >C语言数据类型和变量(下)

C语言数据类型和变量(下)

时间:2024-08-22 17:51:14浏览次数:10  
标签:main return 变量 int scanf 数据类型 占位 printf C语言

目录

1. 算数操作符:+、-、*、/、%

1.1 +和-

1.2 *

5.3 /

5.4 %

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

2.1 连续赋值

6.2 复合赋值符

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

3.1 ++和--

3.1.1 前置++

3.1.2 后置++

3.1.3 前置--

3.1.4 后置-- 

3.2 + 和 - 

4. 强制类型转换 

5. scanf和printf介绍

5.1 printf

5.1.1 基本用法

5.1.2 占位符

5.1.3 占位符例举

 5.1.4 输出格式

5.1.4.1 限定宽度

5.1.4.2 总是显示正负号

5.1.4.3 限定小数位数

5.1.4.4 输出部分字符串

5.2 scanf

5.2.1 基本用法

5.2.2 scanf的返回值

5.2.3 占位符

5.2.4 赋值忽略符


1. 算数操作符:+、-、*、/、%

在写代码的时候,一一定会设计到计算。

C语言中为了方便运算,提供了一系列的操作符,其中有一组操作符叫做:算数运算符,分别是:+ - * / %,这些操作符都是双目操作符。

注:操作符也被叫做:运算符,是不同的翻译,意思是一样的。

1.1 +和-

//加号
int main()
{
	// + :操作符  33,42:操作数
	//33是左操作数  42是右操作数,所以+也叫双目操作符,有两个操作数的操作符
	printf("%d\n", 33 + 42);
	//两个变量相加
	int a = 10;
	int b = 20;
	printf("%d\n", a + b);
	//一个变量和一个数字相加
	printf("%d\n", a + 10);
	return 0;
}
//减号
int main()
{
	printf("%d\n", 33 - 42);

	int a = 10;
	int b = 20;
	printf("%d\n", a - b);

	printf("%d\n", a - 10);
	return 0;
}

1.2 *

运算符*是用来完成乘法。

在C语言中"*"就是乘号,这个和数学中不一样。

int main()
{
	printf("%d\n", 5 * 5);
	int a = 10;
	int b = 20;
	printf("%d\n",a * b);
	printf("%d\n",a * 10);
	return 0;
}

5.3 /

运算符 / 是用来完成除法。

除号的两端是整数,执行的是整数除法,得到的结果也是整数。

int main()
{
	printf("%d\n", 9 / 3);//3

	printf("%d\n", 10 / 4);
	//从数学的角度看,10 / 4是2.5,但这里算出的不是2.5,结果是2。
	return 0;
}

如果希望得到浮点数的结果,两个运算数必须至少有一个浮点数,这时C语言就会进行浮点数除法。

int main()
{
	printf("%d\n", 9 / 3);//3

	printf("%d\n", 10 / 4);
	//从数学的角度看,10 / 4是2.5,但这里算出的不是2.5,结果是2。

	printf("%f\n", 10 / 4.0);//除号两端至少有一个数是浮点数,用%f打印
	//这样结果就是浮点数了,也可以写成10.0/4或者10.0/4.0

	return 0;
}

再看一个例子: 

#include <stdio.h>
int main()
{
	int score = 5;
	score = (score / 20) * 100;
	return 0;
}

上面的代码,你可能觉得经过计算,score会等于25,但实际上score等于0。这是因为score / 20是整数,会得到一个整数值0,所以乘以100后得到的也是0。

为了得到预想的结果,可以将除数20改成20.0,让整数除法变成浮点数除法。

#include <stdio.h>
int main()
{
	int score = 5;
	score = (score / 20.0) * 100;
	printf("%f", score);
	return 0;
}

5.4 %

运算符%表示求模(余)运算,即返回两个整数相除的余值。这个运算符只能用于整数,不能用于浮点数。

#include <stdio.h>
int main()
{
	printf("%d\n", 10 / 3);//10 / 3 = 3 ... 1,得到的是整除之后的余数
	//1. 就是算一个数除两一个的余数
	//2. 计算一个数能不能被另一个数整除
	int n = 0;
	if (n % 2 == 0);//如果余数是0就表示能被整除,不是0就表示不能被整除
	return 0;
}

取模运算符只能用于整型。

负数求模的规则是,结果的正负号由第一个运算符的正负号决定。

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

上面示例中,第一个 运算符的正负号(11或-11)决定了结果的正负号。

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

在创建变量的时候给一个初始值叫初始化,在变量创建好后,再给一个值,这叫赋值。

#include <stdio.h>
int main()
{
	int a = 0;//初始化

	a = 10;//赋值 - 这个时候就要依赖赋值操作符,这里的等号就是赋值操作符

	return 0;
}

2.1 连续赋值

赋值操作符也可以连续赋值。

#include <stdio.h>
int main()
{
	int a = 3;
	int b = 5;
	int c = 0;
	c = b = a + 3;//连续赋值,从右向左依次赋值
	return 0;
}

C语言虽然支持这种连续赋值,但是写出的代码不容易理解,建议还是拆开来写,这样方便观察代码的执行细节。

#include <stdio.h>
int main()
{
	int a = 3;
	int b = 5;
	int c = 0;
	b = a + 3;
	c = b;
	return 0;
}

这样写,在调试的时候,每一次赋值的细节都是可以很方便观察的。

6.2 复合赋值符

#include <stdio.h>
int main()
{
	int a = 0;
	a = a + 10;//a加上10再赋给a,就是让a加上10.
	a += 10;//也可以这样写,这句代码和上面的是等价的 - 复合赋值

	a = a - 3;
	a -= 3;
	//+=,-=都可以,那么*=、/=、%=都是可以的

	return 0;
}

这样的代码C语言提供了更加方便的写法。

#include <stdio.h>
int main()
{
	int a = 10;
	a += 3;
	a -= 2;
	return 0;
}

C语言中提供了复合赋值符,方便我们编写代码。

+=    -=
*=    /=    %=
>>=   <<=
&=    |=    ^=

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

签名吗介绍的操作符都是双目操作符,有两个操作数的。C语言中还有一些操作符只有一个操作数,被称为单目操作符。++、--、+(正)、-(负)就是单目操作符。

3.1 ++和--

++是一种自增的操作符,又分为前置++和后置++,--是一种自减的操作符,也分为前置--和后置--。

#include <stdio.h>
int main()
{
	int a = 5;
	//a = a + 1;//a自增1
	//a++;//也可以这样写
	++a;//还可以这样写
	printf("%d\n", a);
	// 当然 -- 也是类似
	return 0;
}
3.1.1 前置++
#include <stdio.h>
int main()
{
	int a = 5;
	int b = ++a;//前置++
	//前置++的计算方式是先++后使用
	// 赋值步骤:a = a+1 , b = a
	// 结果:a = 6 , b = 6
	printf("a = %d\n", a);
	printf("b = %d\n", b);
	return 0;
}

计算口诀:先+1,后使用 

a原来是5,先+1后a变成6,再使用就是赋值给b,b得到的也就是6,所以计算完成后,a和b都是6,相当于下面的代码。

#include <stdio.h>
int main()
{
	int a = 10;
	a = a + 1; 
	int b = a;
	return 0;
}
3.1.2 后置++
#include <stdio.h>
int main()
{
	int a = 5;
	int b = a++;//后置++
	//后置++的计算方式是先使用后++
	// 赋值步骤:b = a ,a = a+1
	// 结果:a = 6 , b = 5
	printf("a = %d\n", a);
	printf("b = %d\n", b);
	return 0;
}

计算口诀: 先使用,后+1 

a原来是5,先使用就是先赋值给b,b得到了5,然后再+1,然后a就变成了6,所以执行结束后a是6,b是5,相当于下面的代码。

#include <stdio.h>
int main()
{
	int a = 10;
	int b = a;
	a = a + 1;
	return 0;
}
3.1.3 前置--

计算口诀: 先-1,后使用

#include <stdio.h>
int main()
{
	int a = 5;
	int b = --a;//前置--
	//前置--的计算方式是先--后使用
	// 赋值步骤:a = a-1 , b = a
	// 结果:a = 4 , b = 4
	printf("a = %d\n", a);
	printf("b = %d\n", b);
	return 0;
}

3.1.4 后置-- 

计算口诀:先使用,后-1

#include <stdio.h>
int main()
{
	int a = 5;
	int b = a--;//后置--
	//后置--的计算方式是先使用后--
	// 赋值步骤:b = a , a = a-, 
	// 结果:a = 4 , b = 5
	printf("a = %d\n", a);
	printf("b = %d\n", b);
	return 0;
}

注意:

#include <stdio.h>
int main()
{
	int a = 5;
	//printf("%d\n", --a);//前置--,先--,后打印 - 4;
	printf("%d\n", a--);//后置--,先打印,后--
	printf("%d\n", a);
	return 0;
}

3.2 + 和 - 

这里的+是正号,-是负号,都是单目操作符。

运算符+对正负值没有影响,是一个可以完全省略的运算符,但是写了也不会报错。

#include <stdio.h>
int main()
{
	printf("%d\n", 10);
	printf("%d\n", +10);//这段代码和上面的等价

	int a = 10;
	printf("%d\n", a);
	printf("%d\n", +a);//等价
	
}

运算符 - 用来改变一个值的正负号,负数的前面加上 - 会得到正数,正数的前面加上 - 会得到负数。

#include <stdio.h>
int main()
{
	int a = -10;
	printf("%d\n", -10);
	printf("%d\n", -a);//负的负10就是10,负负得正
	printf("%d\n", 10);
	return 0;
}

4. 强制类型转换 

在操作符中还有一种特殊的操作符是强制类型转换,语法形式很简单.

(类型)

代码:

#include <stdio.h>
int main()
{
	//int a = 10;//整数赋给整型没有问题
	
	//那如果我把3.14赋值给a
	int a = 3.14;
	//编译器会认为3.14是double类型,赋给整型,两边类型不一样,会报警告
	//double类型是8个字节,int是4个字节,会丢失数据

	//那么我就想把3.14赋值给a这个整型类型的话我们就得用强转
	int a = (int)3.14;
	//括号里面写int就是把3.14强转为整型,强转只取整数部分,小数部分丢弃
	printf("%d\n", a);

	return 0;
}

俗话说,强扭的瓜不甜,我们使用强制类型转换都是万不得已的时候使用,如果不需要强制类型转换就能实现代码,这样自然更好。

5. scanf和printf介绍

5.1 printf

5.1.1 基本用法

printf()的作用是将参数文本输出到屏幕,print是打印的意思,它名字里面的f表示format(格式化),表示可以定制输出文本的格式。

#include <stdio.h>
int main()
{
	printf("hello world");//printf是库函数,需要包含头文件stdio.h
	return 0;
}

 上面代码会在屏幕上输出一行文字"hello world"。

printf()不会在行尾自动添加换行符,允许结束后,光标就停留在输出结束的地方,不会自动换行。

为了让光标移动到下一行的开头,可以在输出文本的结尾,添加一个换行符\n。

#include <stdio.h>
int main()
{
	printf("hello world\n");
	return 0;
}

如果文本内部有换行,也是通过插入换行符来实现。

#include <stdio.h>
int main()
{
	printf("hello\nworld");
	return 0;
}

printf()是在标准库的头文件stdio.h定义的。使用这个函数之前,必须在源码文件头部引入这个头文件。 

5.1.2 占位符

printf()可以在输出文本中指定占位符。

所谓"占位符",就是这个位置可以用其他值来带入。

#include <stdio.h>
int main()
{
	printf("%d\n", 100);//这个地方的%d就是占位符
	//%d这个会输出一个整数,那么这个整数就是后面的值100,所以打印的话会打印100
	printf("%dabc\n", 100);
	//先打印%d位置的100,后打印abc
	return 0;
}

占位符第一个字符一律为百分号%,第二个字符表示占位符的类型,%d表示这里代入的值必须是一个整数。

常用的占位符除了%d,还有%s表示代入的是字符串。

#include <stdio.h>
int main()
{
	printf("%s will come tonight\n", "lisi");
	//%s是占位符号,这里要代入字符串,所以
	//结果就是lisi will come tonight
	printf("%s will come tonight\n", "wangwu");
	return 0;
}

输出文本里面可以有多个占位符。

#include <stdio.h>
int main()
{
	printf("%s says it is %d o'clock\n", "lisi", 12);//lisi说现在12点
	//这里的%s就被lisi替换,%d就被10替换,前面占位符的顺序是
	//字符串,整型,那么后面的顺序也就是字符串,整型
	printf("%s says it is %d o'clock\n", "cuihua", 18);//翠花说现在18点
	return 0;
}

注意: 

j既然写了占位符,那么参数就要一一匹配,要不然会有很大的问题。

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

5.1.3 占位符例举

printf()的占位符有许多种类,与C语言的数据类型相对应。下面按照字母顺序,列出常用的占位符,方便查找。

#include <stdio.h>
int main()
{
	//%c - 字符
	printf("this is %c\n", 'A');
	//%hd - 十六进制的short int类型
	printf("%hd\n", 100);
	//%ho - 八进制的short int类型
	printf("%ho\n", 100);
	//%x - 十六进制打印
	printf("%x\n", 15);
	return 0;
}
 5.1.4 输出格式

printf()可以定制占位符的输出格式。

5.1.4.1 限定宽度

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

#include <stdio.h>
int main()
{
	printf("%d\n", 123);
	printf("%5d\n", 123);//最少输出5位,输出为"  123"
	printf("%5d\n", 123456);//最小宽度5,如果长度超过5位,就按实际情况打印,这里6位
	return 0;
}

%5d表示这个占位符的宽度至少为5位。如果不满5位,对应的值的前面会添加空格。输出的值默认是右对齐,即输出内容前面会有空格,如果希望改成左对齐,在输出内容后面添加空格,可以在占位符的%的后面插入一个-号。

#include <stdio.h>
int main()
{
	printf("%dxxx\n", 123);
	printf("%-5dxxx\n", 123);//后面的xxx是为了更直观的看见补的空格
	return 0;
}

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

#include <stdio.h>
int main()
{
	printf("%lf\n", 123.45);//直接写123.45默认是double类型的值,所以用%lf
	//%f和%1f在打印的时候, 小数点后默认是打印6位
	printf("%12lf\n", 123.45);//最少12位,这个12位包含小数点和小数点后面的位数
	return 0;
}

%12lf表示输出的浮点数最少要占据12位,由于小数的默认显示u精度是小数点后6位,所以123.45输出结果的头部会添加两个空格。

5.1.4.2 总是显示正负号

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

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

5.1.4.3 限定小数位数

输出小数时,有的时候希望限定小数的位数。如果希望小数点后面只保留两位,占位符可以写成%.2f。

#include <stdio.h>
int main()
{
	printf("%lf\n", 123.45);//默认小数点后面打印6位
	printf("%.2lf\n", 123.45);//小数点后面打印2位
	printf("%.3lf\n", 123.45);//小数点后面打印3位
	printf("%.1lf\n", 123.45);//小数点后面打印1位,四舍五入了
	printf("%.8lf\n", 123.45);//小数点后面打印8位
	return 0;
}

这种写法可以与限定宽度占位符结合使用,既限制小数点位数,也限制宽度。 

#include <stdio.h>
int main()
{
	printf("%12.1f\n", 123.45);//.1表示小数点后只有一位,前面的12表示打印12位
	printf("%3.1f\n", 123.45);//这里写3是不行的,还是正常打印几位就几位
	return 0;
}

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

#include <stdio.h>
int main()
{
	printf("%12.1f\n", 123.45);
	printf("%*.*f\n",12, 1, 123.45);//12对应的就是第一个*,1对应的就是第二个*
	return 0;
}

5.1.4.4 输出部分字符串

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

5.2 scanf

当我们有了变量,我们需要给变量输入值就可以使用scanf函数,如果需要将变量的值输出在屏幕上的时候可以使用printf函数。

#include <stdio.h>
int main()
{
	int score = 0;
	printf("请输入成绩:");
	scanf("%d", &score);//输入操作
	//scanf函数中占位符的后面的参数需要的是地址
	//& 取地址操作符,&score - 取出score的地址
	printf("成绩是:%d\n", score);
	return 0;
}

画图演示:

 注:标准输入一般指的就是键盘,标准输出一般指的就是屏幕。

当我们写好代码运行的时候发现这里报错了,这种错误只在VS上出现,这里报错的原因就是scanf这个函数不安全,vs提示scanf函数不安全,考虑使用scanf_s来替换,但是如果使用scanf_s的话就需要知道这个函数的使用方式和scanf不完全相同,所以不建议用scanf_s,后面又说了,如果想要这个错误信息失效的话就请使用_CRT_SECURE_NO_WARNINGS,那这个应该怎么使用呢?

1.#define _CRT_SECURE_NO_WARNINGS 1 ,将这句代码放在使用scanf函数的.c文件的第一行。

2. 每次写代码都要在源文件前面加这段代码,特别的麻烦,那么我们可以适当的设置一下。 

在VS上这种.c/.cpp的文件,新建的时候其实是拷贝了newc++file.cpp的内容

如果在newc++file.cpp的文件中增加:#define _CRT_SECURE_NO_WARNINGS 1,以后新建.c/.cpp文件的时候就自动有这句话。

在自己VS的安装目录下找到该文件,然后使用记事本打开,将上面的话拷贝到里面,然后点击保存。

如果保存的时候权限不够可以先拷贝到桌面上,桌面的权限还是挺大的,然后修改好了直接拷贝到原位置,替换掉原来的文件。 (记得往桌面弄的时候一定是赋值,不是拖拽,要不然安装目录中就没有newc++file.cpp文件)。

当我们安装路径下面没有newc++file.cpp文件的时候都创建不了.c/.cpp文件。

注意:vs2022创建的时候必须是显示所有模板,京凑视图创建的也是没有的。

5.2.1 基本用法

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

程序运行到这个语句时,会停下来,等待用户从键盘输入。

用户输入数据,按下回车键后,scanf()就会处理用户的输入,将取存入变量。

它的原型定义在头文件stdio.h中。

scanf()的语法跟printf()类似。

scanf("%d",&i);

它的第一个参数是一个格式字符串,里面会放置占位符(与printf()的占位符基本一致),告诉编译器如何解读用户的输入,需要提取的数据是什么类型。

这是因为C语言的数据都是有类型的,scanf()必须提前知道用户输入的数据类型,才能处理数据。

它的其余参数就是存放用户输入的变量,格式字符串里面有多少个占位符就有多少个变量。

上面的代码中,scanf的第一个参数是%d,表示用户输入的应该是一个整数。%d就是一个占位符,%是占位符的标志,d表示整数。第二个参数&i表示,将用户从键盘输入的整数存入变量i。

下面是一次将键盘输入读入多个变量的例子。 

#include <stdio.h>
int main()
{
	int a = 0;
	int b = 0;
	float f1 = 0.0;
	float f2 = 0.0;
	scanf("%d %d %f %f", &a, &b, &f1, &f2);//占位符后面的参数必须是地址
	printf("%d %d %f %f", a, b, f1, f2);
	return 0;
}

上面示例中,格式字符串%d%d%f%f,表示用户输入的前两个是整数,后两个是浮点数,比如1 2 3.0 4.2,这四个依次放入a,b,f1,f2四个变量中。

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

所以,用户输入的数据之间,有一个或多个空格不影响scanf()解读数据。另外,用户使用火车键,将输入分成几行,也不影响解读。

上面示例中,用户分成四行输入,得到的结果与一行输入是完全一样的。每次按下回车键以后,scanf()就会开始解读,如果第一行匹配第一个占位符,那么下次按下回车键时,就会从第二个占位符开始解读。

Scanf()处理用户输入的原理是,用户的输入先放入缓存,等到按下回车键后,按照占位符对缓存进行解读。

解读用户输入时,会从上一次解读遗留的第一个字符开始,直到读完缓存,或者遇到第一个不符合条件的字符为止。 解读用户输入时,会从上一次解读遗留的第一个字符开始,直到读完缓存,或者遇到第一个不符合条件的字符为止。

#include <stdio.h>
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;
}

上面示例中,scanf()读取用户输入时,%d占位符会忽略起首的空格,从-处开始获取数据,读取到-13停下来,因为后面的,不属于整数的有效字符。这就是说占位符%d会读到-13。 

第二次调用scanf()时,就会从上一次停止解读的地方,继续往下读取。这一次读取的首字符是,由于对应的占位符是%f ,会读取到.45e12,这是采用科学计数法的浮点数格式。后面的#不属于浮点数的有效字符,所以会停在这里。

 由于scanf()可以连续处理多个占位符,所以上面的例子也可以写成下面这样。

#include <stdio.h>
int main()
{
	int x;
	float y;
	//用户输入 "    -13.45e12# 0"
	scanf("%d %f", &x,&y);
	printf("%d %f\n", x,y);
	return 0;
}

注意:一定要按照代码给定的格式输入输出的,如果不按照格式来,会导致问题的。 

5.2.2 scanf的返回值

 

scanf()是有返回值的,只不过我们没有接收它的返回值而已,编译器会报警告,我们不用scanf的返回值的话可以不用管。

scanf()的返回值是一个整数,表示成功读取到变量的个数。

如果没有读取任何项,或者匹配失败,则返回0。

如果在成功读取任何数据之前,发生了读取错误或者遇到读取到文件结尾,则返回常量EOF(-1)。

EOF - end of file 文件结束标志

#include <stdio.h>
int main()
{
	int a = 0;
	int b = 0;
	int c = 0;
	int d = 0;
	int ret = scanf("%d %d %d %d", &a, &b, &c, &d);
	int ret = scanf("a = %d b = %d c = %d d = %d\n", a, b, c, d);
	printf("ret = %d\n", ret);
	return 0;
}

完全读取的情况:

非完全读取的情况:

 读到第三个值的时候格式不匹配了,所以只读到了三个。

读到两个值,连续按三次Ctrl+z也会停下来,所以ret是2。 (正常的情况下应该按一次就可以了,VS需要按三次)

一个都没读到,返回的就是0。 

那么我上来就连续按三次Ctrl+z,返回的就是-1,也就是EOF,所以我们通常会拿scanf的返回值判断这次是读取成功了还是失败了。 scanf的返回值如果是EOF,就说明读取失败了,反之则读取成功了。

5.2.3 占位符

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

  • %c:字符。
  • %d:整数。
  • %f:float类型浮点数。
  • %lf:double类型浮点数。
  • %Lf:long double类型浮点数。
  • %s:字符串。
  • %[]:在方括号中指定一组匹配的字符(比如%[0-9]),遇到不在集合之中的字符,匹配将会停止。

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

如果想要强制跳过字符前的空白字符,可以写成scanf(" %c",&ch),即%c前加上一个空格,表示跳过零个或多个空白字符。

下面要特别说一下占位符%s,它其实不能简单的等同于字符串。它的规则是,从当前第一个非空白字符开始读起,直到遇到空白字符(空格,换行符,制表符等)为止。

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

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

 

写成%4s的时候最多只读4个,后面的字符会被丢弃,这样就不会有数组溢出的风险了。

5.2.4 赋值忽略符

有的时候,用户的输入可能不符合预定的格式。

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

上面的示例中,如果用户输入2024-08-22,就会正确解读出年、月、日。问题是用户可能输入其他格式,比如2024/08/22,这种情况下,scanf()解析数据就会失败。

为了避免这种情况,scanf()提供了一个赋值忽略符(assignment suppression character) *。只要把*加载任何占位符的百分号后面,该占位符就不会返回值,解析后被丢弃。

#include <stdio.h>
int main()
{
	int year = 0;
	int month = 0;
	int day = 0;
	scanf("%d%*c%d%*c%d", &year, &month, &day);
	//-就是字符,加上%c,但是想要忽略这个字符的话还得加上*
	printf("%d %d %d\n", year, month, day);
	return 0;
}

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

标签:main,return,变量,int,scanf,数据类型,占位,printf,C语言
From: https://blog.csdn.net/m0_74271757/article/details/140452994

相关文章

  • 算法与数据结构——基本数据类型与编码
    基本数据类型基本数据类型是计算机CPU可以直接进行运算的类型,在算法中直接被使用,主要包括以下几种整数类型byte、short、int、long。浮点数类型float、double,用于表示小数字符类型char,用于表示各种语言的字母、标点符号甚至表情符号等。布尔类型bool,用于表示“是”与“否”......
  • 03.C语言学习【零基础版】@CHX------算术操作符
    一.+and-+:加法-:减法代码:#include<stdio.h>intmain(){ inta=5+7; intb=20-44; printf("%d%d\n",a,b); return0;}运行结果:二.* *:乘法代码:#include<stdio.h>intmain(){ inta=5+7; intb=20-18; printf("%d\n"......
  • 【C语言进阶】数据如何安家?C语言内存中的存储艺术深度解析
    ......
  • go通过使用不同的环境变量可以打包不同平台运行的程序
    在项目下进入控制台,设置不同的参数然后gobuild就可以编译为目标平台程序了/**#go通过使用不同的环境变量可以打包不同平台运行的程序#mac下的环境变量goenv-wCGO_ENABLED=1GOOS=darwinGOARCH=amd64#linux的环境变量goenv-wCGO_ENABLED=0GOOS=linuxGOARCH=amd......
  • Redis 数据类型详解
    Redis是一个开源的内存数据结构存储系统,广泛应用于缓存、消息队列、实时数据分析等场景。Redis提供了多种数据类型,本文将详细介绍Redis的五种主要数据类型及其应用场景,并从概述、基本操作、应用场景和数据结构等方面进行深入探讨。1.字符串(String)概述字符串是Redis......
  • MySQL 数据类型详解
    MySQL是一种广泛使用的关系型数据库管理系统,它支持多种数据类型以满足各种应用场景的需求。本文将详细介绍MySQL支持的数据类型、它们的使用场景以及实现原理,并通过图示帮助读者更直观地理解。目录简介数值类型整型浮点型定点型日期和时间类型字符串类型字符串二进制字......
  • springboot maven项目多环境profile配置,打包后配置文件properties或yml中的${}或@@变
    maven一些配置如下:项目中配置了多环境<profiles><!--数据库类型--><profile><!--mysql版默认--><id>mysql</id><activation><activeByDefault>true</activ......
  • C语言学习,预处理器
    C预处理器不是编译器的一部分,是编译过程中的一个单独步骤。C预处理器是一个文本替换工具,它指示编译器在编译前进行必要的预处理。 C预处理器所有命令都以井号(#)开头,它必须是第一个非空白字符,以下列出了重要的预处理程序指令:No.指令和说明1#define替换预处理器宏。2#inc......
  • C++学习,数据类型
    编写程序时,需要使用各种变量来存储信息,变量是用于存储值的内存。创建变量时,在内存中保留了一些空间。存储各种数据类型的信息,如字符,宽字符,整数,浮点,双浮点,布尔等。根据变量的数据类型,系统分配内存并决定可以存储的内容。 内置类型C++提供了丰富的内置和用户定义的数据类......
  • C语言实现通讯录-动态版本与文件版本
    C语言实现通讯录-动态版本与文件版本1.前言2.动态版本2.1联系人信息之前的:改版:2.2初始化之前的:改版:2.3自动扩容3.文件版本3.1自动保存函数实现:效果:3.2打开时加载信息函数实现:效果:1.前言在先前的探索中,我构建了一个C语言实现简单的通讯录,它能够存储一定数量的......