C语言是一门通用计算机编程语言,广泛应用于底层开发。
C语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。
尽管C语言提供了许多低级处理的功能,但仍然保持着良好跨平台的特性,以一个标准规格写出的C语言程序可以在各种平台上进行编译,甚至包含一些嵌入式处理器(单片机或称MCU)以及超级电脑等作业平台。
C语言历史
C语言是从B语言发展而来,B语言是从BCPL发展而来,BCPL是从FORTRAN发展而来的。
BCPL和B都支持指针间接方式,所以C语言也支持指针间接。指针是C语言的灵魂。
C语言还受到了PL/I的影响。还和PDP-II的机器语言有很大的关系。
70年代早期,PL-I 是一种非常重要的底层编程语言,或者叫做系统编程语言。它与汇编语言及机器语言非常相近,所以可以用来做操作系统这样的一些基础的程序。C语言受到PL-I很大的影响,想要去充分表达计算机所使用的那种机器指令,所以在高级语言中,C语言显得是一种比较底层的语言。
1973年3月,第三版的Unix上第一次出现了C语言的编译器。这个编译器可以编译C语言程序
1973年11月,第四版的Unix发布了,这个版本的Unix是完全用C语言重新编写的。
C语言的发展与版本(C语言标准)
为了避免各个开发厂商使用的C语言语法产生差异,1989年ANSI发布了一个标准——ANSI C,作为C语言最初的标准。在1990年被ISO接受为国际标准——C89(也叫C90)C的标准在1995年和1999年两次更新——C95、C992011年12月8日,国际标准化组织(ISO)和国际电工委员会(IEC)发布的C11标准,是C语言的第三个官方标准,该标准更好的支持了汉字函数名和汉字标识符,一定程度上实现了汉字编程。
C语言主要用于编写什么?
C语言是一种工业语言,用于编写一些基础功能。所以对于C语言来说,我们更注重的是它的开发效率,而不是C语言的学习是不是容易、是不是快乐。所以日常应用很少使用C语言来编写,并且学习的过程中更多也是练习代码,而不是写真实软件。
操作系统嵌入式系统驱动程序底层驱动:图形引擎、图像效果、声音效果。
C语言是一门面向过程的计算机语言。
C语言需要被编译才能运行,编译器主要有:Clang、GCC、WIN-TC、SUBLIME、MSVC、Turbo C 等等
我们一般使用IDE(继承开发环境进行开发),其中就包含了C语言的编译器。
推荐使用:VS2019/Clion
创建test.c源文件
#includeint main() { printf("Hello World!n"); return 0; }
详解以上程序
//printf函数的使用,需要引用头文件studio.h。 #include表示包含,文件名放在<>中 #include//函数的返回类型 函数名() //int是整数型 int main() //{}中的是函数体 { //printf:库函数。用于打印信息。n表示换行 printf("Hello World!n"); //return 返回值; return 0; }
#include初识常量、变量int main() { char c = 'a'; // %d表明后面有一个整数要输出在这个位置上。 //printf("%dn",100); //打印整数:%d //表示打印整数100 printf("%dn",c); //sizeof 是一个关键字,也是一个操作符。用于计算类型或者变量所占空间的大小。 //sizeof的单位是:字节(Byte)。计算机内部存储数据的最小单位:比特位(bit),一个比特位也就是一位二进制 // 1B=8b。 //我们可以看到整形int与长整型int占用的空间大小相同,为什么会这样? // C语言标准中规定:sizeof(long)>=sizeof(int),并不一定非要sizeof(long)>sizeof(int) //为什么整型就分了四种? 根据数据所占空间大小,选择类型,可以更好的利用存储空间。 printf("%dn",sizeof(char)); // 1 printf("%dn",sizeof(short)); // 2 printf("%dn",sizeof(int )); // 4 printf("%dn",sizeof(long)); // 4 printf("%dn",sizeof(long long)); // 8 printf("%dn",sizeof(float)); // 4 printf("%dn",sizeof(double)); // 8 }
变量的定义
//生活中一些值是不变的,一些值是可变的。在C语言中: //常量:不能改变的量。 变量:可以改变的量 //变量名是一种“标识符”,用于标识该变量,区别与其他变量。 //标识符的规则:标识符只能由字母、数字、下划线组成;并且不能以数字开头。同时,C语言的关键字(或叫保留字)也不能作为标识符。 //在ANSI C标准中,所有的变量定义都需要在代码开头就定义好。 //在C99标准中,变量可以定义在任何位置,需要用到的时候定义就可以。 #includeint main() { //所有的变量在使用之前必须定义或声明,所有的变量必须具有确定的数据类型。数据类型表明在变量中存放的是什么样的数据,变量中只能存放指定类型的数据,程序运行过程中也不能改变变量的类型。 //如果定义的变量未初始化,就进行使用,则可能出现不可预料的结果。 //定义变量: //数据类型 变量名 = 初始值; //这里的=,是赋值运算符,将右边的值赋给左边。这里为变量赋值,也被叫做变量的初始化。 int age = 20; double weight = 70.5; //改变变量的值 age = age + 1; weight = weight -10 ; // %d:打印整数型 %f:打印float型 %lf:打印double型 printf("%dn",age); //21 printf("%lfn",weight); //60.500000 //同时定义多个变量 int a,b,c; //同时定义多个变量并且赋值 int d=10,e=230; }
变量的分类
//变量分为:局部变量、全局变量 #include//全局变量:{}外部定义的,也叫函数体外定义的。 //全局变量如果没有初始化,则在编译时被初始化为0。如果是一个全局指针变量没有初始化,则被初始化为NULL int b; int* pb; int a = 100; int main() { printf("%dn",a); //100 //局部变量:{}内部定义的,或被称为是函数内部定义的。 int a = 10; //当局部变量与全局变量的变量名相同时,局部引用时,优先使用局部变量。 //但是不建议局部变量与全局变量名称相同。 printf("%dn",a); printf("%dn",b);//0 //指针也被初始化为NULL,以%d打印就是0 printf("%dn",pb);//0 }
变量的使用:求两个整数的和。使用输入函数
//输入两个整数,求和
//printf是输出函数,scanf是输入函数。两个函数中最后面的f是format,意思为格式化的输入输出。
//int age = 18; int num = 0;
//printf("%d",age) 输出整型数据age。 scanf("%d",&num)
//两个函数中,第一个参数都是一个字符串,输出函数中表示:将第二个参数读取到%d的位置进行输出;输入函数中,按照格式,将输入的值读取到变量中。
#include
int main()
{
//int a = 0;
//int b = 0;
//也可以两个变量一起定义。
int a,b;
//也可以输入一个数,回车,输入另一个数;回车运行。
//这里我们在两个%d之间加入了一个空格,我们在控制台按照格式输入,输入一个数,空格,再输入另一个数,回车运行。实际上就是将我们输入的两个数据按照格式读取到我们的两个变量中
scanf("%d %d",&a,&b);
int sum = a + b;
printf("sum = %d",sum);
}
变量的作用域和生命周期
#includeint b = 100; //全局变量b //如果需要访问另一个文件中定义的全局变量,声明一下就可以使用。 extern int c; int main() { printf("%dn",b);//100 //在这里定义一个变量d。 int d =300; printf("%dn",d);//300 { int a = 10; //局部变量a printf("%dn",a); //10 printf("%dn",b);//100 printf("%dn",c);//1069 ,另一个文件中的全局变量也可以使用了。 //如果{}内的变量与{}外的变量的名称相同,则在{}n内部使用该变量时,使用的是{}内的这个变量 //但是同一个{}内,不能定义同名的变量。 int d = 250; printf("%dn",d);//250 } //printf("%d",a); //这里不能访问变量a,因为出了其所在的{}。 printf("%dn",b);//100 return 0; }
常量
#include//固定不变的,就是常量。如果一个变量被定义为常量,则其变量名需要全部大写。 //常量的定义,语法:#define 常量名; #define NUM 1000; //创建性别枚举。 enum Sex {//其中的三个值,都是枚举常量。 MALE, //男 //这三个值默认是0,1,2。如果是MALE=3, 则三个值是3,4,5。 被叫做赋初值 FEMALE,//女 SECRET //保密 }; int main() { //1、字面常量。(没什么意义,因为不能使用,但是存在) //3.14; //浮点型常量 //10; //整型常量 //'a'; //char类型常量 //"abcd"; //字符串型常量 //2、const修饰的常变量 //常变量定义语法:const 数据类型 变量名 = 初始值; //const是一个修饰符,加在数据类型的前面,用来给这个变量加上一个const(不变的)属性。const属性表示这个变量的值一旦定义,就不可以再次改变。其本质上依然是一个变量,只是被const修饰了,不能被修改,所以被叫做常变量。 //虽然const修饰的变量,其变量值不可变了。但是在需要常量的地方,仍然不可以使用该常变量。 const int n = 10; //n就是常变量,具有常属性(不能被改变的属性),但其本质仍然是个变量 //n =100; //不能修改,编译报错。 //3、 #define定义的标识符常量。常量也可以在这里定义 #define MAX 999; //NUM = 10; //编译报错;不能修改。 int a = NUM; int b = MAX; printf("%d %dn",a,b); //4、枚举常量 enum Sex s = MALE; printf("%dn",s); //0 printf("%dn",FEMALE); // 1 printf("%dn",SECRET); //2 return 0; }
字符串
#include#include // ”hello world“ ,这种由双引号引起来的一串字符称为字符串字面值,或者简称字符串。 //字符串的结束标志是一个 的转义字符。在计算字符串长度的时候 是结束标志,不算做字符串内容 //在Clion中,我们发现在字符串的最后是 00,这是八进制转义字符,可以简写为 int main() { //字符数组 char arr1[] = "abc";//在内存中实际存储的是abc char arr2[] ={'a','b','c'};//在内存中实际存储的是abc //打印 printf("%sn",arr1);//输出abc,因为arr1中存储的字符串,后面有 。所以打印完停止 printf("%sn",arr2);//输出abcabc, 因为arr2中存储的字符后面不知道有什么,直到碰见 才停止打印。 //当我们在其中存储一个 时,打印就会停止了 char arr3[] ={'a','b','c',' '}; printf("%sn",arr3); //输出abc //求一下字符串的长度,使用函数strlen。不计算结束标志 ,只计算字符串长度。 int len = strlen("abc"); //string length printf("%dn",len); //3 printf("%dn",strlen(arr1)); //3 printf("%dn",strlen(arr2)); //6 这个6是一个随机值,因为我们并不知道arr2后面存储的是什么 //所以如果计算没有存储 的字符数组的长度,那么这个长度就是一个随机值。 return 0; }
转义字符
//反斜杠()在C语言中具有转义功能。转义字符出现在特殊字符之前,会将特殊字符转换成普通字符。 //如果我们需要在屏幕上打印一个目录c:todetest.c #include#include int main() { printf("c:todetest.cn"); // 实际输出c: ode est.c printf("c:\tode\test.cn"); //使用转义字符将变为普通字符,成功输出c:todetest.c //%c表示打印字符 printf("%cn",'130'); //打印出X。130是一个八进制,转换成十进制是88,88作为ASCCI码,对应的是X //像键盘上的ABC等符号我们都可以直接按出来,但是计算机只认识二进制,所以需要为他们编号排序。就是我们所说的ASCII表 //ASCII表中的每个字符都对应一个ASCII值,如A对应65;a对应97 printf("%cn",' x30'); //打印出字符0 printf("%cn",'72'); //打印出字符: //笔试题 // t、62、t作为转义字符联合起来,每一个转义字符都算作一个字符。因为是八进制,所以后面的8一定不能与转义字符一起算。 printf("%dn",strlen("c:test628test.c"));//14 return 0; }
n表示换行,r表示将当前位置移动到文本开头。
实际上,我们键盘上的回车,就是相当于移动到文本开头,然后换行。
但是我们在程序中使用的一般都只是一个n来实现换行,然后直接就是下一行的开头了。这是因为在执行程序时,程序与控制台(shell)进行交互,我们从控制台输入输入的数据,控制台翻译后与运行的程序进行交互。等程序执行完之后,将结果显示到显示器上。
为什么我们只用一个n就实现了回车换行的功能?是因为shell帮我们将这个n解释为回车换行了,所以我们一般只使用n,基本上没有使用过r。
| 转义字符 | 释义 |
|---|---|
| ? | 在书写连续多个问号时使用,防止被解析为三字母词 |
| ’ | 字符单引号 |
| " | 双引号 |
| \ | 反斜杠 |
| a | 响铃,也叫蜂鸣 |
| b | 退格,将当前位置移到前一列 |
| f | 换页,将当前位置移动到下页开头 |
| n | 换行,将当前位置移动到下一行开头 |
| r | 回车,将当前位置移动到本行开头 |
| t | 水平制表符 |
| v | 垂直制表符 |
| ddd | ddd表示1-3个八进制数字。如130就是字符X。如果是 72可以表示为72,是: 与 00意思相同 |
| xdd | dd表示2位16进制数字,如x30 ,就是字符0 |
注释
//C++风格的注释 ,则后面的*/就会失效 */
选择语句
#includeint main() { int num = 0;//输入的值 printf("下雨请按1,反之按0:n"); scanf("%d",&num); if(num ==1) { printf("请带伞n"); } else { printf("出行愉快n"); } //当只有一行c语句时,可以省略大括号 // if(num ==1) // printf("请带伞n"); // else // printf("出行愉快n"); return 0; }
循环语句
#includeint main() { printf("饭熟了n"); int eat = 0 ; while(eat<10) { eat++; printf("吃了一碗饭n"); } if(eat==10){ printf("胖了10斤!n"); } }
函数
int Add(int x ,int y)
{
int z = x + y;
return z;
}
int main()
{
int num1,num2;
scanf("%d %d",&num1,&num2);
//int sum = num1 + num2;
//调用函数解决相加
int sum = Add(num1,num2);
printf("%dn",sum);
}
数组
//数组的定义:数据类型 数组名[数组中元素个数]={}
//数组如果初始化,可以不指定数组大小。并且数组大小不能传入一个变量。
//C语言规定:数组的每个元素都有一个下标,数组下标从0开始。数组可以通过下标来访问:数组名[下标]
//数组名本身就是一个地址,所以如果是在调用scanf函数时,数组名前就不用加&符号了。
int main()
{
int arrr[10] = {0} //初始化数组,其中的每个元素值都为0。
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
//遍历数组
int i = 0;
while(i < 10)
{
printf("%d ",arr[i]);
i++;
}//1 2 3 4 5 6 7 8 9 10
printf("n");
int arr2[5] = {1,2,3}; //不完全初始化,剩余的默认为0
int j = 0;
while(j < 5)
{
printf("%d ",arr2[j]);
j++;
}//1 2 3 0 0
return 0;
}
常见关键字
//这些关键字是C语言规定的。并且关键字不能作为变量名。
auto break case char const continue default do double else
enum extern float for goto if int long register return
short signed sizeof static struct switch typedef union unsigned
void volatile while
//extern 用来声明外部符号,如生命其他文件内定义的全局变量
//signed 有符号的 、unsigned 无符号的
//static 静态的
//union 联合体(共用体)
//void 无/空
//像我们已经使用过的include、define,他们并不是关键字,而是预处理指令。
extern
#includeatuo:自动的。每个局部变量都是auto修饰//注意:除非有extern关键字,否则就都是定义。 extern int a; //声明 int b; //定义(未初始化) //如果声明有初始化式,就被当作定义,即使前面加了extern。 //但是注意:只有extern声明位于函数外部时,才可以被初始化。 //虽然可以定义,但现在这个定义被gcc编译器认为是错误的,所以不推荐使用。 extern int c = 100; //函数的声明和定义 extern int SUM(int x,int y); //定义一个外部声明的int型变量d //只是个声明。如果要对c进行读写操作,而我们并没有对c进行定义,因此虽然语法检查没有问题,但是在链接时,连接器会找不到c的地址。 extern int d; int main() { //声明一个外部定义的变量:int类型型变量e //注意:声明外部变量时可以把变量类型去掉如:extern e; extern int e; printf("%dn",c); return 0; }
int main()
{
{
//auto修饰所有局部变量。表示其是自动变量。自动创建,自动销毁
auto int a = 10;
//auto一般都省略掉。auto在新的标准中也有其他用法,暂时不考虑
int b = 1;
}
return 0;
}
register关键字
//register —— 寄存器关键字
int main()
{
//大量/频繁使用的数据,想粗放在寄存器中,提升效率,就可以使用register关键字修饰
//现在编译器已经很聪明了,他觉得用的很多的数据,就会将其存放再寄存器中。
//这里我们仅仅只是建议,如果你建议存放的数据,编译器不认为应该存放在寄存器中,则数据就不会存放在寄存器中,还是编译器说了算
register int num = 100; //建议num的值存放在寄存器中
return 0;
}
typedef关键字
//typedef ——类型定义,因该理解为类型重命名
//重命名unsigned int类型为u_int
typedef unsigned int u_int;
int main()
{
//因为unsigned int写起来太繁琐了,我们将其重新定义
unsigned int num1 = 0;
//定义后使用u_int定义的就是unsigned int类型了
u_int num2 = 0;
return 0;
}
static关键字
//修饰局部变量 #include定义常量和宏void test() { //int i = 0;//所有局部变量都由auto修饰。自动创建、自动销毁。 static int i = 0; i++; printf("%d ",i); } int main() { int a = 0; for(a=0;a<10;a++) { test(); } return 0; }
//宏的定义:宏是一种抽象,根据一系列预定义的的规则替换一定的文本模式。解释器或编译器在遇到宏时会自动进行这一模式替换。宏就是替换。 //define定义常量 #include格式化输入输出 printf#define MAX 1000; //define定义宏 //这里不能这样写,因为宏使用的时候,是使用x+y替换ADD(x,y),而如果传入的x和y是两个表达式,如x=1+2,那么在计算顺序上可能就会出现问题。 #define ADD(x,y) x+y; //所以我们需要为x和y都加上(),并且为他们整体再加上() #define RIDE(x,y) ((x)*(y)); int main() { int i = MAX; printf("%dn",i); //1000 //使用定义的ADD(x,y)宏 int add1 = ADD(1,3); printf("%dn",add1);//4 int add2 = 5*ADD(1,3); //这里我们认为5*(1+3),肯定是输出20,但结果却是8? //是因为宏在使用的时候,是用后面的替换前面的。如5*ADD(1,3)就被替换为5*1+3=8。 //所以我们定义的时候要为x以及y加上(),并且整体再加一个(),因为x和y都可能是一个式子,如x=1+4,y=2+4 //如果不加(),则计算顺序就会再次混乱,加上()就会优先计算()里的,就可以得到我们想要的结果了。 printf("%dn",add2);//8 //使用定义的RIDE(x,y)宏 //我们想要2*(2*4)=16 int ride1 = 2*RIDE(2,4); printf("%dn",ride1);//16 //我们想要45/(3*5)=3 int ride2 = 45/RIDE(2+1,10/2); printf("%dn",ride2);//3 //加上()之后顺序就再也不会出错了 return 0; }
int main()
{
int i = 123;
//-
//右对齐
printf("%9dn",i);// 123
//左对齐
printf("%-9dn",i);//123
//+
printf("%dn",-i); //-123 默认情况下,如果是个负数,打印的时候会加负号
printf("%dn",i); //123 默认情况下,如果是正数,默认不打印正号
printf("%+dn",i); //+123 如果是正数,%+,则会打印正数的正号。
printf("%+dn",-i); //-123 如果是负数,%+,也是打印负数。
//空格
printf("% dn",i); // 123
printf("% dn",-i); //-123
//指定填充时,用0,而不是空格填充。
printf("%5dn",i); // 123。默认用空格填充
printf("%05dn",i); //00123。指定后,用0填充
printf("%-05dn",i); //123。如果是左对齐,则指定之后也不会进行填充。
//#
printf("%on",i); //173。%o以八进制打印
printf("%#on",i); //0173。打印八进制时,带上开头的0
printf("%xn",i); //7b。%x以十六进制打印(小写)
printf("%#xn",i); //0x7b。打印十六进制时,带上小写的0x
printf("%Xn",i); //7B。%x以十六进制打印(大写)
printf("%#Xn",i); //0x7B。打印十六进制时,带上小写的0X
float a = 123.0;
//width 与.prec
//如果要打印的字符数少于指定的数字,则用空格填充。宽度为9,123.00共占6个字符,所以前面补3个空格。
//.2是要保留两位小数。所以123.0变成123.00
printf("%9.2fn",a); // 123.00
//如果是* ,则宽度,作为格式字符串之后的第一个附加整型参数来传递
printf("%*dn",6,i); // 123
//如果是.* 。 则小数点后的位数,作为格式字符串之后的第一个附加整型参数来传递
printf("%.*fn",3,a); //123.000
//如果是*.* 。则格式字符串之后的第一个附加整型参数作为宽度排列,第二个附加整型参数作为精度传递。
printf("%*.*fn",9,3,a); //123.000
return 0;
}
scanf()
int main()
{
int num,num2,num3;
//比如输入了123 456,那么会跳过123,将456存储到num中。
// scanf("%*d %d",&num);
// printf("%dn",num);
//%d与%d之间用逗号(,)隔开,意思是读取输入的时候,以逗号(,)为分隔符读取数据。默认是以空格隔开。
//如输入:12,32 。则num=12,num2=32。
//如果此时输入时以空格隔开:12 32。则num=12,num2=0。此时的32会返回stdin中,等待下一次scanf读取。
//如果我们后面还有一个scanf读取数据,则我们不需要再输入数据,32会被这个scanf读取,保存到num3中,则num3=32。
// scanf("%d,%d",&num,&num2);
// printf("%d %dn",num,num2);
// scanf("%d",&num3);
// printf("%dn",num3);
//定义一个scanf函数的返回值
//当所定义的数据类型与用户输入的数据类型不相符时,就会出现问题,输出结果就不是预期结果,这时可以定一个变量来表示成功读取数据的个数。
//如果输入:12 23 34 ,则ret=3,表示正常读取
//如果输入:12 s 23,则只有a是12,遇到s后,会直接退出,剩下的都没有读取成功。所以ret=1
// int a,b,c,ret;
// ret = scanf("%d %d %d",&a,&b,&c);
// printf("a=%d,b=%d,c=%dn",a,b,c);
// printf("ret=%dn",ret);
//如果输入:you are very good,则str中只存储you,因为遇到了空格。
//这里要注意的是"are very good"还在键盘缓冲区
//但是,其实这时缓冲区字符串首尾指针已经相等了,也就是说缓冲区清空了。scanf()函数应该只是扫描stdin流,这个残存信息是在stdin中)
char str[80];
scanf("%s",str);
printf("%s",str);
return 0;
}
如何处理scanf()函数误输入造成程序死锁或出错?
#includegets、getchar、缓冲区讲解 gets()函数void flush() { char c; //清空缓冲区,后续讲到 while ((c=getchar()) != 'n'&&c!=EOF); } int main() { int a,b,c; //当scanf函数没有成功读取时,清空数据,重新读取。直到scanf成功读取两个数据。 int ret = 1; while(ret !=2) { printf("ret=%d,请输入两个数字:",ret); ret = scanf("%d %d",&a,&b); //fflush(stdin);//清空stdin中残留的数据 。可移植性差。 flush(stdin);//自己写的,用于清空缓冲区的方法。 } c=a+b; printf("%d+%d=%d",a,b,c); return 0; }
getchar()函数——只适用于标准输入流
#include缓冲区详解int main() { int ch = 0; while ((ch=getchar()) != EOF) { //getchar()函数的返回值是其字符对应的ASCII码 printf("%d——",ch); //putchar()函数的返回值是其传入变量对应的字符。 putchar(ch); printf("----t"); } }
//#include//int main() //{ // //定义字符数组,长度为20 初始化其中所有元素为0 // char password[20] = {0}; // printf("请输入密码:"); // //%s表示输入一个字符串 // scanf("%s",password); // printf("请确认密码(Y/N):"); // int ch = getchar(); // if(ch == 'Y') // { // printf("确认成功n"); // } // else // { // printf("确认失败n"); // } // return 0; //} //#include //int main() //{ // char password[20] = {0}; // printf("请输入密码:"); // scanf("%s",password); // printf("请确认密码(Y/N):"); // //在%c取字符之前,使用getchar()吸收遗留的n // getchar(); // int ch = getchar(); // if(ch == 'Y') // { // printf("确认成功n"); // } // else // { // printf("确认失败n"); // } // return 0; //} //#include //int main() //{ // int a = 0; // int b = 0; // int c = 0; // scanf("%d %d %d",&a,&b,&c); // printf("%d %d %dn",a,b,c); // int ch = 0; // while ((ch=getchar()) != EOF) // { // printf("%d——",ch); // putchar(ch); // printf("----t"); // } // return 0; //} //#include //int main() //{ // int a = 0; // printf("请输入一串字符和数字(请以数字开头):"); // scanf("%d",&a); // printf("您输入的字符中,已存储的有效数字为:%dn",a); // fflush(stdin); // printf("已经调用ffluh方法清空缓存区,请输入一个字符:"); // int ch = getchar(); // printf("%c",ch); // // return 0; //} //#include //int main() //{ // int a = 0; // printf("请输入一串字符和数字(请以数字开头):"); // scanf("%d",&a); // printf("您输入的字符中,已存储的有效数字为:%dn",a); // while (getchar() != 'n'); // printf("高级运用getchar() 清空缓存区,请输入一个字符:"); // int ch = getchar(); // printf("%c",ch); // return 0; //}



