c语言中scanf内部扫描赋值的机制。考验基本功的时候到啦!~~~~

helloDesword 2013-01-23 07:00:42
#include<stdio.h>
int main()
{
int a[20],i;
scanf("%d,%d",&i,&a[i]);
return 0;
}

我已经知道了程序出错在scanf处,然后发现原因可能是i的值在一个scanf里面不能及时传送到后面要输入进去的a的i里面然后会导致段异常之类的错误。。我个人的猜测是,输入完成后,scanf先扫描缓冲区的第一个数值,然后赋给i,接着扫描第二个数值,接着赋给a,那么此时的a应该是指定了哪个元素了的。现在假定i不大于20吧。
但是事实上这样的代码运行时程序会自动出错中断。
那么,scanf内部扫描赋值的真实过程是什么呢???
但是我现在不讨论其规范性,我就是想单纯的知道起内部的过程。谢谢各位啦!~~~~~~~
另外scanf中赋值顺序调换是不起作用的!
即:
#include<stdio.h>
int main()
{
int a[20],i;
scanf("%d,%d",&a[i],&i);
return 0;
}
...全文
359 13 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
helloDesword 2013-01-24
  • 打赏
  • 举报
回复
引用 8 楼 ForestDB 的回复:
scanf("%d,%d",&a[i],&i); 压参的时候压的是地址,即a[i]的地址,但很明显,由于i没有初始化,a[i]是个不确定的“对象”,压了个不知什么“东西”的地址。
很好。明白啦!~~~
helloDesword 2013-01-24
  • 打赏
  • 举报
回复
引用 10 楼 zhao4zhong1 的回复:
仅供参考C/C++ code?123456789101112131415161718192021222324252627282930#include <stdio.h>char s[]="123 ab 4";char *p;int v,n,k;void main() { p=s; while (1) { k=sscanf(p,"%d%n",&am……
抱歉不明白。。
helloDesword 2013-01-24
  • 打赏
  • 举报
回复
引用 7 楼 lin5161678 的回复:
引用 5 楼 ls1160 的回复:引用 3 楼 lin5161678 的回复:引用 2 楼 ls1160 的回复:引用 1 楼 lin5161678 的回复:1. 读取三个参数的数据 入栈 2. 根据格式控制字符串读取stdin的数据 按照指定格式写入后面的参数 在函数开始执行之前 函数调用的准备工作已经读取了i的值 这时候只能拿到垃圾值 即 a[垃圾值] ……
soga!~~明白了
赵4老师 2013-01-24
  • 打赏
  • 举报
回复
仅供参考
#include <stdio.h>
char s[]="123 ab 4";
char *p;
int v,n,k;
void main() {
    p=s;
    while (1) {
        k=sscanf(p,"%d%n",&v,&n);
        printf("k,v,n=%d,%d,%d\n",k,v,n);
        if (1==k) {
            p+=n;
        } else if (0==k) {
            printf("skip char[%c]\n",p[0]);
            p++;
        } else {//EOF==k
            break;
        }
    }
    printf("End.\n");
}
//k,v,n=1,123,3
//k,v,n=0,123,3
//skip char[ ]
//k,v,n=0,123,3
//skip char[a]
//k,v,n=0,123,3
//skip char[b]
//k,v,n=1,4,2
//k,v,n=-1,4,2
//End.
ForestDB 2013-01-24
  • 打赏
  • 举报
回复
简单说,函数执行之前,参数已经确定,不存在LZ假想的“动态”变化这么一说。
ForestDB 2013-01-24
  • 打赏
  • 举报
回复
scanf("%d,%d",&a[i],&i); 压参的时候压的是地址,即a[i]的地址,但很明显,由于i没有初始化,a[i]是个不确定的“对象”,压了个不知什么“东西”的地址。
lin5161678 2013-01-24
  • 打赏
  • 举报
回复
引用 5 楼 ls1160 的回复:
引用 3 楼 lin5161678 的回复:引用 2 楼 ls1160 的回复:引用 1 楼 lin5161678 的回复:1. 读取三个参数的数据 入栈 2. 根据格式控制字符串读取stdin的数据 按照指定格式写入后面的参数 在函数开始执行之前 函数调用的准备工作已经读取了i的值 这时候只能拿到垃圾值 即 a[垃圾值] 于是崩溃 你的指望scanf……
读取缓冲区的数据那是在 scanf函数执行过程中做的事情 scanf 开始执行之前 从内存中读取 i 的值 i是垃圾值 a[i]悲剧
helloDesword 2013-01-24
  • 打赏
  • 举报
回复
引用 4 楼 yadoufeng 的回复:
C/C++ code?12345678#include<stdio.h> int main() { int a[20],i; scanf("%d,%d",&i,&a[i]); //i 为初始化未知,导致a[i]越界引发段错误,//如果初始化i=0; 调用scanf函数时&a[0]的地址入栈,你修改i地址的值,怎么可能引起……
恩!你说的的确很对。但是没有提到我想要知道的scanf运行原理。
helloDesword 2013-01-24
  • 打赏
  • 举报
回复
引用 3 楼 lin5161678 的回复:
引用 2 楼 ls1160 的回复:引用 1 楼 lin5161678 的回复:1. 读取三个参数的数据 入栈 2. 根据格式控制字符串读取stdin的数据 按照指定格式写入后面的参数 在函数开始执行之前 函数调用的准备工作已经读取了i的值 这时候只能拿到垃圾值 即 a[垃圾值] 于是崩溃 你的指望scanf给i赋值 那个是函数执行完毕 至少是函数执行……
恩。你好。那么 scanf函数在开始之前读取的i和a【i】的地址的值, 还是读取在缓冲区中存放的用户输入的要赋给i和a【i】的值?
yadoufeng 2013-01-23
  • 打赏
  • 举报
回复


#include<stdio.h> 
int main() 
{       
 int a[20],i;    
  scanf("%d,%d",&i,&a[i]);   //i 为初始化未知,导致a[i]越界引发段错误,
//如果初始化i=0; 调用scanf函数时&a[0]的地址入栈,你修改i地址的值,怎么可能引起 保存在栈中的a[0]地址,所以,输入的第二个永远是修改的a[0]所在地址的值
  return 0; 
 } 

lin5161678 2013-01-23
  • 打赏
  • 举报
回复
引用 2 楼 ls1160 的回复:
引用 1 楼 lin5161678 的回复:1. 读取三个参数的数据 入栈 2. 根据格式控制字符串读取stdin的数据 按照指定格式写入后面的参数 在函数开始执行之前 函数调用的准备工作已经读取了i的值 这时候只能拿到垃圾值 即 a[垃圾值] 于是崩溃 你的指望scanf给i赋值 那个是函数执行完毕 至少是函数执行一半的时候才能发生的事情 额。函数……
函数执行过程中 不会去读取i的值 读取i的值这件事在函数开始执行之前的准备工作中已经完成了 a[垃圾值] 这个在函数开始执行之前就已经确定
helloDesword 2013-01-23
  • 打赏
  • 举报
回复
引用 1 楼 lin5161678 的回复:
1. 读取三个参数的数据 入栈 2. 根据格式控制字符串读取stdin的数据 按照指定格式写入后面的参数 在函数开始执行之前 函数调用的准备工作已经读取了i的值 这时候只能拿到垃圾值 即 a[垃圾值] 于是崩溃 你的指望scanf给i赋值 那个是函数执行完毕 至少是函数执行一半的时候才能发生的事情
额。函数执行完毕这个我理解了,就是得等执行完了,才能有i的值,才能代替a【垃圾值】中的垃圾值 但我有点点不明白至少函数执行到一半的时候这句话。 如果按照一般的函数执行的顺序来说,i的赋值,和a【i】的赋值是有先后的吧。那么按照我上面的方式,先给i赋值了,然后把垃圾值覆盖了,那么a【i】中就应该是自己想要的赋值的元素了吧。这种也属于函数执行到一般么?
lin5161678 2013-01-23
  • 打赏
  • 举报
回复
1. 读取三个参数的数据 入栈 2. 根据格式控制字符串读取stdin的数据 按照指定格式写入后面的参数 在函数开始执行之前 函数调用的准备工作已经读取了i的值 这时候只能拿到垃圾值 即 a[垃圾值] 于是崩溃 你的指望scanf给i赋值 那个是函数执行完毕 至少是函数执行一半的时候才能发生的事情

70,023

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧