回文数|逻辑非” 运算符|函数封装

回文数Palindrome number

这绝对是我目前写过最久的程序!

题目:

回文数的形成。任取一个十进制整数,将其倒过来后与原来的整数相加,得到一个新的整数后,重复以上步骤,最终可得到一个回文数,请编程验证。
**输入格式要求:”%ld” 提示信息:”please enter a number optionaly:” “The generation process of palindrome:\n” “ input error, break.\n”
**输出格式要求:” [%d]: %ld+%ld=%ld\n” “Here we reached the aim at last !\n”
程序运行示例如下:
please enter a number optionaly:345
The generation process of palindrome:

Here we reached the aim at last !

代码实现:

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
#include <stdio.h>

int main()
{
long number, reversenumber = 0, last, newnumber, initial;
int count = 1;
printf("please enter a number optionaly:");
scanf_s("%ld", &number);
printf("The generation process of palindrome:\n");
initial = number;
while (10086) {
while (number != 0) {
last = number % 10;
number = number / 10;
reversenumber = reversenumber * 10 + last;
}
newnumber = initial + reversenumber;
if (initial == reversenumber) {
break;
}
printf(" [%d]: %ld+%ld=%ld\n", count, initial, reversenumber, newnumber);
number = newnumber;
initial = number;
reversenumber = 0;
last = 0;
count++;
}
printf("Here we reached the aim at last !\n");

return 0;
}

中途遇到的问题:

  • %ld是什么?

    ​ 全称是 “long decimal”,用于**整数类型 long**(长整型)的输入输出。

  • intlong有什么区别?

    • **int**:

      通常占 4 字节(32 位),可表示的范围约为 -21 亿~+21 亿(-2³¹ ~ 2³¹-1)。

      例如:int 最大能精确存储 2147483647,超过这个数就会 “溢出”(结果错误)。

    • **long**:

      至少占 4 字节(32 位系统),64 位系统中通常占 8 字节,可表示的范围约为 -922 亿亿~+922 亿亿(-2⁶³ ~ 2⁶³-1)。

      例如:8 字节的 long 能轻松存储像 123456789012345 这样的大整数,而 int 会溢出。

    • 内存占用不同

      int:固定 4 字节(几乎所有系统)。

      long:32 位系统中 4 字节,64 位系统中 8 字节(目的是利用更大的内存空间扩展表示范围)。

    • 什么时候用 int?什么时候用 long

      ​ 用 int:处理普通大小的整数(比如年龄、数量、10 亿以内的数),更节省内存,效率略高。

      ​ 用 long:处理超过 int 范围的大整数(比如身份证号、天文数字、大金额),避免溢出错误。

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

      int main() {
      int a = 2147483647; // int 的最大值
      long b = 2147483648; // 超过 int 范围,必须用 long

      printf("int 最大值+1: %d\n", a + 1); // 溢出,结果错误(变成-2147483648)
      printf("long 存储大整数: %ld\n", b); // 正确输出 2147483648

      return 0;
      }

      简单说:int 是 “普通整数”,long 是 “大整数”,根据需要存储的数值大小选择即可。

最后写的我头皮发麻,浑身燥热,饥渴难耐…….不过还好,自己还是把这个几把代码写出来了

看看AI是怎么写的把!

AI的代码:

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include <stdio.h>

// 函数声明
long reverse_num(long num);
int is_palindrome(long num);

int main() {
long num, original, reversed, sum;
int step = 0;

// 提示用户输入数字
printf("please enter a number optionaly:");
scanf_s("%ld", &num);

// 输出回文数生成过程标题
printf("The generation process of palindrome:\n");

original = num;

// 循环直到得到回文数
while (!is_palindrome(original)) {
step++;
reversed = reverse_num(original);
sum = original + reversed;
printf(" [%d]: %ld+%ld=%ld\n", step, original, reversed, sum);
original = sum;
}

// 如果初始数就是回文数,需要显示第一步
if (step == 0) {
step++;
reversed = reverse_num(original);
sum = original + reversed;
printf(" [%d]: %ld+%ld=%ld\n", step, original, reversed, sum);
}

// 输出最终结果
printf("Here we reached the aim at last !\n");

return 0;
}

// 函数:将数字反转
long reverse_num(long num) {
long reversed = 0;
while (num != 0) {
reversed = reversed * 10 + num % 10;
num /= 10;
}
return reversed;
}

// 函数:判断是否为回文数
int is_palindrome(long num) {
return num == reverse_num(num);
}

解读:

  1. 将反转数字和判断回文数封装到两个函数中,使代码可读性强
  2. 封装到两个独立函数,避免循环嵌套的时候出现变量需不断重新归零,或避免在主函数中定义过多变量,降低大妈可读性

看看是怎么实现的把:

反转数字:

1
2
3
4
5
6
7
8
9
10
11
long reverse_num(long num);				 // 函数声明

// 函数的定义:将数字反转 //定义reverse_num()函数
long reverse_num(long num) {
long reversed = 0;
while (num != 0) {
reversed = reversed * 10 + num % 10;
num /= 10;
}
return reversed;
}
  • 这个里面的的reversed不是在主函数中已经定义了吗,还需要定义?

    在 C 语言中,变量的作用域(即变量能被访问的范围)是由定义它的位置决定的。 reversed 变量在 主函数(mainreverse_num 函数 中是完全独立的两个变量,原因如下:

    1. 变量的 “作用域” 不同
    • reverse_num 函数中定义的 long reversed = 0;,其作用域 仅限于 reverse_num 函数内部。离开这个函数后,这个变量就不存在了,其他函数(包括 main 函数)无法直接访问它。
    • 主函数(main)中如果定义了 reversed 变量(比如你可能在 main 里写了 long reversed;),它的作用域 仅限于 main 函数内部reverse_num 函数无法访问 main 中的这个变量。
    1. 为什么需要在 reverse_num 中重新定义?
    • reverse_num 函数的功能是 “计算一个数字的反转数”,这个过程需要一个临时变量来存储反转后的结果(比如从 0 开始,逐步拼接原数字的每一位)。这个临时变量只在函数内部使用,和 main 函数中可能存在的 reversed 变量没有任何关系。

    即使两个变量名字相同,由于作用域不同,它们会被编译器视为 两个完全独立的变量(可以理解为 “同名不同人”),各自占用不同的内存空间,互不影响。

  • num /= 10是什么意思?

    num /= 10 等价于 num = num / 10

  • reversed = reversed * 10 + num % 10中将”取最后一位数字”整合到递推中,使代码更简洁

  • 函数独立封装的好处

    • 避免循环嵌套,导致reverse_num在上一次循环中的值,运用在了下一次循环reversed = reversed * 10 + num % 10的第二个reverse中(每一次循环reverse的初始值都要为0),当然实现方法就是在每一个循环的开头重新定义reverse的初始值‘0’

判断是否为回文数:

1
2
3
4
5
6
7
8
9
10
11
12
int is_palindrome(long num);				// 函数声明

// 函数:判断是否为回文数
int is_palindrome(long num) {
return num == reverse_num(num);
}

//函数的调用
while (!is_palindrome(original)){


}
  • return num == reverse_num(num) 是什么意思?

    这行代码的作用是判断一个数是否为回文数,并返回判断结果。

    • == 是 “等于” 运算符,用于比较左右两边的值是否相等,相等则返回 1(真),不相等则返回 0(假)。
    • reverse_num(num) 会计算 num 的反转数(例如 num=345 时,反转数是 543)。

    因此:

    • 如果 num 和它的反转数相等(比如 num=888,反转数也是 888),则 num == reverse_num(num)1,函数返回 1(表示是回文数)。
    • 如果不相等(比如 num=345,反转数是 543),则返回 0(表示不是回文数)。
  • 这里的!is_palindrome(original)的感叹号!是什么意思?

    由于这里循环继续进行的条件是original不是回文数,而is_palindrome(original)判断不是回文数会返回0从而终止循环

    所以这里需要反转一下:

    感叹号 ! 是 “逻辑非” 运算符,作用是取相反的布尔值(真变假,假变真)。

    is_palindrome(original) 的返回值是:

    • 如果 original 是回文数,返回 1(真);
    • 如果不是回文数,返回 0(假)。

    因此 !is_palindrome(original) 的意思是:

    • original 不是 回文数时,条件为 (1),循环继续执行(继续相加反转数);
    • original 回文数时,条件为 (0),循环停止。
  • 简单明了地呈现循环条件,避免使用if中的条件判断和break使代码更复杂,同时也避免了非要使用if来打破循环时if语句不知道放哪的烧脑与尴尬

单独列出特殊情况

1
2
3
4
5
6
7
8
9
10
11
12
13
14
   //如果初始值original通过函数is_palindrome()判断是回文数并返回1
//经过!反转布尔值后为假,则无法进入while循环并打印[%d]: %ld+%ld=%ld\n
//从而无法达到题目要求,又无法改变‘!‘语法,所以要单独说明
while (!is_palindrome(original)) {

}


if (step == 0) {
step++; //step = 2
reversed = reverse_num(original);
sum = original + reversed;
printf(" [%d]: %ld+%ld=%ld\n", step, original, reversed, sum);
}

回文数|逻辑非” 运算符|函数封装
http://example.com/2025/11/17/回文数、逻辑非” 运算符、函数封装/
作者
王柏森
发布于
2025年11月17日
许可协议