| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1720 人关注过本帖, 1 人收藏
标题:指针运算问题
只看楼主 加入收藏
albertwzh
Rank: 1
等 级:新手上路
帖 子:4
专家分:0
注 册:2011-11-14
结帖率:0
收藏(1)
已结贴  问题点数:20 回复次数:10 
指针运算问题
我编译运行下列代码遇到几个问题,麻烦哪位大虾帮忙看看
#include <stdio.h>
main()
{
int i;
char *s[]={"test\n","again","\n"}
for(i=0;*(s+1)!="\n";i++)
printf("%s\n",*(s+i));
}
编译运行后输出:
test

again

Segmentation fault(core dumped)

如果把for循环中的*(s+1)改成*(s++),编译不能通过,这是其中一个问题
另外为什么这段代码会有Segmentation fault(core dumped)错误
其次,如果我直接定义一个char指针,如char *s=“test”;,该指针不能进行+1或者++操作
我理解字符指针是可以进行++或者+1操作的,起原理为,将该指针指向的字符往后偏移一个char类型长度的地址
我的这段代码能进行+1操作,不能进行++操作,实在不能理解,我使用的编译器版本是gcc 4.4.5
望详解,多谢!
搜索更多相关主题的帖子: include 
2011-11-14 16:52
zy_space
Rank: 5Rank: 5
等 级:职业侠客
帖 子:163
专家分:364
注 册:2011-11-14
收藏
得分:5 
不管编译器是什么版本,for的用法都是相同的:

     for(表达式1;表达式2;表达式3) {
        语句;
     }

1.首先执行“表达式1”;
2.接着执行“语句”;
3.然后执行“表达式3”;
4.再执行“表达式2”,如果表达式值为非零,跳转到步骤二继续循环,如果值为零结束for语句的循环。


接着是你说的字符指针的问题。
字符指针是可以进行“+1”以及“++”运算的。
你定义char *s[],首先“[]”的结合性高于“*”,s是一个一维数组,“char *”定义数组中的元素是指向字符类型的指针变量。
是存储字符,但是一样可以存储字符串,原理是将字符串首个元素的地址存入字符指针(字符串可以理解为一维指针数组),当系统调用的时候从指针所存储的地址开始调用,一直到遇到‘\0’时为止。
所以你的问题可以解答了:假使你的代码能够通过编译,当第一次执行表达式2,也就是"*(s++)"的时候,s的值将加一,导致原先的s[0]丢失。这种内存错误对系统来说是比较严重的,我们应该尽量避免这种错误。同理char *s = "test",是一样的,可以执行“+1”操作而不能执行“++”操作。
但是可以通过这种方式来实现你的要求:
char *s = "test",  char *p = s;
对于指针p来说就既可以执行“+1”又可以执行“++”操作了

-------------------------------------------------------------------------------------------------

Ps:注册账号后的第一个回复

何必等待?梦在今朝
2011-11-14 17:19
森淼
Rank: 2
来 自:甘肃金昌
等 级:论坛游民
帖 子:10
专家分:17
注 册:2011-11-8
收藏
得分:5 
#include <stdio.h>
void main()
{
    int i;
    char *s[]={"test\n","again","\n"};
    for(i=0;*(s+i)!="\n";i++)
        printf("%s",*(s+i));  //多了/n
    getchar();//vc++2010调试所加
}
这样就可以了,输出正常

闲看庭前花开花落
漫随天外云卷云舒
2011-11-14 17:34
albertwzh
Rank: 1
等 级:新手上路
帖 子:4
专家分:0
注 册:2011-11-14
收藏
得分:0 
回复 2楼 zy_space
多谢指点,能否再请教几个问题
根据字符为一维数组的原理,如果我定义Char *s="test"; 那么执行s++或者s+1应该是使s指针指向test中第二个字符"e",为什么这样定义不行
另外定义char *s[]={"test\n","again","\n"}是我期望的,我的想法是,s是一个指向一个字符串的指针,那么第一次*s++/*s+1也应该是第一个字符串"test"的第二个字符"e",但这个运算的输出结果跟我的目的很不一样。
还有能不能定义一个指针去指向一个字符串,然后判断指针所指的字符串是否为\0来作为一个循环的结束标识,如果能改怎么做?
感谢!
2011-11-14 17:54
zy_space
Rank: 5Rank: 5
等 级:职业侠客
帖 子:163
专家分:364
注 册:2011-11-14
收藏
得分:0 
回复 4楼 albertwzh
首先我更正一下你的一个错误,"s + 1"和"s++"的含义并不相同,前者的含义只是一个运算表达式,而后者等价于"s = s + 1"。

然后回答你的第一个问题(s + 1可以,而s++不行):如果s代表的是字符串的首字符的地址(即&s[0]),那么"s+1"这个表达式(注意是表达式)所代表的含义是字符串中第二个字符的地址(即&s[1])。而"s++"相当于"s = s + 1",导致内存泄露的问题(具体名称不清楚,原因是:存储't'字符的内存没有释放出来,但是却同样无法引用,很危险)。

接着,关于字符指针数组的问题。s是一个以为数组的名称,数组中元素是指向字符的指针元素(原因前面已说),或者换言之,s是一个二阶的指针。由此在按照你的代码给s初始以后,数组s中的元素赋值情况如下:s[0]指向字符t(s[0]存储字符t的地址),s[1]指向字符a(s[1]存储字符a的地址),s[2]指向字符'\n'(s[2]存储字符'\n'的地址)。
这里还有一个问题你必须搞清楚,关于运算符的优先等级,解引用符*的优先级比加法运算符+等级高,但是比自增运算符 ++ 的等级要低。所以*s++和*s+1的含义也不相同。++等级高于*,(假使可以的话),*s++的含义是a的地址(*s++等价于*(s++).s是数组的地址,++使s向后偏移一个元素指向原来s[1]的地址,*解引用符消除(这个词不专业,先这么说吧,方便理解)一次指针,即*s相当于一个一阶指针,指向一个地址,因为++已经使s偏移,s由指向原来的s[0]变为指向原来的s[1],所以*s指向a的地址)。而*s+1不然,*s+1相当于(*s) + 1(*优先等级高于+),*s指向t的地址,所以*s+1含义是指向e的地址(注意这里是*s+1,而不是*(s+1))。
以上这些原因造成与你预期结果不同的输出。
至于你的最后一个问题答案是肯定的,但是注意不应该使用一个作为存储字符串的指针来实现,可以另外声明一个新的指针来实现。例如:

char *s = "Please test this program.\n", *p = s;
while(*p) {
//语句
}

通过检测指针p所指向的字符是否为'\0'来实现循环(若p指向'\0',*p的值为0,循环结束),for语句中以此类推,作为表达式2即可。

有一些建议:
你的基础概念不扎实,应该多看看书,多看一些正确的程序,多理解理解。如果你不把基础概念理解透光听我这样讲解你只会感到头晕,混淆你以前所学的知识。


祝你好运。

何必等待?梦在今朝
2011-11-14 19:46
zy_space
Rank: 5Rank: 5
等 级:职业侠客
帖 子:163
专家分:364
注 册:2011-11-14
收藏
得分:0 
手机回帖表示压力很大啊T_T

何必等待?梦在今朝
2011-11-14 19:48
albertwzh
Rank: 1
等 级:新手上路
帖 子:4
专家分:0
注 册:2011-11-14
收藏
得分:0 
回复 5楼 zy_space
多谢解答和建议,我也是才用C没多久,最近在看 C程序设计 K&R版本,这本书里发现有这么一段程序:
void strcpy(char *s, char *t)
{
while(*s++=*t++)
;
}
加上之前的理解想写段代码测试,发现和这书里讲的有不一样,但是作为一本经典的c教程,应该不会出现这种错误,再看看哪里理解不对。
感谢
2011-11-14 20:17
cnfarer
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:179
帖 子:3330
专家分:21157
注 册:2010-1-19
收藏
得分:5 
回复 7楼 albertwzh
这个没有问题!

★★★★★为人民服务★★★★★
2011-11-14 20:29
albertwzh
Rank: 1
等 级:新手上路
帖 子:4
专家分:0
注 册:2011-11-14
收藏
得分:0 
回复 8楼 cnfarer
请教为什么我的程序里*s++不能运行,即使定义一个 char *s="test",也不能进行这种操作?
2011-11-14 20:57
zy_space
Rank: 5Rank: 5
等 级:职业侠客
帖 子:163
专家分:364
注 册:2011-11-14
收藏
得分:0 
回复 9楼 albertwzh
这就涉及到函数里的形参与实参的单向传值问题了。strcpy(s, t)函数的作用是把t中的字符串复制给s。

何必等待?梦在今朝
2011-11-15 13:16
快速回复:指针运算问题
数据加载中...
 
   



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

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