正在学习C语言中…
编程前须知
今天懒得写了
第一个程序:求下落位移
#include<stdio.h>intmain(){inth,t,g=10;doubles;scanf("%d%d",&h,&t);s=g*t*t/2;if(s<h)printf("%.1f\n",s);elseprintf("%d\n",h);return0;}新知
1.main()里面可以空白也可以写void
2.控制输出小数位:printf(“%.nf”,variable); n代表要求输出n位小数
且会四舍五入,而非直接截断
易错
1.scanf后面修改变量值必须加取变量运算符“&”
2.if后面条件要在()里
3.每一条语句后面都要有分号
;
4.如果if,else,for,while等后面的body只有一行,可以不用{},否则必须有
且这些所在的那一行不能写分号;
5.区分整数除法与浮点除法:只要被除数与除数之中一个是浮点数就采用浮点除法,注意下面第二个是大坑,它是先按整数除法得到1,再转为浮点数1.0
位数没关系,只要有小数点就是浮点数double
int sum=9;
double avg = sum / 2.0;等价于double avg = (double)sum / 2;
inta=9/5;// 1 整数除法,余数 4 被丢掉doubleb=9/5;// 1.0 ⚠️ 先算 9/5=1,再转成 doubledoublec=9/5.0;// 1.8 浮点除法doubled=9.0/5;// 1.8 浮点除法第二个程序:海伦公式求三角形面积
#include<stdio.h>#include<math.h>intmain(){charagain;do{doublea,b,c,p,s;printf("输入三边长:\n");scanf("%lf%lf%lf",&a,&b,&c);if(a+b>c&&a+c>b&&b+c>a&&a>0&&b>0&&c>0){p=(a+b+c)/2.0;s=sqrt(p*(p-a)*(p-b)*(p-c));printf("面积为:%f\n",s);}else{printf("不能组成三角形\n");}printf("还要继续吗?(回复y/n)\n");scanf(" %c",&again);}while(again=='y'||again=='Y');return0;}新知
1.stdio.h库中常用函数有printf,scanf,getchar,putchar等;math.h中库有sin,cos,tan,asin,acos,atan,exp,log,log10,pow,sqrt,cbrt等
2.char定义的是字符数据类型,本质上是字符依据ASCⅡ对应的那个整数,一个变量只能储存单个字符,内存一个byte,赋值形似char c = ‘Y’;。
注意此处是单引号,单引号是字符,本质是一个整数,双引号是字符串,本质是指向那一串字符的地址。
char对应的格式符可以是%c(字符)或%d(int)
字符串对应的格式符是%s
3.定义数组:如 char array[10];,里面的数字指的是数据个数,可以给其赋值字符串,字符串就是以’\0’结尾的字符串数组,比如上述array[10]数组就可以记录9个字符,最后一个留给’\0’,如"abc"=‘a’,‘b’,‘c’,‘\0’
数组是一段连续空间,下标从0开始,如声明int a[5],下标只有0,1,2,3,4
4.字符串字面量,就是写在源码里的那个量,比如"abc",经编译后变为以’\0’结尾的字符数组(即字符串)。
5.逻辑运算符:逻辑与&&,逻辑或||,逻辑非!
任何非0的数的返回结果都是1(真),0的返回结果是0(假)
如int a=5 ,if(a){}就会正常执行,因为a!=0,返回结果就是1
优先级:! > 算术运算 > 关系运算(>, <, ==) > && > || > 赋值(=)
&&和||都有短路特性,只要左边能确定结果,右边就不会执行,0&&任意东西都为假
inti=0;intr=0&&i++;// 左边 0 是假 → 右边 i++ 不执行 → i 还是 0ints=1||i++;// 左边 1 是真 → 右边 i++ 不执行 → i 还是 0易错
1.字符数组中’\0’也占一个位置,这很容易忘记,导致越界
2.注意写\n保证美观
3.%c 会读取空白字符(包括空格、换行、Tab),常需在 %c 前加空格,如 " %c" 来跳过前导空白。(此段代码即是如此)
用户输入三个边长后会按\n来推进程序,而这个\n会保留在缓存区,后续%c一读取就读到了\n != ‘y’||‘Y’,故程序会直接结束
4.%s 遇到空白就停,且不会检查数组越界,建议用宽度限制,如 %19s
补充记录
循环
for循环
适用于次数已知的循环
for(初始化 ; 判断条件 ; 更新表达式){
循环体
}
执行顺序:初始化→判断条件→循环体→更新表达式→判断条件→…
三个位置不能交换,各有职责
// 三部分都可以省略,但分号不能省
for (;; ) // 死循环
for (; i < 5;) // 省略初始化和更新
for (i = 0; ; i++) // 省略条件,等于死循环
可以把更新表达式写在循环体里,但是可读性差
while循环
适用于次数未知,靠条件控制的循环
while(条件){
循环体
}
先判断条件,为真才执行循环体。可能一次都不执行
⚠️记得在循环体里更新,否则会形成死循环
do-while循环
适用于至少执行一次的场景
do{
循环体
}while(条件);\⚠️注意这里需要加分号
先执行一次循环体,再判断条件。至少执行一次
break和continue
break:立即跳出整个循环
for(inti=0;i<10;i++){if(i==5)break;// i 到 5 时直接结束循环printf("%d ",i);// 0 1 2 3 4}continue:跳过本次,进入下一次
for(inti=0;i<10;i++){if(i%2==0)continue;// 偶数跳过printf("%d ",i);// 1 3 5 7 9}注意:continue 在 while 里要小心死循环
inti=0;while(i<5){if(i==2)continue;// ⚠️ i 没机会自增,永远停在 2 → 死循环i++;}然而在 for 里没这个问题,因为 i++ 是循环语法的一部分,continue 后仍会执行
缓冲区
键盘输入的字符不会立刻被程序读到,而是先进输入缓冲区,等 scanf、getchar 来取
若输入:3.14 2.71 1.41\n
缓冲区:[3][.][1][4][ ][2][.][7][1][ ][1][.][4][1][\n]
scanf(“%lf%lf%lf”,…) 按格式一点点读走 3.14、2.71、1.41,但换行 \n 留下了。
于是下一个 scanf(“%c”, …) 就把这个残留的 \n 读走了——这就是为什么要在%c前面加一个空格来跳过空白符
核心结论:scanf 按格式读,多余的字符会留在缓冲区,污染后面的读取。
返回值
几乎所有函数都有返回值,除了返回void的函数
scanf返回值是成功读取的变量个数,失败返回EOF,藉此可以判断是否正确读取
getchar返回值是读到的字符int值,失败返回EOF
数学运算返回值就是运算结果值
零零散散的知识
i ++ 等价于i += 1,放在for循环里就可以说1是它的步长