标题:继续请教我之前一个小程序的问题,短信可能不容易被发现
只看楼主
a271885843
Rank: 2
等 级:论坛游民
帖 子:291
专家分:58
注 册:2011-11-24
结帖率:84.38%
已结贴  问题点数:10 回复次数:13 
继续请教我之前一个小程序的问题,短信可能不容易被发现
#include<stdlib.h>
#include<stdio.h>

int main()
{

    char a[1000];
    char *p;

    gets(a);
    p=a;


    printf("%s\n",p);
    system("pause");
    return 0;
}

这是 论坛里一朋友对我https://bbs.bccn.net/viewthread.php?tid=357272&extra=&page=1 这个帖子的回复。我想问下,我的意思是*p输出,为什么在这里用p呢,还有就是为什么我用*p之后,编译没问题,正常通过,但一运行exe的时候就会出现内存出错的提示呢
搜索更多相关主题的帖子: 短信 include system return 
2011-12-08 22:17
zjslwyp
Rank: 2
等 级:论坛游民
帖 子:42
专家分:76
注 册:2011-3-24
得分:2 
对于这个我只想说你对C的基础比较一般。先去看下书,对你比较有帮助。
2011-12-08 22:37
wang155423
Rank: 6Rank: 6
等 级:侠之大者
帖 子:216
专家分:408
注 册:2011-9-4
得分:2 
这里是字符串输出,指的是从p的首地址开始逐个输出,基本的语法,看看书吧
2011-12-08 22:38
a271885843
Rank: 2
等 级:论坛游民
帖 子:291
专家分:58
注 册:2011-11-24
得分:0 
以下是引用a271885843在2011-12-8 22:17:36的发言:

#include
#include

int main()
{

    char a[1000];
    char *p;

    gets(a);
    p=a;


    printf("%s\n",p);
    system("pause");
    return 0;
}

这是 论坛里一朋友对我https://bbs.bccn.net/viewthread.php?tid=357272&extra=&page=1 这个帖子的回复。我想问下,我的意思是*p输出,为什么在这里用p呢,还有就是为什么我用*p之后,编译没问题,正常通过,但一运行exe的时候就会出现内存出错的提示呢
你说了我就记住了。是不?

认为事物非黑即白是缺智慧的表现……
2011-12-09 20:03
a271885843
Rank: 2
等 级:论坛游民
帖 子:291
专家分:58
注 册:2011-11-24
得分:0 
自己定上去,我自己没多少时间去看书了。真的。群里好心的哥哥姐姐帮我解答一下吧。3Q

认为事物非黑即白是缺智慧的表现……
2011-12-09 20:06
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
得分:2 
有在这里顶的时间都把书看完了,早解决了。

授人以渔,不授人以鱼。
2011-12-09 20:54
a271885843
Rank: 2
等 级:论坛游民
帖 子:291
专家分:58
注 册:2011-11-24
得分:0 
以下是引用TonyDeng在2011-12-9 20:54:21的发言:

有在这里顶的时间都把书看完了,早解决了。
明白了。其实不是我不去看书,而是看了书之后我产生了疑惑。char *p;定义字符串指针,其作用是来存放字符串首地址或者数组的首地址的,比如直接将将字符串赋值给它,如p="c programe langeuge",p就存放这句话的首地址,然后如果是printf("%s\n",p);那么表示从p所存放的首地址开始将此字符串全部输出,但如果是printf("%\n",*p);那么表示输出指针p所指的那个地址存放的单个字符,如全部输出此句话,要加上
  while(*p!='\0')
    {
        printf("%c",*p);
        p++;
    }
才能将此句全部输出,但我的疑问又有了,下面程序运行怎么可以编译通过,输入一段字符按回车,没有输出第一个字符啊,而且显示内存出错,这才是我想问的。
#include<stdlib.h>
#include<stdio.h>
int main()
{
  char a[1000];
    char *p;
    gets(a);
     p=a;
  printf("%s\n",*p);
 }

认为事物非黑即白是缺智慧的表现……
2011-12-09 22:25
embed_xuel
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:58
帖 子:3845
专家分:11385
注 册:2011-9-13
得分:2 
回复 7楼 a271885843
你自己都写了,你打印*p用%c可以,用%s就出错了

总有那身价贱的人给作业贴回复完整的代码
2011-12-09 22:34
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
得分:0 
首先纠正你一个概念:char *p不是定义字符串指针,而是定义一个指针,而且这个指针所指向的数据是char类型的。当定义char *p的时候,指针p是可以运动的,随着它的移动,每个*p所取得的数据跟着变化。但是要注意,指针与数组是有区别的,定义数组char a[1000]时,a虽然是首地址指针,但a无法像p那样运动,你可以a+2或*(a+2),但无法a += 2,而p可以p += 2。因此,要定义数组,不要只考虑char *p,那不是数组,而只是单个指针。

然后,解释你现在的问题。函数printf()是别人写好的代码,当使用格式码"%s"的时候,函数预期匹配的参数是一个字符数组的入口指针,而且这个字符数组应该按照C语言的cz规范构造(即有字符'\0'作结束标志)。好了,现在看你的printf("%s", *p),函数认为,*p是数组入口,也就是说,它把现在指针p的对象值作为了地址,而不是把p作为地址。因此,函数到地址为*p的地方寻找数据,对char数据来说,其值小于255,这个地址值往往是程序的保护区,何况,从这个地址开始往后搜寻,printf()函数经常很难遇到'\0'终止自己的行动,后果是无法猜测的。也就是说,p才是你希望的数组入口,*p不是。

函数printf()所预期的东西,不归编译器管辖,编译器绝对不会验证printf("%d", "hello")这样的问题,因为验证传入数据是否正确是函数编写者自己的事,偏偏写printf()和scanf()函数的程序员是不作这种验证的,他假定使用这个函数的人自己保证输入正确的数据。这是一种很可怕的编程风格。


[ 本帖最后由 TonyDeng 于 2011-12-9 22:55 编辑 ]

授人以渔,不授人以鱼。
2011-12-09 22:52
a271885843
Rank: 2
等 级:论坛游民
帖 子:291
专家分:58
注 册:2011-11-24
得分:0 
以下是引用embed_xuel在2011-12-9 22:34:35的发言:

你自己都写了,你打印*p用%c可以,用%s就出错了
哎。谢谢你。

认为事物非黑即白是缺智慧的表现……
2011-12-09 22:53



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-357340-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.329737 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved