肚子饿了233 发表于 2021-1-7 17:11:49

C语言!与指针有关,为啥要打括号?

1. 以下程序中函数replace的功能是:将字符串s中所有属于字符串s1中的字符都用s2中的对应位置的字符替换。假如s为“ABCBA”,s1为“AC”,s2为“ac”,则调用replace函数后,字符串s的内容将变换为“aBcBa”。试完善程序以达到要求的功能。
#include <stdio.h>
#define MAX 20
void replace(char *s, char *s1, char *s2)
{char *p;
   for(; *s; s++)
   {p=s1;
      while(*p&&   *p!=*s      ) p++;   
      if(*p)*s=      *s=*(s2+(p-s1))      ;      //就是这个地方,为啥写成*(s2+p-s1)就不能行了呢?
   }
}
void main( )
{char s="ABCBA",s1="AC", s2= "ac";
      replace(s, s1, s2);            
      printf("The string of s is:");
      printf("%s\n", s);
}

风过无痕1989 发表于 2021-1-7 17:18:43

本帖最后由 风过无痕1989 于 2021-1-7 17:30 编辑

因为指针 p 固定没有变,s1 是变化的,写成 (p - s1),就能将 s1 的变化反映到 s2,从而指向第2个字母 c,不然,就只能指向字母 a,不能指向字母 c.

肚子饿了233 发表于 2021-1-7 17:33:46

风过无痕1989 发表于 2021-1-7 17:18
因为指针 p 固定没有变,s1 是变化的,写成 (p - s1),就能将 s1 的变化反映到 s2,从而指向第2个字母 c, ...

指针p进行了p++操作,p咋不变了?s1是固定的

肚子饿了233 发表于 2021-1-7 17:42:11

风过无痕1989 发表于 2021-1-7 17:18
因为指针 p 固定没有变,s1 是变化的,写成 (p - s1),就能将 s1 的变化反映到 s2,从而指向第2个字母 c, ...

大神,我的疑问是为啥要加括号呀?不打括号为啥就运行不了呢?

风过无痕1989 发表于 2021-1-7 18:15:36

肚子饿了233 发表于 2021-1-7 17:42
大神,我的疑问是为啥要加括号呀?不打括号为啥就运行不了呢?

打不打括号不影响的,打个括号,只是更清晰一些,可以一眼就看出来,程序在此要干什么。不打括号就运行不了?不可能,我试试

WindyJane 发表于 2021-1-7 18:15:55

你好关于你的问题"就是这个地方,为啥写成*(s2+p-s1)就不能行了呢?"是这样的,任何语言都需要编译器,简单的理解就是 你写的代码是转交给编译器去完成转化交代给电脑(机器)去执行的,好的讲到这那还没回答问题呢~{:10_256:}
回答:首先你得明确你想表达的意思或你想让机器表达的意思:*s=*(s2+(p-s1))这个的意思是s2+偏移 之后解引用取值 赋值给了s所指向的地址的数据.
其次*(s2+p-s1) 这个变成了地址的加减了 之后再取值了, 这个是会有很大的问题的简单理解就是会丢失很多东西 这个是不被允许的,具体想了解可以看小甲鱼的汇编教程~
这个是我个人的理解可能会有偏差, 如果有帮助到您 请给个最佳答案呗~

lingwu 发表于 2021-1-7 18:16:12

c语言规定的指针算术运算只有两种:
指针加减一个整数,或者当两个指针指向同一个数组中的元素时,可以互相做减法。

如果去掉括号的话,加号运算符从左向右运算,两个指针进行减法运算,得到一个类型为ptrdiff_t的值
再用这个值去减一个指针,这种运算是不符合c语言规定的,所以会报错

风过无痕1989 发表于 2021-1-7 18:16:22

肚子饿了233 发表于 2021-1-7 17:33
指针p进行了p++操作,p咋不变了?s1是固定的

对,s1j 是固定的

风过无痕1989 发表于 2021-1-7 18:27:58

不打括号,编译器根据从左至右的原则,认为是 s2 + p 已经出界了,于是报 “不能添加两个指针”的错误
可以这么写:p - s1 + s2

if(*p)*s=      *s=*(s2+(p-s1));    此处的语句也有错误,应该是:
if(*p)*s=*(s2+(p-s1)) ;

肚子饿了233 发表于 2021-1-7 21:05:15

风过无痕1989 发表于 2021-1-7 18:27
不打括号,编译器根据从左至右的原则,认为是 s2 + p 已经出界了,于是报 “不能添加两个指针”的错误
可 ...

s2+p应该没有出界呀?数组s2和数组p的长度都是相同的,若p都不出界,那么s2+p也不会出界(s2本来就是首地址,下标为0),迷糊。。。

肚子饿了233 发表于 2021-1-7 21:07:49

WindyJane 发表于 2021-1-7 18:15
你好关于你的问题"就是这个地方,为啥写成*(s2+p-s1)就不能行了呢?"是这样的,任何语言都需要编译器,简 ...

那怎样解释将此行代码修改为*(p-s1+s2)又能正常运行呢?

肚子饿了233 发表于 2021-1-7 21:13:46

lingwu 发表于 2021-1-7 18:16
c语言规定的指针算术运算只有两种:
指针加减一个整数,或者当两个指针指向同一个数组中的元素时,可以互 ...

当两个指针指向同一个数组时,相互做加减法,如此题中p-s1,它是不是表示下标的变化?
所以按你的解释,*(s2+p-s1) 按照运算优先性,从左至右来算,s2和p不表示同一个数组,所以不能做加减法运算?

WindyJane 发表于 2021-1-7 21:22:46

本帖最后由 WindyJane 于 2021-1-7 21:24 编辑

肚子饿了233 发表于 2021-1-7 21:07
那怎样解释将此行代码修改为*(p-s1+s2)又能正常运行呢?

(p-s1+s2) 偏移+地址= (s2+(p-s1))地址+偏移 √
地址+地址 -地址 ×

WindyJane 发表于 2021-1-7 21:26:55

WindyJane 发表于 2021-1-7 21:22
(p-s1+s2) 偏移+地址= (s2+(p-s1))地址+偏移 √
地址+地址 -地址 ×

具体原因和原理要用汇编知识,简单理解就是汇编规定不允许的

风过无痕1989 发表于 2021-1-7 21:33:00

肚子饿了233 发表于 2021-1-7 21:13
当两个指针指向同一个数组时,相互做加减法,如此题中p-s1,它是不是表示下标的变化?
所以按你的解释, ...

s1 - p 它就不是指针了,而是一个数值,即偏移值,用这个偏移修值来修正指针 s2 的指向

风过无痕1989 发表于 2021-1-7 21:37:53

肚子饿了233 发表于 2021-1-7 21:13
当两个指针指向同一个数组时,相互做加减法,如此题中p-s1,它是不是表示下标的变化?
所以按你的解释, ...

s2 + p 是两个指针,不一定就不是同一个数组,比如
int a
p = a;
q = a;
q = p + 9 ,两个指针指向的是同一个数组,只不过是它们之间有一个偏移

肚子饿了233 发表于 2021-1-7 21:44:58

风过无痕1989 发表于 2021-1-7 21:37
s2 + p 是两个指针,不一定就不是同一个数组,比如
int a
p = a;


但题目中已经规定了呀,指针s2和指针p就是两个不同的数组指针,s2[]="ac",p[]="AC"。

肚子饿了233 发表于 2021-1-7 21:46:29

WindyJane 发表于 2021-1-7 21:22
(p-s1+s2) 偏移+地址= (s2+(p-s1))地址+偏移 √
地址+地址 -地址 ×

你的意思是,两个指向相同数组的指针的相加减表示的是偏移量吗?

WindyJane 发表于 2021-1-7 21:54:11

肚子饿了233 发表于 2021-1-7 21:46
你的意思是,两个指向相同数组的指针的相加减表示的是偏移量吗?

对的 ,但是要相减 不能相加哦

肚子饿了233 发表于 2021-1-7 21:56:07

WindyJane 发表于 2021-1-7 21:54
对的 ,但是要相减 不能相加哦

为啥不能相加呢? 难道相加就不表示偏移量了吗?
页: [1] 2
查看完整版本: C语言!与指针有关,为啥要打括号?