C语言再学习(部分总结)

2019-11-11  本文已影响0人  115小小五

C语言的输入输出

printf()

printf() 的基本用法

image.png

printf()的高级用法

  1. type 表示输出类型,比如 %d、%f、%c、%lf,type 就分别对应 d、f、c、lf;再如,%-9d中 type 对应 dtype. 这一项必须有,这意味着输出时必须要知道是什么类型。
  2. width 表示最小输出宽度,也就是至少占用几个字符的位置;例如,%-9d中 width 对应 9,表示输出结果最少占用 9 个字符的宽度。
  3. 当输出结果的宽度不足 width 时,以空格补齐(如果没有指定对齐方式,默认会在左边补齐空格)
  4. 当输出结果的宽度超过 width 时,width 不再起作用,按照数据本身的宽度来输出。

请看下面的例子:

#include <stdio.h>
int main(){
    int m = 192, n = -943;
    float f = 84.342;
    printf("m=%10d, m=%-10d\n", m, m);  //演示 - 的用法
    printf("m=%+d, n=%+d\n", m, n);  //演示 + 的用法
    printf("m=% d, n=% d\n", m, n);  //演示空格的用法
    printf("f=%.0f, f=%#.0f\n", f, f);  //演示#的用法

    return 0;
}

运行结果:

m=       192, m=192      
m=+192, n=-943
m= 192, n=-943
f=84, f=84.

C语言再屏幕的任意位置输出字符
开发小游戏第一步

#include<stdio.h>
#include<Windows.h>

void setColor(int color);
void setCursorPosition(int x, int y);

int main()
{
    setColor(3);
    setCursorPosition(3, 3);
    puts("★");

    setColor(0XC);
    setCursorPosition(1, 1);
    puts("◆");

    setColor(6);
    setCursorPosition(6, 6);
    puts("■");

    return 0;
}


//自定义光标定位函数
void setCursorPosition(int x, int y)
{
    //定义光标位置
    COORD coord;
    coord.X = x;
    coord.Y = y;
    //获取控制台缓冲区句柄
    HANDLE ConsoleHandle = GetStdHandle(STD_OUTPUT_HANDLE);
    //设置光标位置
    SetConsoleCursorPosition(ConsoleHandle, coord);
}

//自定义文字颜色函数
void setColor(int color) 
{
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color);
}
  1. SetConsoleCursorPosition函数,在window.h头文件中,实现光标定位功能
  2. hConsoleOutput表示控制台缓冲句柄,可通过GetStdHandle(STD_OUTPUT_HANDLE)来获得
  3. dwCursorPosition是光标位置,也是第几行第几列,它是COORD类型的结构体
  4. 从代码输出可以发现,先输出的字符位置不一定靠前,后输出的字符位置不一定靠后,他们都可以在任意位置

键盘输入字符和字符串

输入单个字符

  1. getchar()
  1. getche()
  1. getch()

输入字符串

  1. gets()

总结

  1. C语言中常用的从控制台读取数据的函数有五个,它们分别是 scanf()、getchar()、getche()、getch() 和 gets()。其中 scanf()、getchar()、gets() 是标准函数,适用于所有平台;getche() 和 getch() 不是标准函数,只能用于 Windows。

  2. scanf() 是通用的输入函数,它可以读取多种类型的数据。

  3. getchar()、getche() 和 getch() 是专用的字符输入函数,它们在缓冲区和回显方面与 scanf() 有着不同的特性,是 scanf() 不能替代的。

  4. gets() 是专用的字符串输入函数,与 scanf() 相比,gets() 的主要优势是可以读取含有空格的字符串。

  5. scanf() 可以一次性读取多份类型相同或者不同的数据,getchar()、getche()、getch() 和 gets() 每次只能读取一份特定类型的数据,不能一次性读取多份数据。

缓冲区的世界

缓冲区的定义

缓冲区是内存的一部分,也就是说,计算机在内存中预留了一定的存储空间,用来暂时保存输入和输出的数据,这部分预留空间叫做缓冲区

为什么要引入缓冲区

缓冲区是为了让低速的输入输出设备和高速的用户程序能够协调工作,并降低输入输出设备的读写次数

用户程序的执行速度可以看做CPU的运行速度,如果没有各种硬件的阻碍,理论上他们是同步的

缓冲区类型

全缓冲的典型代表是对硬盘文件的读写

行缓冲的典型代表就是标准输入设备(键盘)和标准输出设备(显示器)

getche(), getch()就不带缓冲区,输入一个字符后立即就执行了,根本不用按下回车键

缓冲区的刷新

总结
缓冲区位于用户程序和硬件设备之间,用来缓存数据,目的是让快速的CPU不必等待慢速的输入输出设备,同时减少操作硬件的次数.对于IO密集型的网络应用程序,比如网站,数据库,DNS,CDN等,缓冲区的设计至关重要,它能十倍甚至一百倍得提高程序性能.

C语言清空(刷新)缓冲区

清空输出缓冲区:

清空输入缓冲区(两种方法):

  1. 使用getchar()清空缓冲区
    getchar()是带有缓冲区的,每次从缓冲区读取一个字符,包括空格,制表符,换行符等空白符,只要我们让getchar()不停地获取缓冲区字符,直到读完缓冲区所有字符,就能达到清空缓冲区的效果了
#include<stdio.h>
int main()
{
int a=1;b=2;
char c;
scanf("a=%d",&a);
while((c=getchar()) !='\n' && c != EOF);
scanf("a=%d, b=%d",a,b);

return 0;
}
//输入示例
a=100
b=300
a=100,b=300
//
a=100b=200
b=300;
a=100,b=300  
  1. 使用scanf()清空缓冲区
    scanf()还有一个高级的用法。就是使用类似于正则表达式的通配符,这样他就可以读取所有的字符了,包括空格。换行符。制表符等空白符,不会再忽略他们。并且,scanf()还允许把读到的数据直接丢掉,不会赋值给变量
    scanf(“%*[^\n]”);scanf("%*c");

效果:

#include<stdio.h>
int main()
{
int a = 1; int b = 2;
scanf_s("a=%d", &a);
scanf_s("%*[^\n]"); scanf_s("%*c");  //在下次读取前清空缓冲区
scanf_s("b=%d", &b);
printf("a=%d, b = %d\n",a,b);

return 0;
}
//输入示例
//同getchar()代码中的输入示例

相比使用getchar(),这种方案不用额外定义一个变量,看起来更简洁

C语言scanf()的高级用法

三个方面:

1. 指定读取长度

例如:

#include<stdio.h>
int main()
{   int n;
    float f;
    char str[23];

    scanf("%2d,&n");
    scanf("%*[^\n]"); scanf("%*c");
    scanf("%5f",&f);
    scanf("%*[^\n]"); scanf("%*c");
    scanf("%22s",str);
    printf("n=%d,f=%g,str=%s\n",n,f,str);
    
    return 0;
}
//输入示例
8920
10.2579
http://data.biancheng.net
n=89,f=10.25,str=http://data.biancheng.

2. 匹配特定字符

  1. %s不能读取特定字符,比如朱读取小写字母,或十进制数等,%s就无能为力了

  2. %s读取到的字符串不能包含空白符,例如,无法将多个单词存放到一个字符串中,因为点此之间有空格,%s遇到空格就读取结束了

想要解决以上问题,可以使用scanf()的另外一种字符匹配方式,就是%[xxx], [ ]保卫起来的是需要读取的字符集合,例如,%[abcd]表示只读取字符abcd,遇到其他字符就读取结束

#include<stdio.h>
int main()
{
    char str[30];
    scanf("%[acbd]", str);
    printf("%s\n",str);

    return 0;
//输入示例
    abcd//此行为输入
    abcd//此行为输出
    absd//此行为输入
    ab//此行为输出
}

3.丢弃读取到的字符
scanf()允许把读取到的数据直接丢掉,不往变量中存放 ,具体方法就是在%后面加一个 *
例如:

总结
scanf()的控制字符串的完整写法为:
%{*} {width} type

循环结构和选择结构

查漏补缺:

  1. 关系运算符都是双目运算符,其结合性均为左结合
  2. 关系运算符的优先级低于算术运算符,高于赋值运算符

if语句的判断条件:
if 语句的判断条件中不是必须要包含关系运算符,它可以是赋值表达式,甚至也可以是一个变量,例如:

//情况①
if(b){
    //TODO:
}
//情况②
if(b=5){  //情况①
    //TODO:
}

都是允许的。只要整个表达式的值为非0,条件就成立。

上面两种情况都是根据变量 b 的最终值来判断的,如果 b 的值为非0,那么条件成立,否则不成立。

switch语句

switch(){
case 1: .....;break;
case 2 .....;break;
case 3: .....;break;
case 4: .....;break;
......
default: ....;
}

注: case后面必须是一个整数,或者是结果为整数的表达式,但不能包含任何变量。

条件运算符:

  1. 条件运算符的优先级低于关系运算符和算术运算符,但高于赋值符
//所以:
       max=(a>b) ? a : b;
//可以去掉括号而写为  
        max=a>b ? a : b;
  1. 条件运算符的结合方向是自右至左。例如:
a>b ? a : c>d ? c : d;
//应理解为:
a>b ? a : ( c>d ? c : d );

C语言for循环中的三个表达式

上一篇 下一篇

猜你喜欢

热点阅读