鱼C论坛

 找回密码
 立即注册
楼主: 竹逸

[已解决]关于scanf函数,我这么理解对吗?

[复制链接]
发表于 2022-8-18 17:54:31 | 显示全部楼层
竹逸 发表于 2022-8-18 17:49
好,既然是以字符形式存在,那我连续输入的1234,就是一个个单独的字符‘1’‘2’‘3’‘4’是吗?为什 ...

什么?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-8-18 23:40:39 From FishC Mobile | 显示全部楼层
本帖最后由 竹逸 于 2022-8-18 23:54 编辑
人造人 发表于 2022-8-18 17:54
什么?


既然每按一次键都是以字符ASCII码值的形式存入在输入流中的,那当我按下数字键1时,就代表着输入流中有字符1对应的ASCII码(二进制存储,十进制是49),疑惑的是计算机从输入流中读取了这个字符1的ASCII码值49,当我们以%d类型输入时,它是如何把49给转换成 数字1 的?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-8-19 07:49:59 | 显示全部楼层
竹逸 发表于 2022-8-18 23:40
既然每按一次键都是以字符ASCII码值的形式存入在输入流中的,那当我按下数字键1时,就代表着输入流中有 ...

类似这样

  1. #include <stdio.h>

  2. int main(void) {
  3.     int result = 0;
  4.     while(1) {
  5.         int ch = getchar();
  6.         if(ch < '0' || ch > '9') {
  7.             ungetc(ch, stdin);
  8.             break;
  9.         }
  10.         result = result * 10 + (ch - '0');
  11.     }
  12.     printf("%d\n", result);
  13.     return 0;
  14. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-8-19 08:00:31 | 显示全部楼层
  1. #include <stdio.h>

  2. int atoi_(const char *str) {
  3.     int result = 0;
  4.     for(size_t i = 0; str[i]; ++i) {
  5.         if(str[i] < '0' || str[i] > '9') {
  6.             break;
  7.         }
  8.         result = result * 10 + (str[i] - '0');
  9.     }
  10.     return result;
  11. }

  12. int main(void) {
  13.     {
  14.         int result = 0;
  15.         while(1) {
  16.             int ch = getchar();
  17.             if(ch < '0' || ch > '9') {
  18.                 ungetc(ch, stdin);
  19.                 break;
  20.             }
  21.             result = result * 10 + (ch - '0');
  22.         }
  23.         printf("%d\n", result);
  24.     }
  25.     {
  26.         printf("%d\n", atoi_("123ab"));
  27.     }
  28.     return 0;
  29. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-8-19 08:59:36 From FishC Mobile | 显示全部楼层
人造人 发表于 2022-8-19 07:49
类似这样

原来是这样的

那这句result = result * 10 + (ch - '0'); 里的 result * 10 是不是没有发挥用处?直接 result = rch - '0' 这样不可以么?

我怀疑计算机内部是不是有一张字符常量表,定义了字符‘0’~‘9’的常量值是1~9,当我们输入这些数字字符时并设定为%d时,就直接用常量值替换,这样感觉就不用每按一个键都得计算一次?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-8-19 09:12:01 From FishC Mobile | 显示全部楼层
本帖最后由 竹逸 于 2022-8-19 09:27 编辑
人造人 发表于 2022-8-19 07:49
类似这样


既然是这样被转换成整形的,那如果我输入123呢,输入流中的字符1,字符2,字符3,被cpu读取转换成整形1,整形2,整形3后,计算机是又如何确定他们各自的权重的?

比如我输入的123要的是一百二十三这个整数,而不是1,2,3三个整数,计算机内部难道会记录我键下的次数?然后把这个次数值当成各数字的权,再 "按权相加"
组成用户完整的整形数据,或者就直接是左移操作?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-8-19 09:54:47 | 显示全部楼层
竹逸 发表于 2022-8-19 09:12
既然是这样被转换成整形的,那如果我输入123呢,输入流中的字符1,字符2,字符3,被cpu读取转换成整形1 ...

这个程序你运行过吗?
直接 result = rch - '0' 这样不可以么?
你试一试看可不可以

调试一下这行代码,弄清楚这行代码是如何把字符组装成数字的
result = result * 10 + (ch - '0');

  1. #include <stdio.h>

  2. int atoi_(const char *str) {
  3.     int result = 0;
  4.     for(size_t i = 0; str[i]; ++i) {
  5.         if(str[i] < '0' || str[i] > '9') {
  6.             break;
  7.         }
  8.         result = result * 10 + (str[i] - '0');
  9.     }
  10.     return result;
  11. }

  12. int main(void) {
  13.     {
  14.         int result = 0;
  15.         while(1) {
  16.             int ch = getchar();
  17.             if(ch < '0' || ch > '9') {
  18.                 ungetc(ch, stdin);
  19.                 break;
  20.             }
  21.             result = result * 10 + (ch - '0');
  22.         }
  23.         printf("%d\n", result);
  24.     }
  25.     {
  26.         printf("%d\n", atoi_("123ab"));
  27.     }
  28.     return 0;
  29. }
复制代码

评分

参与人数 1荣誉 +5 鱼币 +5 贡献 +3 收起 理由
竹逸 + 5 + 5 + 3

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-8-19 10:00:12 | 显示全部楼层
竹逸 发表于 2022-8-19 09:12
既然是这样被转换成整形的,那如果我输入123呢,输入流中的字符1,字符2,字符3,被cpu读取转换成整形1 ...

在二进制中,乘以2就是左移一位数字,对吗?
在十进制中,乘以10就是左移一位数字,对吗?
在十六进制中,乘以16就是左移一位数字,对吗?

所以这里为什么要乘以10呢?调试一下这行代码呀
反汇编看一下这行代码是怎么用cpu指令完成的
调试程序,看一看这行代码如何把数字一步一步的组装起来
result = result * 10 + (ch - '0');
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-8-19 11:48:03 | 显示全部楼层
人造人 发表于 2022-8-19 09:54
这个程序你运行过吗?
直接 result = rch - '0' 这样不可以么?
你试一试看可不可以

你这代码确实运行不了

比如:

for(size_t i = 0; str[i]; ++i)

红标的是什么数据类型?

还有,你的result初始化值是0,result * 10 + (str[i] - '0'); 这用0*10的意义在哪里?你这个result 变量应该是记录字符的个数吧?

还有你的 int main(void) {{  ,为啥main函数有两个左大括号?你这编译器真的行?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-8-19 12:13:55 | 显示全部楼层
本帖最后由 竹逸 于 2022-8-19 13:10 编辑
人造人 发表于 2022-8-19 09:54
这个程序你运行过吗?
直接 result = rch - '0' 这样不可以么?
你试一试看可不可以


你这代码我这样改行不行,我还没学到数组哪里,还不清楚声明一个数组的方式对不对

  1. #include<stdio.h>
  2. #include<math.h>

  3. int main(void)
  4. {
  5.         int result = 0, sum = 0, i = 0;
  6.         char str[3];
  7.         char temp;
  8.        
  9.         while((temp = getchar()) != '\n')
  10.         {
  11.                 str[result++] = temp;
  12.         }

  13.        
  14.         for(; i<result; i++)
  15.         {
  16.                 sum += pow(10,--result) * (str[i] - '0');
  17.     }
  18.     printf("%d", sum);
  19.    
  20.     return 0;
  21. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-8-19 12:21:19 | 显示全部楼层
竹逸 发表于 2022-8-19 11:48
你这代码确实运行不了

比如:

换新版本的编译器
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-8-19 12:21:51 | 显示全部楼层
竹逸 发表于 2022-8-19 12:13
你这代码我这样改行不行,我还没学到数组哪里,还不清楚声明一个数组的方式对不对

不对
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-8-19 12:29:54 | 显示全部楼层
竹逸 发表于 2022-8-19 12:24
我重新改了下,思路应该就是这样的,不知道怎么声明一个动态的数组,就是不确定数组元素的个数。

不对,C语言中的 ^ 是什么?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-8-19 12:31:03 | 显示全部楼层
本帖最后由 竹逸 于 2022-8-19 13:11 编辑
人造人 发表于 2022-8-19 12:29
不对,C语言中的 ^ 是什么?


我忘记用pow()函数了,是求平方的,重新改下
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-8-19 12:38:14 | 显示全部楼层
1.png
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-8-19 12:42:24 | 显示全部楼层
  1. #include <stdio.h>
  2. #include <math.h>

  3. int main(void) {
  4.     int result = 0, sum = 0;
  5.     char str[3]; //比如我输入123,按了3次键
  6.     char temp;

  7.     while((temp = getchar()) != '\n') {
  8.         // str[++result] = temp; ???
  9.         str[result++] = temp;
  10.     }

  11.     for(int i = 0; i < result; i++) {
  12.         // sum += pow(10,--result) * (str[i] - '0');
  13.         sum += pow(10, result - i - 1) * (str[i] - '0');
  14.     }
  15.     // printf("%d", sum); // 为什么就是不愿意换上一行?
  16.     printf("%d\n", sum);

  17.     return 0;
  18. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-8-19 12:43:44 | 显示全部楼层
竹逸 发表于 2022-8-19 12:24
我重新改了下,思路应该就是这样的,不知道怎么声明一个动态的数组,就是不确定数组元素的个数。

不知道怎么声明一个动态的数组,就是不确定数组元素的个数
这个教程中有讲过的
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-8-19 12:56:14 | 显示全部楼层
本帖最后由 竹逸 于 2022-8-19 12:57 编辑


我再重新修改下
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-8-19 13:04:57 | 显示全部楼层
本帖最后由 竹逸 于 2022-8-19 13:21 编辑
人造人 发表于 2022-8-19 12:43
不知道怎么声明一个动态的数组,就是不确定数组元素的个数
这个教程中有讲过的


现在绝对没问题了,你运行一下试试,只能输入3个数字,旧版本的课件关于数组和字符串的那节课还没学过

  1. #include<stdio.h>
  2. #include<math.h>

  3. void main()
  4. {
  5.         int result = 0, sum = 0, i = 0, j;
  6.         char str[3];                  //输入3个数字后回车
  7.         char temp;
  8.        
  9.         while((temp = getchar()) != '\n')
  10.         {
  11.                 str[result++] = temp;   
  12.         }

  13.         j = result;

  14.         for(; i<j; i++, result--)
  15.         {
  16.                 sum += pow(10,result-1) * (str[i] - '0');
  17.     }
  18.     printf("%d\n", sum);
  19. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-8-19 13:31:01 | 显示全部楼层
竹逸 发表于 2022-8-19 13:04
现在绝对没问题了,你运行一下试试,只能输入3个数字,旧版本的课件关于数组和字符串的那节课还没学过
...

没问题了
但是这一行代码多好
result = result * 10 + (ch - '0');
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-4-23 21:10

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表