C语言笔记04_判断一个数是否为质数

C语言 笔记04

本章涉及《啊哈C》第五章内容

1.程序的3种结构
程序在执行时有几种结构,三种:

  1. 自上而下执行——顺序执行
  2. 判断条件执行——选择执行
  3. 循环条件执行——循环执行

2.a++,a--,a+=1

简写 实际意义
a++ a=a+1
a-- a=a-1
a+=2 a=a+2
a-=2 a=a-2
a*=2 a=a*2
a/=2 a=a/2
a%=2 a=a%2

还有++a,--a以后再讲。

3.逻辑挑战7.判断质数很简单

质数(素数)的定义:指大于1的自然数,除了1和该整数自身外,无法被其他自然数整除。
合数的定义:比1大但不是质数的数。

所以我们要判断一个数字a是不是质数,要将a分别除以2,3,4,……,a-2,a-1。如果从2到a-2的所有数都不能被a整除,那么说明a为质数,否则为合数。比如我们判断5是否为质数:

  • 5%2!=0
  • 5%3!=0
  • 5%4!=0

即2 3 4 不能被5整除,所以5是一个质数。

用代码来呈现为:

int a;
a=5;
if(a%2!=0 && a%3!=0 && a%4!=0)
    printf("质数");
else
    printf("合数");

也可从反面判断:

int a;
a=5;
if(a%2==0 || a%3==0 || a%4==0)
    printf("合数");
else
    printf("质数");

……
同样的,我们面对较大的数字,要判断它是否为质数则会随着数的增大而程序更加繁琐,所以我们要改进。
比如if条件我们可以用for循环来解决:

我的改进01:

int a,i;
a=5;     
f=0;
for(i=2,i<=4,i++)  // i总比a小1
{
    if a%i==0
        printf("合数");
    else
        printf("质数");
}

输出:

质数质数质数

发现问题:如果这样写,那如果我们要判断一个很大的数比如1000,那么就会打印出998个……

我的改进02:

引入一个新的量f,用f的两个值来对应合数和质数:

f 质or合
0 质数
1 合数

加入for循环,循环a-2次判断a是否能整除其中某一个数,如果有,则令f=1;如果没有,则令f=0:

int a,i,f;
a=6;
for(i=2;i<=5;i++)
{
    if(a%i==0)
        f=1;
    else
        f=0;
}
if(f==0)
    printf("质数");
else
    printf("合数");

输出:

质数

错误!显然6不是质数啊!回头看看才发现for循环中if虽然起到了判断合数的作用,但由于处于循环之中,6要除以2、3、4、5,那么for循环中f的值的变化为:

1 1 0 0

即最后6/5!=0,所以f=0,判断为质数。这是程序设计上的错误,错误为:虽然我们要对所有的a-2个数都判断,但对于不能被整除的我们不必加入else条件,for循环中只需要存在一个if条件即可。换言之,只需要找到一个余数为0的值,对于余数不为0的值我们不需要在for循环中提到!

我的改进03:

int a,f,i;
a=6;
f=0;
for(i=2;i<=5;i++)
{
    if (a%i==0)
        f=1;
}
if (f == 0)
    printf("质数\n");
else
    printf("合数\n");

输出:

合数

正确!
完整代码如下:

#include <stdio.h>
#include <stdlib.h>
int main()
{
    int a,f,i;
    a=8;
    f=0;
    for(i=2;i<=7;i++)
    {
        if (a%i==0)
            f=1;
    }
    if (f == 0)
        printf("质数\n");
    else
        printf("合数\n");
    system("pause");
    return 0;
}

升级01:输入a判断是否为质数

int a,f,i;
f=0;
scanf("%d",&a);
for(i=2;i<=a-1;i++)
{
    if (a%i==0)
        f=1;
}
if (f == 0)
    printf("质数\n");
else
    printf("合数\n");
system("pause");
return 0;

升级02:输入a,输出a的所有约数和判断a是否为质数

#include <stdio.h>
#include <stdlib.h>
int main()
{
    int a,f,i;
    f=0;
    scanf("%d",&a);
    for(i=2;i<=a-1;i++)
    {
        if (a%i==0)
        {
            f=1;
            printf("%d",i);
        }
    }
    if (f == 0)
        printf("质数\n");
    else
        printf("合数\n");
    system("pause");
    return 0;
}

4.更快一点:break

我们可以利用break提高效率,前面我们需要判断所有a-2个数,现在有了break就能达到以下目的:遇到第一个合数,马上退出当前循环。

#include <stdio.h>
#include <stdlib.h>
int main()
{
    int a,f,i;
    f=0;
    scanf("%d",&a);
    for(i=2;i<=a-1;i++)
    {
        if (a%i==0)
        {
            f=1;
            break;    //退出循环
        }
    }
    if (f == 0)
        printf("质数\n");
    else
        printf("合数\n");
    system("pause");
    return 0;
}

再举个例子:

int i,f;
f=0;
for(i=1;i<=10;i++)
{
    if(i==6)
        break;  //退出循环
    printf("%d",i);
}

输出:

12345

也就是说当i为6时,直接退出循环,而不会执行for循环中后面的语句printf("%d",i);

5.continue

提到break就要想到continue啦!那么continue的作用是什么呢?
continue:跳过后面语句直接进入下一轮循环

例子:打印100内的所有偶数

int a;
for(i=1;i<=100;i++)
{
    if(i%2==1)
        contine
    printf("%d",i);
}

6.逻辑挑战8:验证哥德巴赫猜想

本节我觉得书本中讲得很好,就不用自己的话来描述了,可以回头复习复习。


int k,a,b,i,fa,fb;
for(k=4;k<=100;k=k+2)
{
    for(a=2;a<=k/2;a++) 
    {
        fa=0;
        for(i=2;i<a-1;i++)  // 判断a是否为质数
        {
            if(a%i==0) { fa=1; break;}  
        }
        if(fa==0)    // 如果a为质数
        {
            b=k-a;
            fb=0;
            for(i=2;i<b-1,i++)  // 判断b是否为质数
            {
                if(b%i==0) { fb=1; break;}
            }
            if (fb==0)   // 如果b也是质数
            { printf("%d=%d+%d\n",k,a,b);break; }
            // 打印这个解并跳出循环
        }
    }
}

《啊哈C》:这里只验证了4到100的数,当然你可以验证更大的范围。当然,去验证哥德巴赫猜想有很多种方法,显然这种方法是不够好的,判断质数的部分也不够快,这里只是提供一种思路,等你看完了第6章再回头过来看,我想你一定可以找到更高效的方法。

7.逻辑挑战9:水仙花数

有一种三位数特别奇怪,这种数的“个位数的立方”加上“十位数的立方”再加上“百位数的立方”恰好等于这个数。例如:153=1×1+5×5+3×3,我们为这种特殊的三位数起了一个很好听的名字——“水仙花数”,那么请你找出所有的“水仙花数”吧。

法一:拼接法,列出所有可能拼出3位数

首先用3个循环嵌套打印出100~999所有三位数,然后加入if条件判断后打印出水仙花数:if(i100+j10+k=iii+jjj+kkk)**

int i,j,k;
for(i=1;i<=9;i++)
{
    for(j=0;j<=9;j++)
    {
        for(k=0;k<=9;k++)
        {
            if(i*100+j*10+k==i*i*i+j*j*j+k*k*k)
                printf("%d%d%d\n",i,j,k);  // 可以改进:printf("%d",i*100+j*10+k);
        }
    }
}

完整代码如下:

#include <stdio.h>
#include <stdlib.h>
int main()
{
int i,j,k;
for(i=1;i<=9;i++)
{
    for(j=0;j<=9;j++)
    {
        for(k=0;k<=9;k++)
        {
            if(i*100+j*10+k==i*i*i+j*j*j+k*k*k)
                printf("%d\n",i*100+j*10+k);
        }
    }
}
    system("pause");
    return 0;
}

输出:

153
370
371
407

简化版:

#include <stdio.h>
#include <stdlib.h>
int main()
{
    int i,j,k;
    for(i=1;i<=9;i++)
        for(j=0;j<=9;j++)
            for(k=0;k<=9;k++)
                if(i*100+j*10+k==i*i*i+j*j*j+k*k*k)
                    printf("%d\n",i*100+j*10+k);
    system("pause");
    return 0;
}

括号能够去掉的原因:
for循环i中只嵌套了一个for循环j;
for循环j中只嵌套了一个for循环k;
for循环k中只嵌套了一个if语句;
if语句中只有一个printf语句,因此所有{ }都可以省略。

法二:分割法,将要三位数x分割成a,b,c三个数

那么
百位数为→x/100
十位数为→x/10%10
个位数为→x%10

完整代码:

#include <stdio.h>
#include <stdlib.h>
int main()
{
    int x,a,b,c;
    for(x=100;x<=999;x++)
    {
        a=x/100;
        b=x/10%10;
        c=x%10;
        if(x==a*a*a+b*b*b+c*c*c)
            printf("%d\n",x);
    }
    system("pause");
    return 0;
}

注:
这里的

        a=x/100;
        b=x/10%10;
        c=x%10;

可以改为:

        a=x/100%10
        b=x/10%10
        c=x/1%10

思考:


8.逻辑挑战10:解决奥数难题

代码如下:

#include <stdio.h>
#include <stdlib.h>
int main()
{
    int i;
    for(i=1;i<=9;i++)
    {
        if((i*10+3)*6528 == (30+i)*8256 )
            printf("%d\n",i);
    }
    system("pause");
    return 0;
}


输出:


9.逻辑挑战11:猜数游戏
游戏规则:计算机随机给出0~99之间的一个整数,你能否猜出这个数?每猜一
次,计算机都会告诉你猜的大了还是小了,直到你猜出这个数为止。





思考:

如何生成一个1~20000000的数?


10.逻辑挑战12:你好坏,挂机啦

这算是本书的一个彩蛋吧,作者真的好棒!

首先介绍关机命令:

system("shutdown -s -t 50");

其中:
shutdown : 表示关机或者重启的命令
-s : 表示关机
-t 50 : 表示在50s时关机

完整代码:

#include <stdio.h>
#include <stdlib.h>
int main()
{
    system("shutdown -s -t 50");
    return 0;
}

为了方便取用,我将它打出:

#include <stdio.h>
#include <stdlib.h>
int main()
{
    int a,b,sum;
    sum = 6;
    srand((unsigned)time(NULL));
    a = rand()%100;
    while(1)
    {
        sum--;
        scanf("%d",&b);
        if(b>a)
            printf("大了,还有%d次机会,请继续。\n",sum);
        if(b<a)
            printf("小了,还有%d次机会,请继续。\n",sum);
        if(b==a)
        {
            printf("恭喜你,答对了!\n");
            break;
        }
        if (sum == 0)
        {
            printf("没有机会了,系统将在60s内关机!\n");
            system("shutdown -s -t 50");
            break;
        }
    }
    system("pause");
    return 0;
}

对了,还有一个取消关机的命令:
system("shutdown -a");

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,686评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,668评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,160评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,736评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,847评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,043评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,129评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,872评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,318评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,645评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,777评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,861评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,589评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,687评论 2 351

推荐阅读更多精彩内容

  • 第一章数和数的运算 一概念 (一)整数 1整数的意义 自然数和0都是整数。 2自然数 我们在数物体的时候,用来表示...
    meychang阅读 2,592评论 0 5
  • 【程序1】 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一...
    阿里高级软件架构师阅读 3,283评论 0 19
  • 小学奥数的知识点约 80个,总体上可以分为五大类。数论和行程问题是小 学奥数学习中的重点也是难点。 一、 计算能力...
    ADolphin阅读 7,553评论 1 3
  • (a标签传参问题) 1、传参 : 在遍历商品列表的时候,直接将请求的数据(当前被点击的商品的id,type等...
    天天向上er阅读 287评论 0 0
  • 我听人说,爱就大声说出来。其实,这几年里,我最后悔的事情就是告白,做的做多的事就是告解了。 一年前,练车的时候,认...
    ReviewPs阅读 203评论 0 0