原文链接

质数概念

只能被 1 和自身整除的对于 1 正整数。

2, 3, 5, 7, ...

指针声明和初始化

unsigned long long *pPrimes = NULL;

NULL 对指针而言相当于 0 值,在声明指针的时候最好将其初始化为 NULL 防止其乱指,在后面使用过程中

造成内存覆盖等问题。

声明需要的变量:

// 用来存储所有的质数

unsigned long long *pPrimes = NULL;

unsigned long long trial = 0;

_Bool found = false;

int total = 0; // 需要输出的总质数个数

int count = 0; // 用来计数

pPrimes 指针用来存放动态分配的内存首地址。

trial 用来获得当前将要被处理的可能是质数的数。

total 用户需要展示的质数的个数,由用户输入。

count 循环的计数。

动态分配内存(malloc() 或 calloc())

malloc() 和 calloc() 区别在于 calloc() 有两大有点:

将内存分配为给定大小的数组;

会将所有分配的内存初始化为 0 。

因此尽量使用 calloc 去动态分配内存。

这里我们固定内存的容量大小为: size_t capacity = 10; 使用 size_t 是因为

calloc() 或 malloc() 的第二个参数类型为 size_t 类型。

printf("请问想要输出多少个质数(至少4个) ? ");

scanf("%d", &total);

// 根据输入个数分配空间

// 固定初次分配的内存量

size_t capacity = 10;

pPrimes = (unsigned long long *)calloc(capacity, sizeof(unsigned long long));

if (!pPrimes) {

printf("内存分配失败。");

return 1;

}

记得分配完内存在使用之前,一定要做非空判断,判断是否分配成功,只有成功了才能继续往下,否则可能会造成未知的严重后果。

获取已知的质数

根据质数的特性,我们先声明几个已知的质数(2, 3, 5),然后根据这些已知的质数,去被将来的质数整除,只要能整除,说明

它不是质数。

// 直接找出前 3 个质数 (2, 3, 5)

*pPrimes = 2ULL;

*(pPrimes + 1) = 3ULL;

*(pPrimes + 2) = 5ULL;

count = 3;

trial = 5ULL;

通过下面的循环去找出下一个质数:

unsigned long long *pTemp = NULL;

while (count < total) {

trial += 2ULL; // 直接跳过偶数

// 计算是否能被现有的质数整除,如果能表示非质数

// 这里使用 i = 1 是因为 任何奇数都无法被2整除,

// 因此没必要对 2 进行判断

for (int i = 1; i < count; i++) {

if (!(found = (trial % *(pPrimes + i))))

break;

}

if (found) {

*(pPrimes + count++) = trial;

}

}

trail += 2ULL; 这里使用了个技巧,因为我们知道除了 2 意外的偶数(>0)都不会是质数,因此偶数就没必要

去做多余的判断了。

经过上面的 while 循环我们将找到下一个质数:

*(pPrimes + count++) = trial;

并将它放到最后一个质数的后面通过 *(pPrimes + count++) ,因为指针的 +1 是根据其指针存放的数据类型

的大小递增的,因此可以直接通过指针 +count 来找到要存放当前质数的地址。

但前提是最后一个质数空间后面有更多的空间去容纳它,那么这个时候就需要考虑去动态分配更多的空间了,

因为我们最初只固定分配了 CAP_INCR 个内存空间。

再分配内存(realloc())

realloc() 会在 malloc() 或 calloc() 基础之上分配更多的内存空间,并且会将旧的内存拷贝到新的内存中。

比如:

malloc() 了 5 个内存空间:

1

2

3

4

5

然后通过 realloc() 分配 10 个内存空间:

0

0

0

0

0

0

0

0

0

0

然后会把 malloc() 分配的内存里的内容拷贝到新的里面成为:

1

2

3

4

5

0

0

0

0

0

// 是否找到 ??

if (found) {

// 找到之后得先判断内存是否够用,不够用需要再分配

if (count == capacity) {

capacity += CAP_INCR;

pTemp = realloc(pPrimes, capacity * sizeof(unsigned long long));

if (!pTemp) {

printf("realloc failed.\n");

free(pPrimes);

pPrimes = NULL;

return 2;

}

pPrimes = pTemp;

}

// 将找到的质数保存起来

*(pPrimes + count++) = trial;

}

上面声明了一个新的指针 pTemp 用来指向再分配的内存空间,但是会发现我们后面并没有去针对这个指针去做释放操作,

这是因为我们后面将 pPrimes 指向了 pTemp ,而我们也在后面对 pPrimes 进行了释放。

即如果两个指针同时指向一个内存空间的话,只需要释放一个就可以了,如果两个都去调用 free() 进行释放,

其实就是意味着对同一块内存进行两次释放,这个也可能会造成不可预知的问题,因此切记不要对同一块内存进行两次甚至

更多次的释放操作。

输出结果并释放内存,置空指针

// 输出得到的质数

for (int i = 0; i < total; i++) {

printf("%12llu", *(pPrimes + i));

if (!((i + 1) % 5)) { // 被 5 整除换行,一行显示5个

printf("\n");

}

}

printf("\n");

// 释放内存

free(pPrimes);

// 置空指针

pPrimes = NULL;

分配内存之后,不用的时候不单单要调用 free() 去释放,释放之后,这个指针也需要置空处理,防止乱指。

完整代码

总结

该实例完成,主要是认识 malloc(), calloc() 和 realloc() 动态分配内存以及内存释放函数的使用,及其相关的一些知识和注意点和质数的概念。

c语言打印%-6llu,C语言-输出指定个数的质数相关推荐

  1. STM32F407-高级定时器输出指定个数PWM功能

    高级定时器输出指定个数PWM只需要设置好重复计数器寄存器RCR的值并打开更新中断即可. 一般情况下的更新中断是在CNT计数到ARR的时候产生,而在设置了RCR后,更新中断将会延迟,比如设置RCR的值为 ...

  2. c语言输出指定个数的字符,读取指定个数的字符,依照要求输出。当指定数目≥32时,出错...

    读取指定个数的字符,按照要求输出.当指定数目≥32时,出错. 代码如下: /************************************************************** ...

  3. 【Java学习笔记】接收命令行参数输出指定个数的斐波那契数列

    /*斐波那契数列使用命令行输入参数 */ public class Fibonacci {public static void main(String[] args){if (args.length ...

  4. c语言打印%-6llu,从零开始学C语言

    从零开始学C语言 @阆苑祁寒 写在前面:本文从一个初学者的角度,给出了对C语言的简单理解.如有谬误,敬请指出! Week1 1 #include 2 int main(void)3 {4 printf ...

  5. go语言打印日期_go语言基础:流程控制(4)-多重循环跳转控制

    1.6 多重循环控制 1.6.1 概念解析 1)多重循环就是指将一个循环嵌套在另一个循环体内,就形成了嵌套循环.在外边的for循环称之为外层for循环,在里面的for循环称之为内层for循环.2)实质 ...

  6. java语言打印图形_JAVA语言入门教程之打印图形实例——打印矩形

    本文主要向大家介绍了JAVA语言入门教程之打印图形实例--打印矩形,通过具体的内容向大家展示,希望对大家学习JAVA语言有所帮助. 输出矩形: public class Rect { public s ...

  7. C语言-输入一个正整数,输出它的所有质数因子

    质因子一定是质数上的数,质数例如:2,3,5,7,11,13,17,19~等等只有1和它本身一对因子的数,求一个数的质因子数等价于求该数能整模质数范围[2,n]里的几个数 例如:求100的质因子,那么 ...

  8. 《c语言入门题目19》判断一个数是不是质数(素数)

     前言:(内容仅供分享和参考): 什么是质数: 质数又称素数.一个大于1的自然数,除了1和它自身外,不能被其他自然数整除的数叫做质数:否则称为合数(规定1既不是质数也不是合数).=========== ...

  9. 输出指定个数所有枚举_【一天一大 lee】区间和的个数 (难度:困难) Day20201107

    20201107 题目: 给定一个整数数组 nums,返回区间和在 [lower, upper] 之间的个数,包含 lower 和 upper.区间和 S(i, j) 表示在 nums 中,位置从 i ...

  10. C语言编程实例—输出指定图形

    用C语言打印指定图形时,主要就是根据i(行号)  来确定每一行输出的数据 输入一个数字  就可以根据这个数字输出指定的图形,此算法也可以针对其他情况,比如输出星型. 本案例分两部分:接下来找规律 第一 ...

最新文章

  1. 数据结构-王道2017-第3章 栈和队列-队列
  2. 语音识别:从GMM-HMM到端到端
  3. Html----编写
  4. TX2下编译qt程序步骤
  5. [FW]软件开发中的11个系统思维定律
  6. 应用软件暗藏猫腻,信息安全咋保障
  7. (转)XP和Scrum到底有什么区别?
  8. verilog 按键消抖
  9. C语言的进制转换以及算法实现
  10. Python绘制漫天的雪花,漫步天涯
  11. “那不勒斯”服务器芯片,那不勒斯定名 AMD发布全新CPU品牌EPYC
  12. 华为中兴为何对未来信心十足?
  13. 弘辽科技:拼多多转化率怎么看?4个步骤教会你
  14. python和c语言哪个效率高_Python运行效率优于C语言的功能简介
  15. 日语在线翻译excite网页版
  16. Petya勒索病毒爆发,腾讯安全反病毒实验室首发技术分析
  17. 编译osgEarth2.8遇到gdal_vrt.h找不到的问题
  18. 字符串匹配KMP算法的理解(详细)
  19. 收藏!50个帮你提升自我的网站
  20. AOP-面向切面编程

热门文章

  1. 分层图最短路【bzoj2763】: [JLOI2011]飞行路线
  2. 向上转型---父类引用指向子类对象 A a = New B()的使用
  3. [Java] Lambda表达式
  4. 基于Ubuntu的ESP32平台搭建
  5. SSH登录到远程linux机器并执行命令
  6. 练习: 将一个int[] 中元素,转成字符串格式
  7. SqlServer 存贮过程操作类
  8. Microsoft Windows Sharepoint Services V3.0 安装图示
  9. 不同数据量下主键类型的选择
  10. Java面试题视频讲解汇总,持续更新中...