体验第一个C程序

程序部分

来,复制这段内容,然后打开这个网页

粘贴进去,点击运行。

1
2
3
4
5
6
7
8
9
#include <stdio.h>

int main()
{
printf("哥哥你好,感谢你把我创造了出来!(`・ω・´)\n");
printf("最喜欢哥哥你了(*/ω\*)\n");

return 0;
}

解释上述代码

首先看到代码的第一行#include <stdio.h>

来理解一下,include在英文中有“包含”的意思,因此在这里也是同样

后边的<stdio.h>这个内容,首先来看里边的stdio.h,这个是一个文件的名字

比如你如果用Windows的话,一个可以执行的windows窗口程序的文件名应该是xxx.exe,一个可以运行的记事本文件应该是xxx.txt

因此,这个文件是一个叫做stdio的文件,它的后缀名是h。

另外,你想,中文中如果写什么文章的话,引用作品时是不是得加上书名号,这里也一样哦,只不过因为是英文的内容,就要加上英文的书名号<>啦。

如果你不能理解上面的内容也没有关系,只是记住,最开始你写的程序的第一行一定要按照这个内容去写就好。

下边来看第二行的代码int main()

首先咱们来科普一下一个英语单词Integer,这个单词在wiki百科中的定义为:整数,是序列{,4,3,2,1,0,1,2,3,}{\displaystyle \{\ldots ,-4,-3,-2,-1,0,1,2,3,\ldots \}}中所有的数的统称,包括负整数、零(0)与正整数。和自然数一样,整数也是一个可数的无限集合。这个集合在数学上通常表示粗体Z{\displaystyle Z}Z\mathbb {Z} ,源于德语单词Zahlen(意为“数”)的首字母。

好了,这并不重要。你只需要记住int代表的就是integer,也就是整数的含义。

继续看main这个单词,这个在英语中的定义是主,主要,主體,所以在代码中,这个也代表着同样的含义,也就是主要的的含义,这里可以表示函数的主入口。

说人话:也就是计算机是从这里开始看你的程序的。

接下来看一看第三行的代码

根据前两行的叙述,你肯定会觉得你已经理解了,不就是英文单词嘛,然后看到了printf这个单词,内心:what???

这里绝对不是我多打了一个字母,当然也就是说print你应该认识是打印的意思。

这里表示了同样的含义,也就是向屏幕上打印一行内容。

内容就是后边可以看到的中文内容啦。

接下来看第四行代码

这里有一个return,也就是英文的返回,那么我们返回什么呢?

你想呀,整个世界最初不就是茫茫宇宙中的一颗不起眼的小行星,经过数亿年的过程慢慢地吸引周围的其他小块,经过了各种各样的变化,最终才形成了咱们现在所居住的地球嘛。

所以,如果说返回最初的状态的话当然是0啦,因为最开始就是什么都没有嘛。

好像歌里唱的むしろ0からまた宇宙を始めてみようか

其他没有提到的内容

细心的你肯定会发现,我没有说到上文中的()、{}这两组符号了对不对。

嘿嘿,现在就要来解释了,首先刚才说的叫做main的程序入口,这个东西叫做函数

函数这个东西 就是和你理解的数学中那个概念是一样的,比如y=f(χ){\rm{y = f(}}\chi {\rm{)}},其作用就是给一个输入的内容,比如x,然后通过函数进行计算,最后输出计算结果y。

那么程序中也是一样的功能,只不过输入的内容不一定是一个数字,同样输出内容也不一定是一个数字。

接下来是{},这个你就记住是把相关的内容括起来放在一起的感觉就好。

比如文中,我声明了main()函数,那么,我需要把main()函数的函数体放在这个大括号里,这样计算机就可以明白我们要干什么啦。

稍微改一下,体验一下写程序的乐趣

代码部分

那么复制下边的代码,然后打开这个网页贴进去,点击运行。

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>

int main()
{
char str[100];
printf("哥哥要给妹妹起什么名字呢 :");
scanf("%s", str);
printf("\n哥哥你好,我是%s,感谢你把我创造了出来!(`・ω・´)\n", str);
printf("最喜欢哥哥你了(*/ω\*)\n");

return 0;
}

思考一下哪里有变化

首先是我加了一行char str[100];

根据上文内容,你是不是会想到这个char也是代表某一个英文单词呢?

对啦,就是character,这里取字符的意思。

那么这里来讲一下这一行的意思吧。

首先我声明了一个叫做str的长度为100的字符串类型变量。

字符串:一堆字符构成的一个串串。

字符:比如任意一个英文字母,或者一个汉字。一定是一个!

你是不是不能理解上边的内容,没关系,这里你可以理解为我告诉计算机我需要一个地方,这个地方我希望存放一些字符(也就是英文字母或者汉字),他们一共长度为100,一会儿我就要用了,所以先和你打声招呼。

那么接下来我再需要使用这个字符串的时候,我只需要记住它的名称,也就是这里的str就可以了。

我还加上了一行 scanf("%s", str);

这一行看着是不是和printf有一些相似,没错~

那么聪明的小可爱你是不是已经可以猜到了是什么意思了?

来看看我想的和你想的是否一样吧。

首先我先不看字母f,那么就剩下了scan,是不是很眼熟。

举个例子Scan the QR code.,没错,我们日常的扫二维码就是这个动词。

那么放在这里有什么用呢?

刚才你是不是给可爱的妹妹起了一个名字呢?

那么计算机其实做的就是扫描了你输入的内容,然后把这些内容放在了上一段说的那个str字符串中。也就是说,可爱妹妹的名字被计算机记了下来,留下了证据了。警察叔叔就是这个人

警察叔叔就是这个人!

图源:twi

咳咳咳。。。

你以为没了?

太天真了hhh

你有没有注意我修改了一行printf("\n哥哥你好,我是%s,感谢你把我创造了出来!(`・ω・´)\n", str);

理解不?不理解?

咱们一点点看,首先是\n,有没有发现,这个内容并没有被打印在屏幕上?

什么?没注意。。给我认真看啊kora

这个东西她叫做转义字符,也就是可以理解为和计算机定下的暗号,每当计算机看见这些暗号,就会执行一些特殊的任务。

什么?你问为什么不用函数,hhh

Too young, too simple

我上边是不是说了printf函数会打印出来引号里边的内容

什么没说过?

我不要你以为,我要我以为,现在开始你就记住了。

嗯!很好,那么如果我在引号里写上比如function();,你猜她会发生什么。

对,原封不动地打印出来,很好!

所以这个时候我就要和计算机定一些暗号了,在计算机给我打印文字的时候,我需要让计算机执行一些奇怪的操作。

这个就是转义字符了。

那么,这个转义字符的含义是换行。

还有很多转义字符哦,来看下这个表

转义字符意义ASCII码值(十进制)
\a响铃(BEL)007
\b退格(BS) ,将当前位置移到前一列008
\f换页(FF),将当前位置移到下页开头012
\n换行(LF) ,将当前位置移到下一行开头010
\r回车(CR) ,将当前位置移到本行开头013
\t水平制表(HT) (跳到下一个TAB位置)009
\v垂直制表(VT)011
\\代表一个反斜线字符’\’092
\’代表一个单引号(撇号)字符039
\"代表一个双引号字符034
\0空字符(NULL)000
\ddd1到3位八进制数所代表的任意字符三位八进制
\xhh1到2位十六进制所代表的任意字符二位十六进制

你有没有发现有一个叫做%s的东西,这个不是转义字符哦!

这个是占位符,和后边的str一起使用的说。

这边的功能是,将%s的位置使用str字符串的内容进行替换。也就是计算机开始证明你的罪证的时候了

所以这个占位符究竟是个什么东西呢?

这里我只列出下边的一部分内容,如果想看比较全的内容,可以去下边的参考链接中寻找C语言再学习 -- printf、scanf占位符这一项内容哦。同时下边的表格也是来源于那个链接的哦。

转换说明输出
%c一个字符
%d有符号十进制整数
%e浮点数、e-记数法
%E浮点数、E-记数法
%f浮点数、十进制记数法
%g根据数值不同自动选择%f或%e。%e格式在指数小于-4或者大于等于精度时使用
%G根据数值不同自动选择%f或%E。%E格式在指数小于-4或者大于等于精度时使用
%i有符号十进制整数(与%d相同)
%o无符号八进制整数
%p指针
%s字符串
%u无符号十进制整数
%x使用十六进制数字0f的无符号十六进制整数
%X使用十六进制数字0F的无符号十六进制整数

scanf的占位符

转换说明符意义
%c把输入解释成一个字符
%d把输入解释成一个有符号十进制整数
%e、%f、%g、%a把输入解释成一个浮点数(%a是C99标准)
%E、%F、%G、%A把输入解释成一个浮点数(%A是C99标准)
%i把输入解释成一个有符号十进制整数
%o把输入解释成一个有符号八进制整数
%p把输入解释成一个指针(一个地址)
%s把输入解释成一个字符串:输入的内容以第一个非空白字符作为开始,至下一个空白字符之前的全部字符
%u把输入解释成一个无符号十进制整数
%x、%X把输入解释成一个无符号十六进制整数

那么既然你已经看懂了上边的内容了

就让我们开始正式的内容吧。

介绍变量类型

C语言中有好多类型的变量呢

比如charintfloatdoublevoid

有什么用nie?

因为计算机处理所有东西用的都是这些类型的变量呀。

什么,没理解?

那换句话说,计算机非常笨,无论做什么事情,计算机做的就只有计算,也就是说无论是玩游戏还是看学习资料,只要你和计算机做互动,那么计算机做的所有工作都是一堆数字进行计算,是不是超级神奇?!

在计算机计算的过程中,会需要各种各样类型的变量,因此就出现了这些变量。

介绍运算符

上边说过了,计算机做的就只有数字的计算,因此我们可以定义一些计算方法,并告诉计算机。

对于C语言,有很多种计算已经定义好了,我们直接使用就可以,比如+、-、*、/分别代表加减乘除运算、%代表求余运算,也就是做除法时不允许出现小数,如果有余数直接保留、++表示将当前的变量加上1、--表示当前变量减一

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdio.h>

int main()
{
int a = 21;
int b = 10;
int c ;

c = a + b;
printf("Line 1 - c 的值是 %d\n", c );
c = a - b;
printf("Line 2 - c 的值是 %d\n", c );
c = a * b;
printf("Line 3 - c 的值是 %d\n", c );
c = a / b;
printf("Line 4 - c 的值是 %d\n", c );
c = a % b;
printf("Line 5 - c 的值是 %d\n", c );
c = a++; // 赋值后再加 1 ,c 为 21,a 为 22
printf("Line 6 - c 的值是 %d\n", c );
c = a--; // 赋值后再减 1 ,c 为 22 ,a 为 21
printf("Line 7 - c 的值是 %d\n", c );

}

看完上述内容,我只解释一个地方,就是 c = a + b;

这句话代表将a和b的值进行相加,并且将结果存在c中。

下边还有一些其他的运算符,将在下一讲中介绍

运算符描述实例
==检查两个操作数的值是否相等,如果相等则条件为真。(A == B) 为假。
!=检查两个操作数的值是否相等,如果不相等则条件为真。(A != B) 为真。
>检查左操作数的值是否大于右操作数的值,如果是则条件为真。(A > B) 为假。
<检查左操作数的值是否小于右操作数的值,如果是则条件为真。(A < B) 为真。
>=检查左操作数的值是否大于或等于右操作数的值,如果是则条件为真。(A >= B) 为假。
<=检查左操作数的值是否小于或等于右操作数的值,如果是则条件为真。(A <= B) 为真。

介绍判断

单if判断

你是不是真的以为计算机只会傻傻地运算?

其实计算机也会偷懒

计算机中有一个判断机制,也就是说,计算机在做运算之前会判断是否应该去做这个运算,如果不是,计算机才懒得去做。

还是直接先看代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>

int main ()
{
/* 局部变量定义 */
int a = 10;

/* 使用 if 语句检查布尔条件 */
if( a < 20 )
{
/* 如果条件为真,则输出下面的语句 */
printf("a 小于 20\n" );
}
printf("a 的值是 %d\n", a);

return 0;
}

这里使用了一个if函数,这个作用就是告诉计算机,我这个代码在执行的时候可以怎样偷懒。

有没有注意到if函数中的a < 20,这个就是上一节写的那些剩下的运算符,至于有什么用,嘿嘿,自己猜!

if-else判断

如果你认真思考的话,你可能会发现,如果我要让计算机偷懒的情况有很多的时候,尤其是这些情况呈补集关系的时候,我岂不是要写很多次if函数

Noh!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>

int main ()
{
/* 局部变量定义 */
int a = 100;

/* 检查布尔条件 */
if( a < 20 )
{
/* 如果条件为真,则输出下面的语句 */
printf("a 小于 20\n" );
}
else
{
/* 如果条件为假,则输出下面的语句 */
printf("a 大于 20\n" );
}
printf("a 的值是 %d\n", a);

return 0;
}

看见上边的程序了没,如果a>20的话,我可以直接使用else去解决。

当然如果你有很多种情况的话,多写几个if呗,就比如下边这个

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <stdio.h>

int main ()
{
/* 局部变量定义 */
int a = 100;

/* 检查布尔条件 */
if( a == 10 )
{
/* 如果 if 条件为真,则输出下面的语句 */
printf("a 的值是 10\n" );
}
else if( a == 20 )
{
/* 如果 else if 条件为真,则输出下面的语句 */
printf("a 的值是 20\n" );
}
else if( a == 30 )
{
/* 如果 else if 条件为真,则输出下面的语句 */
printf("a 的值是 30\n" );
}
else
{
/* 如果上面条件都不为真,则输出下面的语句 */
printf("没有匹配的值\n" );
}
printf("a 的准确值是 %d\n", a );

return 0;
}

是不是觉得C语言好厉害?

当然if也可以嵌套起来用哦,来看下这段代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <stdio.h>

int main ()
{
/* 局部变量定义 */
int a = 100;
int b = 200;

/* 检查布尔条件 */
if( a == 100 )
{
/* 如果条件为真,则检查下面的条件 */
if( b == 200 )
{
/* 如果条件为真,则输出下面的语句 */
printf("a 的值是 100,且 b 的值是 200\n" );
}
}
printf("a 的准确值是 %d\n", a );
printf("b 的准确值是 %d\n", b );

return 0;
}

看到了吗,我在一个if里边又写了一个if,这样使可以的哦

switch判断

这个不是老任的NS啊,这个是英文开关的意思,同时程序也可以理解成开关

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <stdio.h>

int main ()
{
/* 局部变量定义 */
char grade = 'B';

switch(grade)
{
case 'A' :
printf("很棒!\n" );
break;
case 'B' :
case 'C' :
printf("做得好\n" );
break;
case 'D' :
printf("您通过了\n" );
break;
case 'F' :
printf("最好再试一下\n" );
break;
default :
printf("无效的成绩\n" );
}
printf("您的成绩是 %c\n", grade );

return 0;
}

看下上边的代码

case代表是一种情况,因为这里定义了char类型的变量,因此case的值也应该是一个char,也就是一个字符,比如代码中的'a'

每一个case后边都需要紧跟着这个开关需要执行的代码,执行完这些代码后将不会继续做判断,会依次执行下边所有开关的代码。

因此我们需要一个break命令。

break是啥,打断。

也就是说,我是用了了一个break打断了复读机的复读(指继续执行下边的函数)

tips: 这里的大胆的作用范围仅限于switch函数作用范围

循环

不知道你有没有听过这样一个故事:

一富翁世不识字,人劝其延师 训子。师至.始训以执笔临朱。书一画则训曰:“一”字,二画则训曰: “二’,字.三画则训日:‘’三”字。其子便欣然投笔,告父曰:“儿已都晓字 义,何烦师焉?”乃谢去之。鱼时,父拟招所亲万姓者饮.令子晨起治状,久之不成。父趣之,其子患日:“姓亦多矣,奈何偏姓万,自朝至今.才完得五百余画。”

翻译一下:

胡图虽有钱,但大字不识一个。有人。戒劝他给几子请个教师。胡图认为有道理,就请来一位教书先生。一开学,老师先教胡图的儿子学写字。他把着学生的笔杆,写一画,告诉他是个“一,字;写两画,告诉他是个“二”字,写三画,告诉他是个“三,字。胡图的几子学到这里非常得意,把笔一丢,就去告诉他父亲说:“我学会了,我学会了!写字原来容易得很。我用不着老师了,把老师辞退吧,何必多花钱呢?”胡图听了也很高兴,就把老师辞了。过了几天,胡图邀请一个姓万的朋友吃饭,让儿子给他写一封请帖,儿子听到后就拿了笔和纸到书房里写了。胡图等到了太阳快落山了儿子也没有把请帖给他。于是他到书房去催儿子写快点。一进门就发现满屋子都是画满“一”的纸,他问儿子在干什么,儿子说:“他姓什么不好,偏偏要姓‘万’,害得我现在都还没写完。”

那么现在学了这么多程序了,我要你按照这个故事的方法写一个“万”字。

你该怎么做呢,写一万行printf("——");么?

虽然复制粘贴很快,你也可以按照指数增长的方法进行复制粘贴,但是这也好麻烦对不对。

那么你就需要学习这个叫做循环的法宝了

for循环

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>

int main ()
{
/* for 循环执行 */
for( int a = 10; a < 20; a = a + 1 )
{
printf("a 的值: %d\n", a);
}

return 0;
}

看代码,我解释一下,剩下你自己悟

这段代码的含义是a最开始为10,每做一次循环就给a的值加上1,一直做到a不再小于20,结束。

while循环

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>

int main ()
{
/* 局部变量定义 */
int a = 10;

/* while 循环执行 */
while( a < 20 )
{
printf("a 的值: %d\n", a);
a++;
}

return 0;
}

这段代码的含义和上边的是相同的,在这里不解释,请尽量自行理解哦。

do_while循环

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>

int main ()
{
/* 局部变量定义 */
int a = 10;

/* do 循环执行 */
do
{
printf("a 的值: %d\n", a);
a = a + 1;
}while( a < 20 );

return 0;
}

功能和作用都和上边的相同,但是这里判断顺序是不同的。

while循环是先进性判断a是否小于20,如果小于20执行下边的循环体。

可do_while是,无论a的值是多少,我都会先执行一次循环体,再进行判断。

具体体现在,对于while或者for函数来说,如果a的初始值设为大于等于20,那么循环体将不会被执行。

但是对于do_while循环来说,即使a的初始值大于20,我也会执行一次循环的函数体再进行退出。

所以,函数是什么?

看到这里有没有觉得晕头转向的?

先做个游戏吧

呐呐呐,咱们来玩点不一样的叭,别一直让我讲了|ू・ω・` ),接下来换你上。

emm。。玩点什么好呢?

那。。。嗯,决定了!咱们就来玩一个程序填空吧!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

#include<_________>

int fun(int, int);

int main(){
int i = 0;

i = fun(1,2);

printf("i=%d", i);

_________;
}

int fun(int a, int b){
// 返回一个数字,结果是a和b的和
int sum = 0;

sum = _________;

return _________;
}









不许偷看答案哦










好的,接下来我要公布答案啦

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

#include<stdio.h>

int fun(int, int);

int main(){
int i = 0;

i = fun(1,2);

printf("i = %d", i);

return 0;
}

int fun(int a, int b){
// 返回一个数字,结果是a和b的和
int sum = 0;

sum = a + b;

return sum;
}

你填对了嘛?

下边让我来解释一下吧

首先int fun(int, int);这一行

她的作用是声明一个叫做fun的函数,并且这个函数需要两个int类型的参数作为变量。

那么什么是声明呢?

盲生,恭喜你发现了华点

你有没有发现这个fun函数的具体定义在main函数的下边

这就导致了,当程序执行i = fun(1,2);一行的时候,程序不知道这个fun到底是干什么的,会报错的!

还记不记得我说过计算机很笨,计算机在看这个程序的时候是从上到下一行一行看的,你没有事先告诉计算机这个函数,就拿过来直接用的话,计算机那个猪脑子是不知道的,就会一个劲儿地报错。

所以如果你的函数实现在主函数的下边,咱们就迁就一下这个笨笨滴计算机,提前写一下声明好啦。

接下来看一下函数的实现吧

如果你还是没能理解函数究竟是干什么的,你可以想象一下,把调用函数的位置直接换成函数的具体内容。

比如上边的i = fun(1,2);这一行,如果按照替换的想法,可以直接变成i = 1 + 2;对不对。

这就是函数的功能啦。

至于为什么要有函数这个东西,当然是为了偷懒啦。

一个非常伟大的社会学家曾经说过:

懒和好奇心是第一生产力 —— 沃兹基硕德

你可以这样想,我上边的fun函数的功能是求两个int类型的整形数字的和,即使写很多次也不会省事很多。

但是如果我的函数是求从1加到输入数字的和呢?

比如下边这个函数

1
2
3
4
5
6
7
int fun(int num){
int sum;
for(int i = 1; i <= num; i++){
sum += i;
}
return sum;
}

每一次都要用一串循环替代的话,是不是要打很多字呢?

所以这个时候直接调用fun(100)这样一句话,就能解决小学时候困扰咱们很久的一个问题了

是不是很神奇呢?

这就是函数的功能啦

具体函数可以参照下边这个模型

1
2
3
4
5
6

返回值类型 函数名称(参数类型 参数名称x, ...){
具体函数体,可以使用参数x和其他参数;
return 需要返回的值,可以为空;
}

很可怕的指针

关于指针这个内容,我觉得有必要直接讲,因此这里暂时不写东西

我错了!我不应该不写指针的,这个内容还没有完结。

一句话学会指针

只要你记住了这句话,你就能理解指针的奥秘了。

“指针就是一个变量,只是它存储的内容是一个地址值。”————沃兹基硕德

看起来很容易是不是?

但是你真正能理解这句话么?

具体例子

例子1

在C语言中,有很多种指针,每种指针指向不同类型的变量。

比如

1
2
int a = 5;
int* p = &a;

这个代码片段中,p叫做整形类型的指针,其存储的是整型变量a在内存空间的地址值。

&a代表取得变量a的地址。

int*代表定义一个指向int类型变量的指针变量。

那么问题来了:变量p含有几个地址呢?

答案是2个,分别是p所在的物理地址和p所储存的整型变量a的地址。

再来一个问题,请写出下面的值:

1
2
3
4
5
6
7
8
a = _______

*a 表示_______

*p 表示_______

&p = 表示_______

1
2
3
4
5
6
7
a = <u>   5   </u>

*a 表示<u>不存在</u>

*p 表示<u>变量a的值</u>

&p = 表示<u>指针p的物理地址</u>

你答对了么?

例子2

这次直接看例子

1
2
3
int a = 5;
int* p = &a;
int** p1 = &p;

里边的p叫做一级指针p1叫做二级指针

是不是很懵,还记得我刚才说的那句话么?指针就是一个存储地址的变量。

因此这里p1是一个指向一级指针的指针变量,存储的内容就是一个整形指针的物理地址值。

因此有以下内容

1
2
3
**p1 = a = 5;
*p1 = *&p = &a;
*&p1 = &p;

但是不存在如下内容

1
2
3
4
5
6
&&a
&&p
&&p1
&*a
&*p
&*p1

以上是指针内容

下面开始做练习吧

第一部分

从简单到难题,只有比较复杂的题会提供参考答案哦

1、编程实现在屏幕上打印输出“Hello World!”

2、鸡兔同笼:“今有雏兔同笼,上有三十五头,下有九十四足,问雏兔各几何?”

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include<stdio.h>
void main()
{
int chicken; //鸡的数目
int rabbit; // 兔子数目
for(chicken=0;chicken<=35;chicken++)
{
rabbit=35-chicken;
if(2*chicken+4*rabbit==94)
{
printf("结果:chicken = %d , rabbit = %d \n", chicken, rabbit);
}
}
}

我曾经写过一个鸡兔同笼相关问题的文章,你可以去挑战一下能不能都用C语言实现出来

传送门:鸡兔同笼问题的解法

3.1.1、韩信点兵:士兵5人一行最后余1人;6人一行,最后余5人;7人一行最后余4人;11人一行,最后余10人。求总人数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include<stdio.h>
void main()
{
int max=10000; //假定士兵最多 为10000人
int i;
printf("符合条件的数有: \n");
for(i=21;i<max;i++)
{
if((i%5==1)&&(i%6==5)&&(i%7==4)&&(i%11==10))
{
printf("%d ",i);
}
}
printf("\n");
}

3.1.2、中国南北朝时期(公元5世纪)的数学著作《孙子算经》卷下第二十六题,叫做“物不知数”问题,原文如下:“有物不知其数,三三数之剩二,五五数之剩三,七七数之剩二。问物几何?”,即一个整数除以三余二,除以五余三,除以七余二,求这个整数。

《孙子歌诀》:“三人同行七十希,五树梅花廿一支,七子团圆正半月,除百零五使得知”。这个歌诀给出了模数为3、5、7时候的同余方程的秦九韶解法。意思是:将(明朝数学家程大位将解法编成易于上口的除以3得到的余数乘以70,将除以5得到的余数乘以21,将除以7得到的余数乘以15,全部加起来后除以105,得到的余数就是答案。)

这道题不提供答案哦,请现场写。

第二部分

1、定义两个整型变量x和y,并从键盘接受输入,然后计算这两个数的和、差、积与商,并在屏幕上显示输出其计算结果。

1
2
3
4
5
6
7
8
9
10
#include<stdio.h>
int main(){
int x,y;
scanf("%d %d",&x,&y);
printf("x+y=%d\n",x+y);
printf("x-y=%d\n",x-y);
printf("x*y=%d\n",x*y);
printf("x/y=%d\n",x/y);
return 0;
}

第三部分

1、建立项目文件,并在源文件中正确书写下列表达式,同时在屏幕上打印出表达式的运算结果。(其中,x,y是浮点型变量,初值由键盘输入)

χ2+γ3{\chi ^2} + {\gamma ^3}

第四部分

1、设一函数:

y={x,(x<1)3x2,(1x<6)4x8,(x6)y = \left\{ \begin{array}{l} x,(x < 1)\\ 3x - 2,(1 \le x < 6)\\ 4x - 8,(x \ge 6) \end{array} \right.

用scanf函数输入x的值,求y的值,并用printf函数在屏幕上打印输出。

提示:运行程序3次,分别检验在 , 和 三种条件下程序是否正确。

测试实例

输入:1 输出:1

输入:3 输出:7

输入:7 输出:20





2、给出一个百分制成绩,要求输出成绩等级Excellent,Good,Middle,Passed,Failed。其中,90分以上为Excellent,80-89为Good,70-79为Middle,60-69为Passed,60分以下为Failed

  • 要求程序分别用if语句和switch语句来实现。
  • 程序要能任何数据,当数据非法时(大于100或小于0)提示用户出错(屏幕上打印“Illegal”)。

    测试实例

    输入:100 输出:Excellent

    输入:88 输出:Good

    输入:75 输出:Middle

    输入:64 输出:Passed

    输入:37 输出:Failed

    输入:123 输出:Illegal

    输入:-55 输出:Illegal





3、编写一个简单计算器程序,输入格式为:data1 op data2.其中data1和data2是参加运算的两个数,op为运算符,其取值只能是+、-、*、/。

提示:根据op的取值使用switch语句实现计算功能。

测试实例

输入:5+8 输出:13

输入:5-8 输出:-3

输入:5*8 输出:40

输入:5/8 输出:0.625





4、编程打印输出求0~1000中同时能被7和13整除的那些数。

提示:利用单重循环(while, do…while, for)即可实现,在循环体内判断能否同时被7和13整除。

测试结果:

输出: 0 91 182 273 364 455 546 637 728 819 910




5、有一分数序列:2/1, 3/2, 5/3, 8/5, 13/8,21/13,……,编程求出这个数列的前20项之和。

提示

a) 数列中每一项的分子是前一项分子与分母之和,而分母为前一项的分子;

b) 利用单重循环(while, do…while, for)进行计算并累加求和。

测试结果:

输出: 32.66





6、编程序,由键盘输入10个整数,输出其中偶数之和以及偶数平均值。
提示
a)利用单重循环(while, do…while, for)接受从键盘输入,同时判读该数是否为偶数,并累加求和;

b)循环体外求平均值,然后将计算结果输出。

测试实例

输入:12 35 46 4 13 8 72 25 61 82

偶数之和:224

偶数平均值; 37.333333





7、利用公式e≈1+1/1!+1/2!+1/3!+…+1/n!, 编程序求e的近似值,直到第n项(1/n!) < 10-6为止。

提示

a)利用二重循环编程实现,其中内层循环求n!,外层循环进行累加求和;

b)外层循环终止条件:(1/n!) < 10-6

测试结果

输出:2.718281

方法一:

1
2
3
4
5
6
7
8
9
10
11
12
13
#include<stdio.h>
#include<math.h>
int main(){
double sum=1,s=1;
int n=1,jc=1;
while(s>=pow(10,-6)){
jc*=n; // jc 代表截成
n++;
s=1./jc;
sum+=s;
}
pntf("%f",sum);
}

方法二:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <stdio.h>
#include <math.h>

double fun(int num)
{
int res = 1;
for (int i = 1; i < num; i++)
{
res *= i;
}
// printf("%d",res);
return res;
}

int main()
{
double e = 0, tmp;
int i = 1;
while (1)
{
tmp = (1 / fun(i));
if(tmp < pow(10, -6)) break;
e += tmp;
i++;
}
printf("%f", e);
}

第五部分

1、定义1个一维数组:int arr[10],然后从键盘输入10个整数,编程求出其最大值、最小值以及平均值,并在屏幕上打印输出。

提示:在一个循环体内用scanf函数输入10个数,然后再用一个循环处理数据处理。

测试实例:

输入:100 10 -125 -9 0 90 70 60 300 -250

输出: max=300

min=-250

ave= 24.60





2、定义两个字符数组:char str1[80], str2[80],其中字符串str1接受从键盘输入,然后编程将字符数组str1的内容逐个拷贝到字符数组str2中。(不允许使用库函数strcpy)

提示:从键盘接受1个字符串输入str1后,使用一个循环将str1中字符逐个赋值给str2中的对应元素。

测试实例:

输入:Hello World! 输出:Hello World!





3、定义1个一维数组:int arr[20],然后从键盘输入20个整数,使用冒泡法编程将该数组从小到大进行排序,并将排序后结果打印在屏幕上。

提示:利用一个二重循环体实现冒泡排序(允许使用互联网搜索)。

测试实例:

输入:100 10 -125 -9 0 90 70 60 300 -250 -72 39 48 22 83 159 142 -129 -24 539

输出:-250 -129 -125 -72 -24 -9 0 10 22 39 48 60 70 83 90 100 142 159 300 539




4、将20个数存放在一个数组中,首先使用选择法对这20个数按升序排列,并输出排序后的结果;然后从键盘输入一个数,要求用二分查找的方法找出该数在数组中的位置(即下标),如果该数不在数组中,则输出“无此数”。

提示:首先利用一个二重循环实现选择排序;然后使用单重循环来实现二分查找。

测试实例:

输入: 100 10 -125 -9 0 90 70 60 300 -250 -72 39 48 22 83 159 142 -129 -24 539

输出:-250 -129 -125 -72 -24 -9 0 10 22 39 48 60 70 83 90 100 142 159 300 539

输入: -129

输出: 17

输入: 301

输出: 无此数





5、定义1个二维数组:int arr[5][6],然后从键盘输入5行6列共30个整数,编程求出所有元素中的最大值、最小值及其下标,同时求出每行元素的平均值,并在屏幕上打印输出。

提示:在一个二重循环体内用scanf函数输入30个数,然后再用一个二重循环处理数据处理。

测试实例:

输入: 6 5 4 3 2 1

7 8 9 10 11 12

13 14 15 16 17 18

24 23 22 21 20 19

30 29 28 27 26 25

输出:

Maximum:a[4][0]=30

Minimum:a[0][4]=1;

Average:

Ave[0]= 3.50

Ave[1]= 9.50

Ave[2]= 15.50

Ave[3]= 21.50

Ave[4]= 27.50

第六部分

1、一个素数,当它的数字位置对换以后仍为素数,这样的数称为绝对素数。编写一个程序,求出所有的两位绝对素数。

要求:

  • 编写函数int isPrime(int n)判断数n是否为素数;
  • 编写函数void absPrimeTens()打印输出求出所有的两位绝对素数;
  • 在主函数中调用函数absPrimeTens()
    测试实例:

    输出: 11 13 17 31 37
    71 73 79 97




2、写两个函数,分别求两个整数的最大公约数和最小公倍数,用主函数调用这两个函数,并输出结果,两个整数由键盘输入。

提示:

  • 编写函数int gcd(int m, int n)返回m和n的最大公约数;
  • 编写函数int lcd(int m, int n)返回m和n的最小公倍数。

测试实例:

输入:6 8 输出:2 24

输入:125 75 输出:25 375





3、求方程ax2+bx+c=0的根,用三个函数分别求当b2-4ac大于0、等于0和小于0时的根,并输出结果。

提示:

  • 编写函数void deltaZero(float a, float b, float c)求当b2-4ac等于0时的根;
  • 编写函数void deltaLargerZero(float a, float b, float c)求当b2-4ac大于0时的根;
  • 编写函数void deltaLessZero(float a, float b, float c)求当b2-4ac小于0时的根;
  • 另外,考虑当a=0时的情况,此时方程退化为一次方程。

测试结果:

输入: 0 1 1 输出: X=-1

输入:1 2 1 输出: X1=X2= -1

输入:1 3 2 输出:X1= -1 X2= -2

输入:1 2 2 输出:X1= -1+1i X2= -1-1i





4、求阶乘问题。要求定义函数fact(n)计算n!,主函数中输入一个正整数n,输出n!,要求函数fact(n)分别采用递归和非递归两种形式实现。
提示:

  • 递归版:主要利用递推公式 fact(n) = n * fact(n-1),并注意终止条件。
  • 非递归版: 主要利用单重循环实现。

测试结果:

输入:9 输出:recursive edition, 9!= 362880

输入:9 输出:no-recursive edition, 9!= 362880





5、输入10个学生5门功课的成绩,分别用函数求:

①每个学生的平均分;

②每门课平均分;

③找出最高的分数所对应的学生和课程;

④求出平均分方差:σ=1/n∑xi2-(∑xi/n)2,xi为某一学生的平均分。

要求:上述函数放在专门的程序文件prog_fun.c中,而主函数放在独立的程序文件prog_main.c中,并在主函数中调用上述所有函数进行测试。

最后编辑时间:2020-8-17 11:47:09 2020-8-19 23:45:13
这次真的已完结

参考链接

integer定义:https://zh.wikipedia.org/wiki/整数

main定义:https://zh.wiktionary.org/wiki/main

RADWIMPS「前前前世」歌詞 :http://hikikotori.hatenablog.com/entry/2016/07/05/232701

转义字符表格:https://blog.csdn.net/a3192048/article/details/90463894

部分代码参考:https://www.runoob.com/cprogramming/c-tutorial.html

C语言再学习 – printf、scanf占位符:https://blog.csdn.net/qq_29350001/article/details/52278308