【C语言】无符号unsigned
无符号unsigned这是一个非常好的问题。很多初学者(甚至有经验的程序员)容易陷入一个误区:“既然这个变量(比如年龄、身高、人数)不可能是负数,那我就应该用unsigned。”这个直觉通常是错的 。Google 的 C++ 编码规范甚至明确建议:除非万不得已,尽量使用有符号类型(int)。那么,到底什么时候必须 或推荐 使用 unsigned 呢?主要有以下三种场景: 1. 进行位操作 (Bitwise Operations) —— 最核心场景这是使用 unsigned 最正当、最无可争议的理由。 如果你要把一个变量当作**“一串二进制位”** (而不是一个数字)来处理,比如进行移位操作(>>, <<)、按位与/或/异或,请务必使用 unsigned。 原因: 有符号数(signed)的最高位是符号位 。当你对有符号数进行右移 操作时,不同的编译器处理方式不同(有的补0,有的补1),结果是未定义的或不可移植的。而无符号数的行为是确定的(总是补0)。 IoT 场景: 你是物联网专业的,将来写嵌入式代码(比如控制寄存器、设置GPIO引...
【C语言】神奇的递归、return、和主函数的定义
C语言学习笔记:利用递归实现字符串倒序输出 作者:王星皓 1. 题目要求编写一个C语言程序,利用递归函数将输入的字符串倒序输出。 输入提示:input your string:\n 输入格式:%s 输出格式:%c 2. 方法一:使用指针实现 (Pointer Approach)这是C语言中最常用的递归处理字符串的方法。利用指针算术运算 s+1 逐步向后移动,直到遇到结束符 \0。 123456789101112131415161718#include <stdio.h>void reverse_print(char *s) { if (*s == '\0') { return; // 基准情况:遇到结束符停止 } else { reverse_print(s + 1); // 递:移动指针到下一个字符 printf("%c", *s); // 归:打印当前字符 }}int main() {...
【C语言】输入与字符串
输入与字符串一、getchar和scanf1. getchar() 的行为它是最原始的字符读取函数。它的逻辑是:输入缓冲区里有什么,我就拿什么,绝不挑食。 2. scanf() 的行为scanf 通常比较“聪明”,比如 %d 或 %s 会自动跳过空格、回车和制表符。一旦遇到这些空白字符,它就会立刻停止读取 , 但是! %c 是个特例。当使用 %c 时,它的行为和 getchar() 几乎一模一样:不跳过任何空白字符 。 二、gets 、 fgets 和 gets_s1. gets() —— 亡命徒 (The Outlaw) 状态 :极度危险 ,已被废弃(C11 标准已将其从库中移除)。 安全性 :0 分 。 它不接受数组大小作为参数。 原理 :你给它一个 10 字节的杯子,如果用户倒入 100 升水,它会照单全收,溢出的水会覆盖掉杯子后面的内存(造成缓冲区溢出攻击)。 回车处理 :“吃掉”回车 。 读取到 \n 为止,然后把 \n 扔掉,换成 \0。 内存样子:输入 abc + 回车[‘a’, ‘b’, ‘c’, ‘\0’] 2. fgets() —— 严谨的守卫...
【C语言】scanf循环读取一次输入
scanf循环读取一次输入背景有n个整数,使其前面各数顺序向后移m个位置,最后m个数变成最前面m个数。输入提示:”共有多少个数?”输入格式:”%d”输入提示:”后移多少个?”输入格式:”%d”输出提示:”请以,号为间隔输入%d个数。\n”输出格式:”%d,”输出提示:”移动后顺序为:\n”输出格式:”%d,”程序的运行示例如下:共有多少个数?5后移多少个?2请以,号为间隔输入5个数。1,2,3,4,5移动后顺序为:4,5,1,2,3 代码实现:12345678910111213141516171819202122232425262728293031323334353637383940414243#define _CRT_SECURE_NO_WARNINGS#include <stdio.h>#define MAX 1000void move(int*, int, int);int main(void){ int a[MAX], n, m; char sep; printf("共有多少个数?"); scanf(&qu...
【C语言】二分法查找下标
二分法查找下标题目:折半查找算法,当找到输入元素后显示其在数组中的下标 代码实现:1234567891011121314151617181920212223242526272829303132333435363738394041424344#include <stdio.h>int main(){ // 修正1:up设为9(数组最大下标),low设为0(数组最小下标),初始化found为0 int up = 9, low = 0, mid, found = 0, find; int a[10] = { 1, 5, 6, 9, 11, 17, 25, 34, 38, 41 }; printf("请输入要查找的数字: "); // 修正2:scanf添加取地址符 & scanf("%d", &find); printf("\n"); // 修正3:循环条件改为逻辑与 &&,且使用 standard 的 l...
【C语言】循环中变量的作用域
循环中变量的作用域背景:输入某班学生某门课的成绩(最多不超过40人),当输入为负值时,表示输入结束,用函数编程统计成绩不低于平均分的学生人数。要求:(1)按如下函数原型进行编程:int GetAboveAver(int score[], int n);(2)在主函数中:输入学生成绩,然后调用函数GetAboveAver计算成绩不低于平均分的学生人数,最后输出该人数。要求:(1)学生成绩和平均分均定义为int类型(2)**无输入提示信息**输入格式为:”%d”**输出格式为:”Students of above average is %d\n”程序运行示例:88 75 86 67 59 66 -1↙Students of above average is 3 代码实现:1234567891011121314151617181920212223242526272829303132#define _CRT_SECURE_NO_WARNINGS#include <stdio.h>#define MAX 40int calculate(int*,int);int main()&...
【C语言】疑难解答(1)
疑难解答(1)学了一段时间的C语言,我向哈基米问了几个问题 Q:我现在正在使用visual studio 2026,为什么我使用scanf的时候会显示scanf不安全?A:Visual Studio 给你的报错通常是 C4996,这并不是说 scanf 这个函数坏了,而是因为它有一个先天缺陷 :不检查边界 。 1. 缓冲区溢出(Buffer Overflow)想象一下,你申请了一个只能装 5 个字符的数组 char a[5],但是你在 scanf("%s", a) 的时候,用户如果不听话,输入了 100 个字符。 scanf 也是个“老实人”,用户给多少它就往内存里塞多少。 结果 :多出来的字符会溢出,覆盖掉数组后面原本不属于它的内存区域。这可能导致程序崩溃,甚至被黑客利用(这就是著名的“缓冲区溢出攻击”)。 2. 微软的解决方案微软为了安全,推出了 scanf_s 等一系列带 _s (Secure) 后缀的函数。它们要求你明确告诉它“这块内存有多大”,如果输入超过这个大小,函数就会报错而不是让程序崩溃。 Q:为什么 12#define _CRT_SE...
【C语言】运算符优先级和数组定义
运算符优先级和数组定义背景按照筛法求素数的思想求出100以内的所有素数。每行10个。**输出格式要求:”%5d”用筛法求素数的基本思想是:把从2到N的一组正整数从小到大按顺序排列。从中依次删除2的倍数、3的倍数、5的倍数,直到根号N的倍数为止,剩余的即为2~N之间的所有素数。如有: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去掉2的倍数(不包括2),余下的数是:3 5 7 9 11 13 15 17 19 21 23 25 27 29剩下的数中3最小,去掉3的倍数,如此下去直到sqrt(30)的倍数,最后求出的素数为:2 3 5 7 11 13 17 19 23 29 代码实现123456789101112131415161718192021222324252627282930#include <stdio.h>#include <math.h>#define n 100int main(){ //const int n=100; in...
【C语言】吃掉缓冲区
吃掉缓冲区背景:对输入的一个数判断是否是素数。所谓素数是指这个数只能被1和自身整除。要求在主函数输入一个数,调用函数Fun()判断该数是否是素数。打印信息在主函数中进行。例如:从键盘输入5,5是素数则打印如下信息:”5 is a prime number”。又如:从键盘输入4, 4不是素数则打印如下信息:”4 is not a prime number”。负数、0和1均不是素数。对输入的数据要考虑数据的合法性,不满足条件的数要重新输入直到满足条件为止。不能使用全局变量,不按给定的函数原型编写程序不给分。Fun()函数原型为: int Fun(int m);**输入数据提示信息:”Please input a number:\n”注:该提示信息请放在循环体外**输入数据格式为:”%d”**输出格式要求:若是素数输出数据格式为:”%d is a prime number\n”若不是素数输出数据格式为: “%d is not a prime number\n”程序运行示例1;Please input a number:1111 is a prime number程序运行示例2:Plea...
【C语言】void的含义
void的含义背景写一个函数,如果它首次被调用,则返回字母A,第二次被调用,则返回字母B,第三次调用,则返回字母C,以此类推。(提示:使用一个static数据类型)函数原型为:char call_times(void)。编写main函数测试它。**输出格式要求:”第一次调用返回字符%c!\n” “第二次调用返回字符%c!\n” “第三次调用返回字符%c!\n” 代码实现:123456789101112131415#include <stdio.h>char call_times(void);int main(){ printf("第一次调用返回字符%c!\n",call_times()); printf("第二次调用返回字符%c!\n",call_times()); printf("第三次调用返回字符%c!\n",call_times()); return 0;}char call_times(void){ static char ch='A'; return...


