请教一个C问题,关于scanf,strlen,数组和指针的问题。请向下看。。。
类似代码,四种结果。
#include "stdio.h"#include "stdlib.h"#include "string.h"int main(){ char str[1]; char n; printf("Please input a string!"); scanf("%s",&str); n=strlen(str); printf("str=%s\n",str); printf("str=%s\n",&str); printf("str[0]=%s\n",&str[0]); printf("str[0]=%c\n",str[0]); printf("str[0]=%s\n",&str[0]); printf("str[1]=%c\n",str[1]); printf("sizeof=%d\n",sizeof(str)); printf("strlen=%d\n",n); exit(0);}#include "stdio.h"#include "stdlib.h"#include "string.h"int main(){ char str[1]; char n; printf("Please input a string!"); scanf("%s",&str); //n=strlen(str);//注释掉 printf("str=%s\n",str); printf("str=%s\n",&str); printf("str[0]=%s\n",&str[0]); printf("str[0]=%c\n",str[0]); printf("str[0]=%s\n",&str[0]); printf("str[1]=%c\n",str[1]); printf("sizeof=%d\n",sizeof(str)); printf("strlen=%d\n",n); exit(0);}#include "stdio.h"#include "stdlib.h"#include "string.h"int main(){ char str[1]; int n;//此时n改为INT ; printf("Please input a string!"); scanf("%s",&str); n=strlen(str); printf("str=%s\n",str); printf("str=%s\n",&str); printf("str[0]=%s\n",&str[0]); printf("str[0]=%c\n",str[0]); printf("str[0]=%s\n",&str[0]); printf("str[1]=%c\n",str[1]); printf("sizeof=%d\n",sizeof(str)); printf("strlen=%d\n",n); exit(0);}#include "stdio.h"#include "stdlib.h"#include "string.h"int main(){ char str[1]; int n;//此时n改为INT ; printf("Please input a string!"); scanf("%s",&str); //n=strlen(str); printf("str=%s\n",str); printf("str=%s\n",&str); printf("str[0]=%s\n",&str[0]); printf("str[0]=%c\n",str[0]); printf("str[0]=%s\n",&str[0]); printf("str[1]=%c\n",str[1]); printf("sizeof=%d\n",sizeof(str)); printf("strlen=%d\n",n); exit(0);}
str[0]=123456789
str[1]=2
sizeof=1
strlen=892613426
我想知道strlen()在这些函数中到底起到了什么作用,为什么影响这么大?
PS:我分不多。。。。
[解决办法]
我也得学学C,高层语言用惯了~~
[解决办法]
首先,要问错误代码会什么会得到某个结果,去看编译原理和编译后的汇编代码
然后,这些代码的问题其实就出在一个地方:str数组越界因而修改了n的内存
局部变量是存放在栈空间里的,你定义一个m字节大小的变量,执行时就将m个字节压入栈空间(本质上是栈顶指针移动,将m字节划入栈)。因此你连续定义str和n两个局部变量,它们的内存空间就是相连的
因此,str数组被scanf函数越界访问的时候,n的内存数据就被改变了
第一个例子,n和str[1]占用同一个字节,n被赋值导致str[1]也同样变成了strlen的返回值9——这是一个不可见字符,因此printf无法让你看见它
第二个例子没什么可说的
第三个例子,跟第一个例子一样,str[1]被改成了不可见字符9,但为什么不输出str[2]之后的东西?因为int型占用4字节,除了最低字节是9之外,其他三个高字节都是有效数据0——没错,对于C风格字符串来说,str[2]就是结束符0了
第四个例子,n没有被初始化,strlen也没有被执行,那么由于scanf访问越界,n的四个字节就等同于str[1]到str[4],按字节换算就是53*256*256*256+52*256*256+51*256+50=892613426