C语言学习的第二天,基本上一些小程序,都可以去解决了,像趣味100例的前10道题,都可以放肆大胆的去敲,去理解里面的一些算法。
在程序的编写过程中,我也遇到了一些很容易被忽视的点,通过查漏补缺,才能更好的熟练掌握这个工具。
一下是自己遇到的一些小问题,和同学询问过的一些容易被忽视的知识点,每天还会继续更新。
1、scanf( )的使用
scanf( )是基本输入输出库中的常用函数,我们用它来从终端获取输入的数值或字符。但是scanf( )却有很多雷区,会让你常常与终端沟通不了,不要着急,我们慢慢去看。
scanf("x=%d,y=%d",x,y);
>>12 13
像这样输入12 13,终端是读取不了的,首先我们要明确scanf( )的使用方法:
函数名: scanf
功 能: 执行格式化输入
用 法: int scanf(char *format[,argument,...]);
scanf()函数是通用终端格式化输入函数,它从标准输入设备(键盘) 读取输入的信息。可以读入任何固有类型的数据并自动把数值变换成适当的机内格式。
其调用格式为: scanf("<格式化字符串>",<地址表>);
scanf()函数返回成功赋值的数据项数,出错时则返回EOF。
1、格式化字符串
最简单的理解,就是你" "之间写的什么格式,在终端中输入时,也必须是这种格式。
像scanf("%d %d",&a,&b); 在输入时也必须是: 数字[空格]数字,如果少了这个空格,是不行的。还用像例题中的那种格式化字符串: scanf("a=%d,b=%d",&a,&b); 则输入时必须也是: a=数字,b=数字 缺一不可。
2、地址表
必须记得要在变量前加'&',&是地址运算符,分别获得变量的内存地址。
3、输入多个值,该如何输入。
char a,b;
scanf("%c%c",&a,&b);
char a,b;
scanf("%c",&a);
getchar();
scanf("%c",&b);
注意!上述两种为读入字符类型,与整型类型差别很大,需要注意
第一种方法输入时,在终端中输入时不能像获取整型变量一样,每个数字应以空格间或者回车开,因为此时空格和回车并不会像输入数字的时候被scanf()省略掉,而是会被读取。
特别注意第二种,此处getchar ()的用法,用来吸收掉两个scanf()的回车符,可以用putchar()来实验一下,此处回车被吸收掉,这种用法要会使用。
2、GCC编译时,库的使用
在之前的简单学习中,我们只用到了stdio.h这个头文件,头文件是什么、stdio.h又是什么呢?
一般地,在C语言或C++中,会把用来#include的文件的扩展名叫 .h,称其为头文件。 #include文件的目的就是把多个编译单元(也就是c或者cpp文件)公用的内容,单独放在一个文件里减少整体代码尺寸;或者提供跨工程公共代码。
stdio 就是指 “standard input & output"(标准输入输出)
所以,源代码中如用到标准输入输出函数时,就要包含这个头文件!
例如printf("%d",i); scanf("%d",&i);等函数。
Glibe (GNU Library C)是GNU推出的C语言函数库,符合ISO C(International Standard for the C programming Language ) 和 POSIX ( Portable Operating System Interface for ComputerEn\-ironments)标准。其中,ISO C定义了C函式库的标准格式,POSIX定义了不同计算平台应该遵守的C函数库标准,是ISO C标准的扩充。因此Glibc可以在各种不同让系结构的计算平台上使用。
Glibc中包含了大量的函数库,其中libe是最基本的函数库,每个工程序都需要使Iibc库。此外,常用的还有数学库libm、加密库libcrypt、POSIX线程库libpthread、网络服务库libnsl、IEEE浮点运算库libiee等。Glibc库为C程序提供了大量功能强大的函数,包括输入输出函数、字符串处理函数、数学函数、中断处理函数、错误处理函数、日期时间函数等。
C程序在调用Glibc中的函数库时,需要引用与函数库对应的头文件,如stdio.h、string.h、time.h等。这些头文件都存放在/usr/include目录下。同时,在编译命令中需要加入某些函数库的链接参数(在函数库的使用文档中会列出具体的链接库名称参数),并使用符号'-l'。进行连接。比如libm库的链接参数为m,libpthread库的链接参数为pthread等.
以上看不懂没关系,会用就行。
例:趣味100例第一题:
/*第一例:绘制余弦曲线*********************************************/
/*编写日期:2018/07/20***************编写人:董炳政****************/
/*在屏幕上用"*"显示0~360的余弦cos(x)曲线*************************/
#include <stdio.h>
#include <math.h>
int main()
{
double y;
int x,m;
for(y = 1;y >= -1;y -= 0.1)
{
m=acos(y)*10;
for(x = 1;x < m;x++)
printf(" ");
printf("*");
for(;x < 62-m;x++)
printf(" ");
printf("*\n");
}
return 0;
}
很多同学问我,为什么第一例就跑不起来呀,我程序和例子是一样的。综合发现,大家都是困在了最后一步库没链接上。因为程序中调用了math.h.
最后gcc编译时应为:
gcc fun1.c -o fun1 -lm
在调用库的以后一定要注意链接!
3、switch case的使用
C语言提供了一种用于多分支选择的switch语句, 其一般形式为:
switch(表达式)
{
case 常量表达式1: 语句1;
case 常量表达式2: 语句2;
…
case 常量表达式n: 语句n;
default: 语句n+1;
}
其语义是:计算表达式的值。 并逐个与其后的常量表达式值相比较,当表达式的值与某个常量表达式的值相等时, 即执行其后的语句,然后不再进行判断,继续执行后面所有case后的语句。如表达式的值与所有case后的常量表达式均不相同时,则执行default后的语句。
常见错误:
switch(i)
{
case1:
......
case2:
......
......
default:
......
}
发现问题了么?
错在case后面没有正确的添加空格,很容易被忽视的一个点。
还有switch语句中一定要注意break的用法,因为,如果在一条case语句中没有break语句,程序将继续执行下面的语句,直到遇到break,或者将全部程序跑完。
4、while的一些小用法
有同学问我,while(a),是什么意思,括号里面什么条件也没有,看不太懂。其实while(a)就等价为while(a != 0),只要括号里的值不为0,则继续执行。其实,如果大家学过51的话,应该会有印象,我们所有的51主程序都是放在while(1)这个死循环里面的,1不为0,所以程序才能循环的执行下去。类似的用法还有一个地方,也就是条件运算符: ? :它是唯一的三目运算符。在趣味100例中的书籍分配问题中,在输出所有符合条件的结果的时候,用到了printf(count % 5 ? "%2d:%d,%d,%d" : "%2d:%d,%d,%d\n"); 此处也是省略了count % 5 != 0。如果成立则执行:前面的一句不换行,如果不成立则执行后面换行的一句。日后遇到类似这种问题时,不妨使用一下,可以使得程序更加简洁。
2018/07/24
以后日常更新此篇文章,能力有限,如有错误,请指正。