鱼C论坛

 找回密码
 立即注册
查看: 2261|回复: 21

[已解决]关于指针和自增的一个小问题...

[复制链接]
发表于 2018-9-12 20:01:02 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
#include <stdio.h>

#define MAX 1024

int main()
{
        char str1[2 * MAX];
        char str2[MAX];

        char *target1 = str1;
        char *target2 = str2;

        char ch;
        int n;

        printf("请输入第一个字符串:");
        fgets(str1, MAX, stdin);

        printf("请输入第二格字符串:");
        fgets(str2, MAX, stdin);

        printf("请输入需要连接的字符个数:");
        scanf("%d", &n);

        while (*target1++ != '\0')
                ;

        target1 -= 2;

        while (n--)
        {
                ch = *target1++ = *target2++;
                if (ch == '\0')
                {
                        break;
                }
                if ((int)ch < 0)
                {
                        *target1++ = *target2++;            
                }
        }

        *target1 = '\0';

        printf("连接后的结果是:%s\n", str1);

        return 0;
}
这个程序是第22课的课后作业中的一道题。现在我们用此程序打印这样一句话:
鱼C工作室的域名 (输入到给字符串str1)
是:FishC.com (输入到给字符串str2)
然后把 *target = ‘\0’ 用双斜杠给注释掉。注释掉之后我们输入需要链接的字符个数可以为1~7都行,但是到8了就出乱码,不知道为什么!
还有一个问题就是,当while进行最后一次循环的时候,*target1和*target2这两个指针所进行的自增运算,也就是地址的偏移的数据会保留吗?
最佳答案
2018-9-12 20:14:09
1. 因为 while 内部有 *target1++,所以用 *target1 = '\0'; 以确保字符串的结束,如果没有,会有乱码的现象。字数不一定的,看情况。
2.指针是指针,不能够存储那些数据,存储数据的始终是 str1。target1 一开始是指向 str1 的首元素的地址而已,你 ++ 之后就偏移位置了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-9-12 20:14:09 | 显示全部楼层    本楼为最佳答案   
1. 因为 while 内部有 *target1++,所以用 *target1 = '\0'; 以确保字符串的结束,如果没有,会有乱码的现象。字数不一定的,看情况。
2.指针是指针,不能够存储那些数据,存储数据的始终是 str1。target1 一开始是指向 str1 的首元素的地址而已,你 ++ 之后就偏移位置了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-9-12 21:22:15 | 显示全部楼层
claws0n 发表于 2018-9-12 20:14
1. 因为 while 内部有 *target1++,所以用 *target1 = '\0'; 以确保字符串的结束,如果没有,会有乱码的现 ...

谢谢朋友帮我解答!我还是第二个小问题不太清楚,咱们就拿第一个while来举个栗子~
当表达式条件满足不了的时候,也就是判断 *target++ = ‘\0’的时候,此时此刻指针已经指向了结束字符‘\0’的位置,然后表达式不成立了,那这时候自增运算是不是还要进行最后的一次运算,结果是指向了‘\0’再向后的一个位置?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-9-12 21:32:15 | 显示全部楼层
啊涂涂 发表于 2018-9-12 21:22
谢谢朋友帮我解答!我还是第二个小问题不太清楚,咱们就拿第一个while来举个栗子~
当表达式条 ...

while n,跟 '\0' 没有关系。

退出的条件是 ch == '\0',退出之后,将目前 target1 所指向的地方赋值为 0 ,以表示字符串结束。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-9-12 21:42:41 | 显示全部楼层
claws0n 发表于 2018-9-12 21:32
while n,跟 '\0' 没有关系。

退出的条件是 ch == '\0',退出之后,将目前 target1 所指向的地方赋值 ...

那要是当退出第一个while循环的时候 *target的自增没起到作用的话,下面的 *target -= 2就会偏移到正常的字符上,然后下面的字符数组会把正常的字符给覆盖住不是?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-9-12 21:44:17 | 显示全部楼层
让我加下你好友吧,好好问问你。这个问题困扰我好几天了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-9-12 21:45:40 | 显示全部楼层
啊涂涂 发表于 2018-9-12 21:42
那要是当退出第一个while循环的时候 *target的自增没起到作用的话,下面的 *target -= 2就会偏移到正常的 ...

第一个是因为 target1 只是指向首地址,所以那个循环是让 target1 指到现有字符串的末端。第二个 while 才是把 str2 的内容附加到 str1 之后
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-9-12 21:52:29 | 显示全部楼层
claws0n 发表于 2018-9-12 21:45
第一个是因为 target1 只是指向首地址,所以那个循环是让 target1 指到现有字符串的末端。第二个 while  ...

那现有字符的末端不就是结束字符0吗?他第一个while下面用的有地址的偏移呀,在结束字符的位置上向左偏移两个位置,第一次到换行符,那第二次不就到正常字符了?而且他这个自增运算符是在表达式结束的时候才进行自增的,那是不是就证明虽然while括号里的条件满足不了,但是还是会进行最后一次自增?从而指向了结束字符再向后的一个位置,然后从此位置像左偏移两个位置,到达换行符。然后第二个str2的字符就会把换行符和结束字符给覆盖掉。我是这样想的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-9-12 23:31:49 | 显示全部楼层
啊涂涂 发表于 2018-9-12 21:52
那现有字符的末端不就是结束字符0吗?他第一个while下面用的有地址的偏移呀,在结束字符的位置上向左偏移 ...

第一个 while, target1 ++ ,最后一次会多走一次的。所以接下来就 target -= 2,移回来,指向 str1 '\0' 的位置。
第二个 while,看的是 n , 跟 str, target 等完全没有关系。运行的程序是从 str1 的 '\0' 开始覆盖。因为用户可以任意输入一格值,所以不能保证会遇到 str2 的结束符。因此,在退出循环后,target1 加上 '\0'
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-9-13 06:38:05 | 显示全部楼层
claws0n 发表于 2018-9-12 23:31
第一个 while, target1 ++ ,最后一次会多走一次的。所以接下来就 target -= 2,移回来,指向 str1 '\0'  ...

那个换行字符和结束字符哪个在句子的最末尾?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-9-13 06:49:21 | 显示全部楼层
啊涂涂 发表于 2018-9-13 06:38
那个换行字符和结束字符哪个在句子的最末尾?

应该是换行符在结束字符的前面,我上面用的是fgets函数来接受用户输入的字符串
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-9-13 10:46:33 | 显示全部楼层
兄弟解决了吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-9-13 15:35:26 | 显示全部楼层

没有完全解决
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-9-13 15:44:56 From FishC Mobile | 显示全部楼层
啊涂涂 发表于 2018-9-13 06:38
那个换行字符和结束字符哪个在句子的最末尾?

没有换行,哪来的换行?只有结束 '\0'。被覆盖掉了,才能把第二个字符串接在第一个后面,然后结束
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-9-13 15:59:38 | 显示全部楼层
claws0n 发表于 2018-9-13 15:44
没有换行,哪来的换行?只有结束 '\0'。被覆盖掉了,才能把第二个字符串接在第一个后面,然后结束

输完字符串不按回车吗?只有一个结束字符的话,他定位到结束字符之后还要向前偏移两个地址,那岂不是偏移到正常字符上了?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-9-13 16:08:19 From FishC Mobile | 显示全部楼层
本帖最后由 claws0n 于 2018-9-13 16:09 编辑
啊涂涂 发表于 2018-9-12 21:52
那现有字符的末端不就是结束字符0吗?他第一个while下面用的有地址的偏移呀,在结束字符的位置上向左偏移 ...


其实就第一个 while 循环是让指针指到字符串的最后一个元素。因为自增运算的关系,会跑过头,所以之后 target -= 2 移回来。目前指针指向 str1 的 '\0' 。第二个 while 是以 n 作为主要的结束条件。内部 ch 其实不需要赋值给 target1。无论如何,ch 的值是从 str2 来的,对吧?所以 if 只是一个安全措施。虽然有一点怪,但作用是把 str2 的资料加到 str1 的末端。最后为了安全,给 str1 加上结束符。

你的问题应该是自增......简单来说,加号在后,就是之后才加。
a = 5
b = a++
print(a, b) a == 6, b == 5
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-9-13 16:11:23 From FishC Mobile | 显示全部楼层
啊涂涂 发表于 2018-9-13 15:59
输完字符串不按回车吗?只有一个结束字符的话,他定位到结束字符之后还要向前偏移两个地址,那岂不是偏移 ...

fgets() 有安全保护,不要太在意
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-9-13 16:26:58 From FishC Mobile | 显示全部楼层
啊涂涂 发表于 2018-9-13 15:59
输完字符串不按回车吗?只有一个结束字符的话,他定位到结束字符之后还要向前偏移两个地址,那岂不是偏移 ...

str1 是函数内部定义的,所以没有初始化,都是垃圾值。写入时,靠左边的才有意义,所以还真的需要结束符。前前后后的过程都大致说明了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-9-13 18:20:36 | 显示全部楼层
claws0n 发表于 2018-9-13 16:26
str1 是函数内部定义的,所以没有初始化,都是垃圾值。写入时,靠左边的才有意义,所以还真的需要结束符 ...

嗯嗯,你说的我也知道。第二个while我明白什么意思,其实我的疑问特别简单,就是想问问换行符是不是在结束字符前面。刚才我试验了,把*target -= 2 给改成 *target -= 1了。结果出现的问题是确实没有把换行符覆盖,本来应该是 I Love FishC.com结果变成了 I Love
                                                        FishC.com
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-9-13 18:24:34 | 显示全部楼层
第一句话的排列不就是 I Love/n/0这样的嘛,然后自增跑过头 I Love/n/0/?(跑到?这里),此时此刻从问好开始向左偏移两个地址,先到0再到n。然后偏移结束,
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-3-29 04:51

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表