因为想成为大佬,想记录我学习编程的成长过程,所以选择在掘金记录。 我会记录我最基本的日常学习内容以及心得体会,以及自己所遇到的坑,如何去解决的。 上高中的时候班主任就经常说:“没有无缘无故的成功。” 如此记录不仅是见证自己成长,更是希望给更多的人提供编程上的帮助。(会一直更新)
从最简单的HELLO C PRODRAM开始,我会一直更新,其中用的软件是DEV-C++,然后,程序中都有注意点和我所踩的坑,希望能对你们有帮助。
------------------------2021/2/19 18:46-------------------------------
第一章:
< 1.>
#输出控制符的笔记:
输出控制符包含如下:
%d------ int
%ld------ long int
%c------ char
%f------ float
%lf------ double
%x(或者%x或者%#x)------ int 或 long int 或 short int
以十六进制输出的整型都可。
%o------ 同上
以八进制输出的整型
%s------ 字符串
< 2.>
以下是相对应的代码:
/*
2020/12/23 17:05 功能:从硬盘某个文件读取某个数据输出在另一个文件 目的:测试%x %X %#x %#X的用法
*/
include <stdio.h>
int main()
{
int i = 47; //47是十进制
printf("%d\n", i); //输出结果是47
printf("%x\n", i); //输出结构为2f
printf("%X\n", i); //输出结果为2F
printf("%#x\n", i); //输出结果为0x2f (0是数字,不是字母)
printf("%#X\n", i); //输出结果是0X2F
return 0;
}
/*
在DEV-C++中输出的结果为:
----------------------
47
2f
2F
0x2f
0X2F
----------------------
将来你自己看的时候都不用运行了,一目了然。(不同的软件结果可能不太一样。)
心得:
其次重要的一点是一般都推荐使用%#x和%#X,因为你的程序不是只给你自己一个人看的
0f表示输出结果为十六进制,要比其它几个输出结果更直接明白。
否则别人只认为是输出了一个数字和一个字母而已。
注意:
敲代码的规范性要求符号成双成对!先(后)再;再将光标移动到双括号中间进行输入,
有时代码很多的时候你没法找出这种缺少()的错误 。
*/
/*
2020/12/23 17:56
目的:
通过测试明白输出控制符的含义
*/
include <stdio.h>
int main(void)
{
int i = 33; //定义整型33
printf("i = %d\n", i); //用输出控制符%d的意义是将33这个二进制01代码用 整型 输出
printf("i = %#X\n", i); //用输出控制符%#X的意义是将33这个二进制01代码用 十六进制 输出
printf("i = %o\n", i); //用输出控制符%o的意义是将33这个二进制01代码用 八进制 输出
return 0;
}
/* 在DEV-C++中运行结果为:
i = 33 i = 0X21 i = 41
暂无心得 */
< 3.>
输入工具 scanf 的知识点笔记:
Scanf的使用
【通过键盘将数据输入到变量中】
两种用法:
- scanf(“输入控制符”,输入参数);
功能:将从键盘输入的字符转化为控制字符所规定格式的数据,然后存入以输入参数的值为地址的变量中;
- scanf(“非输入控制符 输入控制符”,输入参数);
功能:将从键盘输入的字符转化为控制字符所规定格式的数据,然后存入以输入参数的值为地址的变量中;
非输入控制字符必须原封不动的输入;
< 4.>
相对应的代码:
/*
2020/12/24 16:44
目的:测试scanf中非输入控制符的注意事项
*/
include <stdio.h>
int main()
{
int i;
scanf("m%d", &i); //m属于非输入控制符 m123正确 123错误 m123n正确
printf("i = %d\n", i); //i输出结果为整型部分
return 0;
}
/* 此程序在DEV-C++中的输出结果为:
m123 i = 123
123 i = 0
m123n i = 123
*/
/* 心得: 在scanf中使用非输入控制符时要注意运行时要原封不动将非输入控制字符输入 注意事项: 在scanf使用时 1.m%d后不像printf中%d的后面加\n 否则不会输出内容 */
< 5.>
除法运算符和取余运算符的笔记:
/(除法)的运算结果与运算结果的数据类型相关,比如两个数都是int,则商就是int,若商有小数,则截取小数部分只保留整数部分。
被除数和除数中只要有一个或者二者都是浮点型数据,则商也是浮点型数据,不截取小数部分。
Eg: 16 / 5 = 3; 16 / 5.0 = 3.20000; -13 / 4 = -3;
%(取余)的运算对象要求必须是整数,结果是整除后的余数,其余数的符号与被除数的符号相同。(被除数 / 除数 = 商)
Eg: 13 % 3 == 1; 13 % -3 == 1; -13 % 3 == -1;
-13 % -23 == -13(商零余13); 3 % 5 == 3(商零余3);
👇
注意这个不是负负得正!商的符号只取决于被除数。
< 6.>
相对应的代码:
/*
2021/01/10 12:27
功能:测试取余运算符的结果
*/
include <stdio.h>
int main(void)
{
printf("%d %d %d %d %d %d %d", 13 % 3, 13 % -3, -13 % 3, -13 % -3, 3 % 5, -3 % 5, -3 % -5);
return 0;
}
/*
在DEV-C++中的输出的结果是
-----------------------------
1 1 -1 -1 3 -3 -3
-----------------------------
注意:取余的对象数据类型都必须是整数类型;
心得:
取余的商的符号只与被除数的符号相同,
而且,类似:3 % 5 =3(商零余3,所以取余是3);
*/
< 7.> 逻辑用语使用:
/*
2020/01/14 14:12
测试逻辑用语 &&(并且)、||(或)的用法;
*/
#include <stdio.h>
int main(void)
{
int i = 10;
int k = 4;
int h = 3;
int g = 7;
int m,n,p;
m = (3>2) && (k = 8);/*当&&的左边是真必须要执行后面的表达式,
把8赋值给K后是个真值(非零数是真,但是执行结果为真的时候必为 1 ),
所以执行m = 1,k = 8;
*/
n = (1>2) && (h = 5);/*当&&左边是假 , “一票否决 ”无论右边是真是假,结果都一定为假,
所以右边的表达式不用执行(此程序直接输出定义的 h 值)
即:n = 0, h = 3;
*/
p = (3>2) || (g = 9);/*当||左边是真,“一票确定 ”无论右边是真是假,结果都一定为真,
所以右边的表达式不用执行(此程序直接输出定义的 g 值)
即:p = 1, g = 7;
当||左边是假,就要由右边是真是假来决定 p 的真假,
所以必须执行右边的表达式;
*/
printf("m = %d, k = %d, n = %d, h = %d, p = %d, g = %d",m, k, n, h, p, g);
return 0;
}
/*
在DEV-C++中执行结果为
m = 1, k = 8, n = 0, h = 3, p = 1, g = 7
心得:
根据逻辑运算符左边的表达式的真假,也就是“一票否决 ”、“一票确定 ”这种来决定右边是否执行
而且所有 非零值是 “真 ”
零是 “假 ”
*/
第二章:
< 1.>
if的使用笔记:
if最简单的使用。
格式:
if (表达式)
语句;
功能:
如果表达式为真,则语句执行;
如果表达式为假,则语句不执行;
2. if 的范围问题。
格式1: if (表达式)
语句1;
语句2;
解释:if 的表达式如果为真,则只执行语句1,而不执行语句2;
格式2: if (表达式)
{
语句1;
语句2;
}
解释:if 的表达式如果为真,则语句1、语句2都执行;
由此可见:if 只能控制一个语句是否执行;
如果想要控制多个语句是否执行,要用{ }括起来;
3. if、、、else if、、、else的用法。
格式:
if (表达式1)
语句1;
else if (表达式2)
语句2;
else if (表达式3)
语句3;
else
语句4;
解释:若表达式1不成立且表达式2成立,则执行语句2;
若表达式1,2都不成立且表达式3成立,则执行语句3;
若表达式1,2,3都不成立,则执行语句4;
补充穿插if 循环 “强制转换” 的小知识点:
首先,要理解 float 和 double 都不能保证将一个数据完整存储下来。
Eg: float 0; 并不一定是0;可能是一个接近零的浮点数,0.0000000000000000000001也会保存为0;
< 2.>
相对应的代码:
< A.>
/*
2021/1/27 19:08
功能:
测试if 简单用法中重点注意的地方。
*/
include <stdio.h>
int main(void)
{
if (3)
printf("AAAA\n"); // 能输出
if (0)
printf("BBBB\n"); //不能输出
if (0==0)
printf("CCCC\n"); //能输出
return 0;
}
/* 在Dev-c++中输出的结果为:
AAAA CCCC
心得:一个非零数是真,零是假,0==0这个表达式是正确的, 所以 if 控制的语句能输出。
*/
< B.>
/*
2021/1/27 19:23
功能:
测试 if 控制的范围
*/
include <stdio.h>
int main(void)
{
if (1>2)
printf("AAAA\n"); //不能输出
printf("BBBB\n"); //能输出
return 0;
}
/*
在Dev-c++中输出的结果为:
BBBB
心得: if 中的表达式为假,if 控制的语句不能输出; 输出结果为 BBBB,说明 if 控制的语句只有一句; 注意: 当语句不属于上一个判断语句时, 需要将这个语句靠齐判断语句的开头;
*/
< C.>
/*
2021/1/27 19:32
功能:
if 控制的范围可以用 { } 括起来;
*/
include <stdio.h>
int main(void)
{
if (1>2)
{
printf("AAAA\n");
printf("BBBB\n");
}
printf("CCCC\n");
return 0;
}
/* 在Dev-c++中输出结果为:
CCCC
心得: 当 if 想控制多个语句的时候,需要用 { }括起来; 同时,if 不能控制的语句需要缩进。
*/
< D.>
/*
2021/1/27 20:59
功能:测试 if、、、else、、、的用法。
*/
include <stdio.h>
int main(void)
{
double delta ;
printf("请输入 delta 的值 %lf\n", delta);
scanf("%lf", &delta);
if ( delta > 0)
printf("二元一次方程有两个不同的解");
else if ( delta == 0)
printf("二元一次方程有且只有一个解");
else
printf("二元一次方程没有解");
return 0;
}
/*
在Dev-c++中输出结果为:
请输入 delta 的值 0.000000
5
二元一次方程有两个不同的解
心得: 其实也可以有这个 格式 if (表达式1) printf (语句1); else if (表达式2) printf (语句2); else if (表达式3) printf (语句3); else printf (语句4);
注意:鉴于个别软件保存文件的方式不一样, 先说一下,当文件名为: if、、、else、、、 当你运行的时候无法运行, 原因就是文件名后缀都是、加什么, 比如c文件文件名是: 、c 而此时、后边是else、、、 所以没法运行c文件。 在必要条件下加一个、c进行保存。 */
< E.>
/*
2021/1/30 19:35
功能:测试 if 对于成绩的简单判断;
*/
include <stdio.h>
int main(void)
{
float score;
printf("请输入您的成绩:");
scanf("%f", &score);
if ( score >100 )
printf("做梦!");
else if ( score >= 90 && score <= 100 ) //不能写成 90 <= score <=100 ;否则输出结果都是1,表达式为真,输出为1;
printf("成绩优秀!");
else if ( score >= 80 && score <90 )
printf("成绩良好!");
else if ( score >= 60 && score <80 )
printf("及格!");
else if ( score >= 0 && score <60 )
printf("成绩不及格,继续努力!");
else
printf ("成绩有误,请重新输入!");
return 0;
}
/*
在DEV-C++中运行结果为:
请输入您的成绩: 45 成绩不及格,继续努力!
心得: 表达式写法不能直接按照数学习惯写编程 例如 : 90 <= score <= 100;
*/
< F.>
/*
2021/1/30 20:24
功能:利用 if 互换值
*/
include <stdio.h>
int main(void)
{
int i,j;
int t; //定义一个临时变量;
//7、8行代码无法完成 i 和 j 值的互换;
i=3;
j=4;
// i=j; //7行 i = 4 j=4 // j=i; //8行 j = 4 换了半天还是将 i = 4 又赋值给了 j
//正确的 i 和 j 的互换过程; t = i; i = j; j = t;
printf("i = %d j = %d\n", i, j);
return 0;
}
/*
在DEV-C++中运行的结果为:
i = 4 j = 3
心得: 互换两个值的时候需要定义一个临时值 t (temporary 临时的) 并且记住顺序: t = i i = j j = t 举的例子是一瓶可乐,一瓶雪碧,一个空瓶子的交换;
*/
< G.>
/*
2021/2/2 19:25
功能: 测试 if 给任意的三个数排序
*/
include <stdio.h>
int main(void)
{
int a, b, c;
printf("输入三个数(请用空格隔开):", a, b, c);
scanf("%d %d %d", &a, &b, &c);
//用编码将 a为最小值 b为中间值 c为最大值 输出
int t;
if ( a < b )
{
t = a;
a = b;
b = t;
}
if ( a < c )
{
t = a;
a = c;
c = t;
}
if ( b < c )
{
t = b;
b = c;
c = t;
}
printf("输入的三个数从大到小排序为:%d %d %d\n", a, b, c);
return 0;
}
/*
在DEV-C++中运行结果是:
输入三个数(请用空格隔开): 4 8 5 输入的三个数从大到小排序为:8 5 4
心得: 多个数字或者字母排序时可以通过比较然后互换值 也就互换位置(冒泡法)
*/
第三章:
< 1.>
/*
2021/2/13 9:49
功能:测试 for 循环嵌套的简单使用
*/
include <stdio.h>
int main(void)
{
int i,j;
for (i=0; i<3; ++i)
for (j=2; j<5; ++j)
printf("哈哈\n");
printf("嘻嘻\n");
return 0;
}
/*
在DEV-C++中运行结果为:
哈哈
哈哈
哈哈
哈哈
哈哈
哈哈
哈哈
哈哈
哈哈
嘻嘻
心得:
注意运行的顺序。 比如:
for(1;2;3)
{ for(4;5;6)
printf("7");
}
运行顺序为 1,2(若2满足条件),(执行)4,5(如果满足条件),(执行)6,直到第二个for循环结束
才进行 3,2,4,5,6,5,6......
*/
< 2.>
/*
2021/2/13 9:53
功能:测试 for 循环嵌套的复杂使用
*/
include <stdio.h>
int main(void)
{
int i,j;
for (i=0; i<3; ++i)
{
printf("嘿嘿\n");
for(j=2; j<5; ++j)
{
printf("哈哈\n");
printf("嘻嘻\n");
}
printf("呜呜\n");
}
return 0;
}
/*
在DEV-C++中运行结果为:
嘿嘿
哈哈
嘻嘻
哈哈
嘻嘻
哈哈
嘻嘻
呜呜
嘿嘿
哈哈
嘻嘻
哈哈
嘻嘻
哈哈
嘻嘻
呜呜
嘿嘿
哈哈
嘻嘻
哈哈
嘻嘻
哈哈
嘻嘻
呜呜
心得:
复杂的使用更要注意顺序。 顺序查看D:/桌面/c program and self-study/program and result/for循环的嵌套使用-1
*/
-----------------------------------我是分界线------------------------------------------
如果有想要for有关的问题的评论我,因为牵扯问题有点多,我直接把我记录的文件发给你。
例如:
for循环强制转换
for求奇数和
for求能整除3的整数和
for求奇数的个数
for求奇数的平均值
for求奇数和偶数的和
这类问题的程序我不再一一列举,用一个程序也可以,分开说能好分析,如有需要的小伙伴私信我。 谢谢支持!
----------------------------来来来,继续继续!-----------------------------------
< 3.>
/*
2021/2/14 9:19
功能:利用while判断回文数(牵扯算法)
*/
include <stdio.h>
int main(void)
{
int val;
int m;
int sum = 0;
printf("请输入一个任意的值:\n");
scanf("%d",&val);
m = val;
while(m)
{
sum = sum*10+m%10;
m = m/10;
}
if(sum==val)
printf("YES!\n");
else
printf("NO!\n");
return 0;
}
/*
在DEV-C++中 运行结果为:
请输入一个任意的值:
12321 YES!
解释:回文数就是一个数正着和倒过来都是一个数。
心得:如果不能想出来如何去编写这个程序,那就把别人的算法理解记住。
思考:为什么不能直接用一个val代入while? 因为在执行val=val/10之后,val的值就不是你输入的值了,所以在if判断sum = val时就不对了。
*/
< 4.>
include <stdio.h>
int main(void)
{
int a1 = 1, a2 = 2, a3 = 3;
int n, i;
printf("请输入你想开始的值得到你想要的菲波拉契序列:\n");
scanf("%d", &n);
if(n==1)
a1 = 1;
else if(n==2)
a2 = 2;
else if(n==3)
a3 = 3;
else
{
for(i=3; i<=3; ++i)
{
a(i+1) = a(i) + a(i-1);
printf("a(i+1)\n");
}
}
return 0;
}
< 5.>
/*
2021/2/15 11:17
功能:利用for循环求斐波拉契序列。
*/
include <stdio.h>
int main(void)
{
int n;
int f1, f2, f3;
int i;
f1 = 1;
f2 = 2;
printf("请输入你需要的序列:\n");
scanf("%d", &n);
if(1==n)
f3 = 1;
else if(2==n)
f3 = 2;
else
{
for(i=3; i<=n; ++i)
{
f3 = f1 + f2;
f1 = f2;
f2 = f3;
}
}
printf("%d\n", f3);
return 0;
}
/*
在DEV-C++中运行结果为:
请输入你需要的序列:
7 21
注意:看懂程序多敲击几遍。
*/
< 6.>
include <stdio.h>
include <math.h> //调用<math.h>的sqrt(求根)
int main(void)
{
double a, b, c;
double delta;
double x1, x2;
char ch;
do
{
printf("请输入一元二次方程的三个系数:\n");
printf("a = ");
scanf("%lf", &a);
printf("b = ");
scanf("%lf", &b);
printf("c = ");
scanf("%lf", &c);
delta = b*b - 4*a*c;
if(delta>0)
{
x1 = (-b + sqrt(delta))/(2*a);
x2 = (-b - sqrt(delta))/(2*a);
printf("此一元二次方程有两个解:x1 = %lf, x2 = %lf\n", x1, x2);
}
else if(delta=0)
{
x1 = x2 = (-b)/(2*a);
printf("此一元二次方程有且仅有一个解:x1 = x2 =%lf\n", x1, x2);
}
else
printf("无实数解!\n");
printf("您想继续请按(y),否则按任意键。\n");
scanf(" %c", &ch); //%c前面有空格
}while('y'==ch || 'Y'==ch);
return 0;
}
/*
在DEV-C++中运行结果为:
请输入一元二次方程的三个系数:
a = 1
b = 2
c = 2
无实数解!
您想继续请按(y),否则按任意键。
y
请输入一元二次方程的三个系数:
a = 3
b = 2
c = 1
无实数解!
您想继续请按(y),否则按任意键。
y
请输入一元二次方程的三个系数:
a = 4
b = 6
c = 1
此一元二次方程有两个解:x1 = -0.190983, x2 = -1.309017
您想继续请按(y),否则按任意键。
e
注意:“%c”的%c前面要有一个空格。
*/
--------------------2021/2/19更新(switch与break continue)----------------------------
< 7.>
/*
2021/2/17 20:28
功能:测试break是否能直接用于if语句。
*/
include <stdio.h>
int main(void)
{
int i;
for(i=0; i<3; ++i)
{
if(3>2)
break; //break不能直接用于if语句,除非if是一个循环的子语句。而且,根据运行结果可以知break终止的是外部的for循环。
printf("哈哈!\n");
}
return 0;
}
/*
在DEV-C++中运行结果为:
Process exited after 4.493 seconds with return value 0 请按任意键继续. . .
没有输出语句,说明break终止的是外部的for循环,而非if语句。
*/
< 8.>
/*
2021/2/17 21:00
功能:测试当break处于多层嵌套中时终止作用于哪一个。
*/
include <stdio.h>
int main(void)
{
int i,j;
for(i=0; i<3; ++i)
{
for(j=2; j<=4; ++j)
break;
printf("嘿嘿!\n"); //运行三次,说明只有第一个循环执行了。
}
return 0;
}
/*
在DEV-C++中运行结果为:
嘿嘿! 嘿嘿! 嘿嘿!
Process exited after 4.56 seconds with return value 0 请按任意键继续. . .
注意:当break用于循环多层嵌套中时,break只终止距离它最近的循环。
*/
< 9.>
include <stdio.h>
int main(void)
{
int x=1, y=0, a=0, b=0;
switch(x)
{
case 1:
switch(y)
{
case 0:
a++;
break;
case 1:
b++;
break;
}
b=100;
break;
case 2:
a++;
b++;
break;
}
printf("输出a、b的值:%d %d", a, b);
return 0;
}
/*
在DEV-C++中运行结果为:
输出a、b的值:1 100
Process exited after 4.619 seconds with return value 0 请按任意键继续. . .
*/
< 10.>
/*
2021/2/19 11:33
功能:测试break在switch多层嵌套的使用。
*/
include <stdio.h>
int main(void)
{
int x=1, y=0, a=0, b=0;
switch(x)
{
case 1:
switch(y)
{
case 0:
a++;
break;
case 1:
b++;
break;
}
b=100;
break;
case 2:
a++;
b++;
break;
}
printf("输出a、b的值:%d %d", a, b);
return 0;
}
/*
在DEV-C++中运行结果为:
输出a、b的值:1 100
Process exited after 4.619 seconds with return value 0 请按任意键继续. . .
说明break在switch多层嵌套中只对距离他最近的起终止作用。
*/
/*
2021/2/19 12:23
功能:测试continue的简单使用。
*/
include <stdio.h>
int main(void)
{
int i,j;
char ch;
scanf("%d",&i);
printf("i = %d\n", i);
while((ch=getchar()) !='\n') //第7行 键盘输入的字母赋值给ch,这个值不等于换行符则继续执行这个语句,知道你按换行键终止。
{
continue; //第8行
}
scanf("%d",&j);
printf("j = %d\n", j);
return 0;
}
/*
背景:要求非法输入的 i 值不影响 j 的赋值。
如果 没有第7行,第8行代码,若非法输入 i = 1 ajdasjnj 则输出结果 i = 1, j = (一串垃圾数值)。 相当于不直接让你键盘输入 j 的值,直接自动将 ajdasjnj赋给了 j 。
自行输入试值!
*/
-----------------------补充笔记:--------------------------------------
break 和 continue
1.break:
break如果用于循环,是终止循环。
break如果用于switch(选择语句),终止switch。
break不能用于if语句,除非if属于一个循环的子语句。
例子:
for(i=0; i<3; ++i)
{
If(3>2)
break;
printf(“哈哈!\n”);
}
虽然break是if的语句,但是终止的却是外部的for循环。所以printf(“哈哈!\n”);不能被执行。 在多层循环嵌套中break只终止距离他最近的循环。
例子:
for(i=0; i<3; ++i)
{
for(i=2; i<=4; ++i)
break;
printf(“嘿嘿!\n”);
}
运行结果为:嘿嘿! 嘿嘿! 嘿嘿!
说明break只能终止距离它最近的循环,只有第一个循环运行。
当break在switch的多层嵌套中使用时,也是终止距离它最近的switch。
例子:
int x=1, y=0, a=0, b=0;
switch(x)
{
case 1:
switch(y)
{
case 0:
a++;
break;
case 1:
b++;
break;
}
b=100;
break;
case 2:
a++;
b++;
break;
}
printf("输出a、b的值:%d %d", a, b);
return 0;
}
输出a、b的值:1 100
以上几个例子说明break不论在循环嵌套还是选择嵌套中,都是对最近的循环或者选择起终止作用。
2.continue:
用于跳过该循环的剩余语句,
直接去判断是否执行下一次循环。
例子:
a.
for(1; 2; 3)
{
A;
B;
continue;
C;
D;
}
则执行完continue后直接跳过C,D。直接执行3,也就是说C,D不被执行。
b.
while(表达式)
{
A;
B;
continue;
C;
D;
}
则执行完continue后直接跳过C,D。直接执行 表达式 ,也就是说C,D不被执行。
注意:此时for与while互换时,for的3语句要放在continue的前面!否则3会被continue跳过!