1613551 发表于 2022-4-23 14:24:27

有没有大佬讲解一下为什么要-1啊

{:10_266:} 看了好多遍还是没有理解,这个减一有什么用,好像都一样吧?

isdkz 发表于 2022-4-23 14:28:49

因为下标是以 0 开始的,而字符数组的大小是从 1 开始算的,当然要减1了

1613551 发表于 2022-4-23 14:34:47

isdkz 发表于 2022-4-23 14:28
因为下标是以 0 开始的,而字符数组的大小是从 1 开始算的,当然要减1了

{:10_282:}不好意思,没看懂....下标是什么...就是可以举例一下吗

isdkz 发表于 2022-4-23 14:38:48

本帖最后由 isdkz 于 2022-4-23 14:42 编辑

1613551 发表于 2022-4-23 14:34
不好意思,没看懂....下标是什么...就是可以举例一下吗

下标也就是索引,表示第几个,str 中的 0 就是下标,

在计算机中是以 0 开始的,不是以 1 开始的,

比如说 char str 声明了一个长度为 10 的字符数组,

这个字符数组的第一个元素是 str,而不是 str,

所以第10个元素不是 str,而是 str,即 str

1613551 发表于 2022-4-23 14:57:25

isdkz 发表于 2022-4-23 14:38
下标也就是索引,表示第几个,str 中的 0 就是下标,

在计算机中是以 0 开始的,不是以 1 开始的 ...

我好像有点懂了,你是说sizeof计算大小的时候会把\n也计算进去,所以为正确的计算出字符串的大小,所以应该-1,相当于把多计算的\n去掉吗?

isdkz 发表于 2022-4-23 15:00:46

1613551 发表于 2022-4-23 14:57
我好像有点懂了,你是说sizeof计算大小的时候会把\n也计算进去,所以为正确的计算出字符串的大小,所以应 ...

不是,sizeof计算出来的就是字符串的长度了,因为字符的位置是从 0 开始算的,

而长度是从 1 开始算的,所以字符串的最后一个字符就是字符串的长度减 1 呀

1613551 发表于 2022-4-23 15:10:27

isdkz 发表于 2022-4-23 15:00
不是,sizeof计算出来的就是字符串的长度了,因为字符的位置是从 0 开始算的,

而长度是从 1 开始算的 ...

这样的话我突然不是很理解为什么要用sizeof来计算,而不用strlen

isdkz 发表于 2022-4-23 15:13:49

1613551 发表于 2022-4-23 15:10
这样的话我突然不是很理解为什么要用sizeof来计算,而不用strlen

strlen得到的只是字符串的长度(不包括结束符\0),

而 sizeof 得到的是整个字符数组的长度

1613551 发表于 2022-4-23 15:22:03

isdkz 发表于 2022-4-23 15:13
strlen得到的只是字符串的长度(不包括结束符\0),

而 sizeof 得到的是整个字符数组的长度

我没理解,如果是char类型的话,sizeof不就比strlen多获取了一个\n吗?然后还通过-1,然后减掉了

风车呼呼呼 发表于 2022-4-23 19:40:18

1.sizeof所计算的是该变量的内存空间有多大(能放多少字节的数据)
2.字符串必须以'\0'结尾,否则编译器不会知道字符串是到哪里结束,'\0'也占着1字节的空间

在你的例子中,str数组有10字节的内存空间可用,也就是最多能放10字节的数据,1个字符占1字节空间
字符串"I love FishC.com!"长度是17,尺寸(所占空间)是18(含'\0')
str数组空间明显不够存放完整
本着能放多少就放多少的想法,就有了
strcat(str, "I love FishC.com!", sizeof(str))
也就是把字符串的前10个字符放进去,即"I love Fis"
但是这样一来str空间就被用完了,'\0'放不下去就出问题了
你或许可以通过str的方式来逐一访问每一个字符,但是想要以%s一次性输出字符串就肯定不行,没有'\0'做结尾根本无法识别
综上,你必须留出最后一字节空间存放'\0'

FK二十一 发表于 2022-4-24 09:49:12

strlen 函数用于返回指定字符串的长度。
C 语言字符串的长度取决于结束符('\0')的位置。   
                                                                     —— 小甲鱼
也就是说都会计算' \n '的

cjgank 发表于 2022-4-24 10:25:14


1.楼主应理解字符数组如何存放字符串
2.关于sizeof()和strlen()的区别,看一下这篇文章    https://www.cnblogs.com/caojun97/p/16129482.html

1613551 发表于 2022-4-24 13:02:02

风车呼呼呼 发表于 2022-4-23 19:40
1.sizeof所计算的是该变量的内存空间有多大(能放多少字节的数据)
2.字符串必须以'\0'结尾,否则编译器不 ...

我懂了,就是strcat是会在末尾自动追加一个\0的,而数组的长度最大也才10,你又填了10个字符进来,那么就没有\0的位置了

1613551 发表于 2022-4-24 13:03:56

风车呼呼呼 发表于 2022-4-23 19:40
1.sizeof所计算的是该变量的内存空间有多大(能放多少字节的数据)
2.字符串必须以'\0'结尾,否则编译器不 ...

但是,我试了一下,就算不留个位置给\0,程序也能正常打印诶?

风车呼呼呼 发表于 2022-4-24 15:45:11

1613551 发表于 2022-4-24 13:03
但是,我试了一下,就算不留个位置给\0,程序也能正常打印诶?

的确,strcat是会自动在末尾追加\0,虽然10字节空间已经被占满了,最后的\0还是会放在紧接在这10字节后面的一字节空间内,这并不是数组str的内存空间了。
而按%s打印,实际上是传一个首地址开始读数据,读到\0就认为结束了,并不会检查是不是超过了str的空间。

虽然能打印出正确结果,但绝对不要这么做
一是因为内存里具体怎么存放数据,哪个数据放在了哪个地址里,这都是系统做的事,对程序员是不可见的,万一紧接在str后面的内存空间存放着有用的数据,你这\0一过去就覆盖破环了原数据,后果是无法估计的。
二是假设你认为了str这空间里面存放的就是完整字符串了,如果将它逐一字符的放进另一个10字节大小的空间,这时候新的那片空间之后的可就不一定是\0了,再想以字符串完整输出肯定会多出一片乱码

zzxhh628 发表于 2022-4-24 15:46:55

1613551 发表于 2022-4-24 13:03
但是,我试了一下,就算不留个位置给\0,程序也能正常打印诶?

#include <stdio.h>
#include <string.h>

int main()
{
    char a="abcde";
    char a2="abcd";
    size_t b=sizeof(a);
    size_t b2=sizeof(a2);
    int c=strlen(a);
    int c2=strlen(a2);
    printf("%s %d %d\n",a,b,c);
    printf("%s %d %d\n",a2,b2,c2);
    if(a=='\0')
      printf("!");
    return 0;
}
你试试这个,看看sizeof和strlen得出结果的区别,sizeof得到的是整个字符数组的长度,但是strlen得到的是字符串的长度(不算\0)。字符串结尾都是\0,就算你不留空间它也是\0,但是可能会覆盖其他数据吧。
页: [1]
查看完整版本: 有没有大佬讲解一下为什么要-1啊