C语言学习笔记之输入与输出

主题: C语言学习笔记
时间:2020年12月31日
作者:ybb
参考:C语言Chinese Net

3、C语言变量和数据类型

3.8 C语言中的字符

单个字符 %c
字符串 %s
ASCII表对应的值
ASCII表原图
常用的对应关系:A-Z~65-90
a-z~97-122
0-9~48-57
因此,字符和整数没有本质的区别。
char变量在内存中存储的是字符对应的ASCII值。

#include<stdio.h>
int main() {
    
    
	char a = '&';
	char *str = "every two steps forward";
	printf("a is:%c\n",a);
	printf("str is:%s\n",str);
	printf("str is:%s\n","it often feels one step back");
	return 0;
}

3.9 C 语言数据类型转换

强制类型转换
自动类型转换

无论是强制转换或是自动转换,都只是为了本次运算的需要而对变量的数据长度进行的临时性转换,而不改变数据说明时对该变量定义的类型

#include<stdio.h>
int main() {
    
    
	float PI = 3.141592;

	int s1;
	int r;
	double s2;
	r = 5;
	s1 = PI * r*r;
	s2 = PI * r*r;
	printf("s1 is %d\n,s2 is %lf\n",s1,s2);
	return 0;
}

浮点型转换成整型是将小数部分直接丢掉,而不是按照四舍五入向前舍入

3.10 C语言转义字符

只能使用八进制或十六进制,不能使用十进制

printf:

输出控制符”和“输出参数”无论在“顺序上”还是在“个数上”一定要一一对应。
输出控制符:

C语言输出控制符

#include<stdio.h>
int main()
{
    
    
	int a = 10;
	float b = 11.11;
	double c = 12.12121212;
	char *str = "you are best";
	printf("a is %d\n",a);
	printf("a is %5d\n", a);
	printf("a is %u\n", a);
	printf("b is %f\n", b);
	printf("a is %X\n",a);
	printf("c is %f\n", c);
	printf("c is %lf\n", c);
	printf("c is %.10f\n", c);
	printf("str is: %s\n",str);
}

%x、%X、%#x、%#X 的辨析:
小写 大写 带0x指示16进制 带0x指示16进制

推荐%#X

3.11 C 语言加减乘除运算

C语言大量用到的简写: 在 C 语言中,表达式 a=a#b 可以简写为 a#=b,#表示 +、-、*、/、% 中 的任何一种运算符。
注意:a#=b 仅是一种简写,不会影响效率(大家都这样写)

3.12 自增与自减:

a1=++a;会先进行自增操作,再进行赋值操作;而 b1=b++;会 先进行赋值操作,再进行自增操作。c1=- -c;和 d1=d- -;也是如此。

3.13 C 语言运算符的优先级和结合性

优先级:多个运算符出现在同一个表达式中,各个运算符的执行顺序
C语言表达式:
C语言语句:
双目运算符、三目运算符、单目运算符
C语言运算符优先级和结和性汇总表:
C语言运算符优先级和结合性

3.14 printf的高级应用

格式化输出

#include<stdio.h>
int main() {
    
    
	int a1 = 10, a2 = 100, a3 = 1000;
	int b1 = 200, b2 = 2000, b3 = 20000;
	int c1 = 3000, c2 = 30000, c3 = 300000;

	printf("%d%d%d\n", a1, a2, a3);
	printf("%d%d%d\n", b1, b2, b3);
	printf("%d%d%d\n", c1, c2, c3);


	printf("%-8d%-8d%-8d\n",a1,a2,a3);
	printf("%-8d%-8d%-8d\n",b1,b2,b3);
	printf("%-8d%-8d%-8d\n",c1,c2,c3);

	printf("%8d%8d%8d\n", a1, a2, a3);
	printf("%8d%8d%8d\n", b1, b2, b3);
	printf("%8d%8d%8d\n", c1, c2, c3);

	return 0;
}

printf()格式控制符的完整形式:
%[flag][width][.precision]type

.precision 表示输出精度,也就是小数的位数。
 当小数部分的位数大于 precision 时,会按照四舍五入的原则丢掉多余的数字;
 当小数部分的位数小于 precision 时,会在后面补 0。
另外,.precision 也可以用于整数和字符串,但是功能却是相反的:
 用于整数时,.precision 表示最小输出宽度。与 width 不同的是,整数的宽度不足时会在左边补 0, 而不是补空格。 用于整数时,起作用是在不足长度时左边补0,长度充足是原样输出
 用于字符串时,.precision 表示最大输出宽度,或者说截取字符串。当字符串的长度大于 precision 时,会截掉多余的字符;当字符串的长度小于 precision 时,.precision 就不再起作用

flag的使用:

#include<stdio.h>
int main() {
    
    
	int a1 = 10, a2 = 100, a3 = 1000;
	int b1 = 200, b2 = 2000, b3 = 20000;
	int c1 = 3000, c2 = 30000, c3 = 300000000;
	int A = 66;
	float B = 666;

	double C = 88.8888;

	printf("%d%d%d\n", a1, a2, a3);
	printf("%d%d%d\n", b1, b2, b3);
	printf("%d%d%d\n", c1, c2, c3);


	printf("%-8d%-8d%-8d\n",a1,a2,a3);
	printf("%-8d%-8d%-8d\n",b1,b2,b3);
	printf("%-8d%-8d%-8d\n",c1,c2,c3);

	printf("%8d%8d%8d\n", a1, a2, a3);
	printf("%8d%8d%8d\n", b1, b2, b3);
	printf("%8d%8d%8d\n", c1, c2, c3);

	printf("% *d\n", 5, 4000);

	printf("%d\n%o\n%X\n",A,A,A);
	printf("%#d\n%#o\n%#X\n", A, A, A);
	printf("%#f\n", B);
	return 0;
}

printf随处可见,我们要把他利用好
程序员思维、逻辑思维、未来思维

3.15 C语言scanf的基本应用

printf与scanf_s
puts与gets

对于scanf(),输入数据的格式要和控制字符串的格式保持一致。
取地址,取的是什么?

本质上讲,我们从键盘输入的数据并没有直接交给scanf(),而是放入了缓冲区,我们按下enter键,scanf()函数才会从缓冲区读取数据,如果缓冲区的数据符合scanf()的要求,那么就会读取结束,否则继续等待用户输入。

下例说明 scanf() 不会跳过不符合要求的数据,遇到不符合要求的数据会读取失败,而不是再继续等待用户 输入。 总而言之,正是由于缓冲区的存在,才使得我们能够多输入一些数据,或者一次性输入所有数据,这可以 认为是缓冲区的一点优势。

#include<stdio.h>

int main()
{
    
    
	int a = 1, b = 2, c = 3, d = 4;

	scanf_s("%d%d%d%d",&a,&b,&c,&d);
	printf("a=%d b=%d\n",a,b);
	printf("c=%d d=%d\n",c,d);
	return 0;
}

利用scanf()输出单个字符、字符串、整数、小数:

下面代码的调试存在问题? 可能是因为VS2017的问题,对老的代码不兼容???

#include <stdio.h> 
int main() 
{
    
     
char letter; 
int age; 
char url[30]; 
float price; 
scanf("%c", &letter); 
scanf("%d", &age); 
scanf("%s", url); //可以加&也可以不加& scanf("%f", &price); printf("26 个英文字母的最后一个是 %c。\n", letter); 
printf("C 语言中文网已经成立%d 年了,网址是 %s,开通 VIP 会员的价格是%g。\n", age, url, price); 
return 0; 
}

scanf()格式控制符汇总:
格式控制符要牢记

3.16 scanf的高级应用

printf与scanf要对比学习和应用,学习的最终目的不是考高分,而是能够真正解决实践中遇到的问题。
使用多个scanf连续读取数据时,我了避免缓冲区遗留数据的影响,我们应该使用scanf("%*[^\n]");scanf("%*c");清空缓冲区

将读取到的字符直接丢弃,这就是在清空输入缓冲区

实际中应该限制读取的数据长度,我们可以为字符串分配有限的内存空间,当用户输入的字符串过长就存放不了了,会冲刷掉其他数据,从而导致程序出错或者崩溃。如果黑客发现了这个漏洞,就会构造栈溢出攻击,改变程序的执行流程,甚至替换成自己的恶意代码,对服务器影响很大。

匹配特定的字符:%[0-9A-Za-z]
不匹配特定的字符:%[^0-9]
丢弃读取到的字符:%*[a-z]

scanf()如何指定字符串的最大长度与字符串截取
scanf()如何读取指定字符[0-9]
scanf()如何不读取指定字符[^0-9\n]
scanf()如何读取带空格的字符串[^\n]

scanf()不仅可以完全替代gets(),并且比gets()强大。

scanf()小结:
scanf({*}{width}type)
其中,{ } 表示可有可无。各个部分的具体含义是:
 type 表示读取什么类型的数据,例如 %d、%s、%[a-z]、%[^\n] 等;type 必须有。
 width 表示最大读取宽度,可有可无。
 *表示丢弃读取到的数据,可有可无。

猜你喜欢

转载自blog.csdn.net/BJTUYBYUAN/article/details/112002703