OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4002|回复: 28

字符数组问题,求解

[复制链接]

82

主题

589

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1255
金钱
1255
注册时间
2017-11-18
在线时间
296 小时
发表于 2018-1-13 10:25:31 | 显示全部楼层 |阅读模式
1金钱
1.问题描述:
我先定义了一个字符数组,并初始化,如下:
char SendBuff[] = "ABCDEFGH";                                      

然后我用strlen和sizeof分别计算它们在内存占用的字节大小:
len = strlen(SendBuff);
len_1 = sizeof(SendBuff);
然后在通过printf在电脑上位机上显示,结果是len = 16, len_1 = 8,这个结果我很疑惑,我觉得len应该等于8,sizeof等于9
然后我去看了这两个变量在内存中的值为十六进制len = 0x00000010和len_1 = 0x00000008,确实是对应16和8,为什么呢?
后来我将char SendBuff[] = "ABCDEFGH";      改为char SendBuff[] = "12345678";    这两个变量在内存中的值为十六进制len = 0x00000008和len_1 = 0x00000008,结果就正常了,什么原因呢?
2.截图如下:
问题1.jpg
问题2.jpg
问题3.jpg
问题4.jpg

最佳答案

查看完整内容[请看2#楼]

看了大家的回复,大部分是在讨论sizeof和strlen这两个问题上,还有就是会不会计算内存大小,字符数组初始化要不要给数组先指定大小的问题 1.字符数组初始化时候可以我们指定数组大小,也可以不指定,当我们不指定数组大小时候,那么在初始化时候编译器会自己计算并决定数组的大小 2.而且编译器也会自己在后面添加\0,因此并不存在找不到\0而得到一个数组大小随意值。 3.sizeof它是一个关键字而不是函数,sizeof(int)和sizeof in ...
没有脑袋
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

82

主题

589

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1255
金钱
1255
注册时间
2017-11-18
在线时间
296 小时
 楼主| 发表于 2018-1-13 10:25:32 | 显示全部楼层
看了大家的回复,大部分是在讨论sizeof和strlen这两个问题上,还有就是会不会计算内存大小,字符数组初始化要不要给数组先指定大小的问题
1.字符数组初始化时候可以我们指定数组大小,也可以不指定,当我们不指定数组大小时候,那么在初始化时候编译器会自己计算并决定数组的大小
2.而且编译器也会自己在后面添加\0,因此并不存在找不到\0而得到一个数组大小随意值。
3.sizeof它是一个关键字而不是函数,sizeof(int)和sizeof int,这两个计算的结果在32位系统下面结果都是4,一个有(),一个没有(),因此sizeof不是函数,而是关键字。相反strlen是函数。strlen()用于计算字符串中字符的数目(也就是字符长度,以字符为单位给出字符串长度,但是一个字符占用一个字节),当它遇到\0时候就会停止,因此它计算的结果中并不包括\0在内。而sizeof关键字计算得是在内存中占用的空间,在我们初始化字符数组时候,虽然只有A~H这8个字符,但是编译器会在后面自己加上\0,因此sizeof在计算时候它的结果将\0包含在内。
4.虚心向前辈们请教,感谢大家给出自己的见解,我C语言刚刚接触不久,里面有什么说的不对的知识点大家可以提出来,我回去看书找资料或者经过代码验证确认后改正,谢谢。大家共同进步~~~~~~~~~~
5.以上不明白的地方,大家也可以编译一下下面这段代码:
#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[])
{
        char SendBuff[] = "ABCDEFGH";
        int len_1 = 0;
        int len_2 = 0;
        
        len_1 = strlen(SendBuff);
        len_2 = sizeof(SendBuff);
        
        printf("strlen = %d\n", len_1);
        printf("sizeof = %d\n", len_2);
        
        return 0;
}


输出结果:
strlen = 8
sizeof = 9
没有脑袋
回复

使用道具 举报

10

主题

56

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
279
金钱
279
注册时间
2017-3-27
在线时间
66 小时
发表于 2018-1-13 11:02:35 | 显示全部楼层
汉字占2个字节,字母不分大小都是1个 你这边要是16的话 是不是你定义的时候开输入法了。。
回复

使用道具 举报

2

主题

685

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3448
金钱
3448
注册时间
2017-7-4
在线时间
869 小时
发表于 2018-1-13 11:05:02 | 显示全部楼层
开你的编辑器设置的编码格式。UTF-8?GB2312?
回复

使用道具 举报

82

主题

589

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1255
金钱
1255
注册时间
2017-11-18
在线时间
296 小时
 楼主| 发表于 2018-1-13 11:05:31 | 显示全部楼层
wangbo411326 发表于 2018-1-13 11:02
汉字占2个字节,字母不分大小都是1个 你这边要是16的话 是不是你定义的时候开输入法了。。

百度输入法???搜狗输入法???并没有,我输入ABCDEFGH都是英文输入法
没有脑袋
回复

使用道具 举报

82

主题

589

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1255
金钱
1255
注册时间
2017-11-18
在线时间
296 小时
 楼主| 发表于 2018-1-13 11:07:18 | 显示全部楼层
美丽的时光机器 发表于 2018-1-13 11:05
百度输入法???搜狗输入法???并没有,我输入ABCDEFGH都是英文输入法

还有就是我把字母减少2个就正常了,恢复到原来8个字母就不正常了,这怎么解释呢?所以我觉得不是输入法的锅
没有脑袋
回复

使用道具 举报

82

主题

589

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1255
金钱
1255
注册时间
2017-11-18
在线时间
296 小时
 楼主| 发表于 2018-1-13 11:07:38 | 显示全部楼层
wangbo411326 发表于 2018-1-13 11:02
汉字占2个字节,字母不分大小都是1个 你这边要是16的话 是不是你定义的时候开输入法了。。

还有就是我把字母减少2个就正常了,恢复到原来8个字母就不正常了,这怎么解释呢?所以我觉得不是输入法的锅
没有脑袋
回复

使用道具 举报

82

主题

589

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1255
金钱
1255
注册时间
2017-11-18
在线时间
296 小时
 楼主| 发表于 2018-1-13 11:11:35 | 显示全部楼层
Acuity 发表于 2018-1-13 11:05
开你的编辑器设置的编码格式。UTF-8?GB2312?

试过了,不行
没有脑袋
回复

使用道具 举报

3

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
82
金钱
82
注册时间
2017-12-28
在线时间
19 小时
发表于 2018-1-14 10:57:01 来自手机 | 显示全部楼层
用strlen计算字符数组的长度,得到的值是一个随机数,因为strlen一直在找字符结束符'/0',所以是一个随机数,而sizeof计算的是数组大小,所以会为8
回复

使用道具 举报

3

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
82
金钱
82
注册时间
2017-12-28
在线时间
19 小时
发表于 2018-1-14 10:59:29 来自手机 | 显示全部楼层
strlen是计算字符串的长度的,字符串和字符数组不一样
回复

使用道具 举报

82

主题

589

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1255
金钱
1255
注册时间
2017-11-18
在线时间
296 小时
 楼主| 发表于 2018-1-14 12:54:45 | 显示全部楼层
yuneizhilin 发表于 2018-1-14 10:57
用strlen计算字符数组的长度,得到的值是一个随机数,因为strlen一直在找字符结束符'/0',所以是一个随机数 ...

字符数组,初始化时候会自动在末尾加上\0的,所以你这种分析方式是不对的,得到的不是随机数
没有脑袋
回复

使用道具 举报

82

主题

589

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1255
金钱
1255
注册时间
2017-11-18
在线时间
296 小时
 楼主| 发表于 2018-1-14 12:55:42 | 显示全部楼层
yuneizhilin 发表于 2018-1-14 10:59
strlen是计算字符串的长度的,字符串和字符数组不一样

可以计算
没有脑袋
回复

使用道具 举报

3

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
82
金钱
82
注册时间
2017-12-28
在线时间
19 小时
发表于 2018-1-14 14:25:42 来自手机 | 显示全部楼层
字符串初始化会自动加结束符,字符数组不会
回复

使用道具 举报

82

主题

589

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1255
金钱
1255
注册时间
2017-11-18
在线时间
296 小时
 楼主| 发表于 2018-1-14 14:52:22 | 显示全部楼层
yuneizhilin 发表于 2018-1-14 10:57
用strlen计算字符数组的长度,得到的值是一个随机数,因为strlen一直在找字符结束符'/0',所以是一个随机数 ...

1."sizeof计算的是数组大小,所以会为8",这句话不对,sizeof计算结果包含\0在内,这点如果你不明白可以翻书看。
2.strlen是用来计算实际字符数的,计算的结果不包括编译器自动加上的\0,字符数组初始化时候也会在后面加上\0
没有脑袋
回复

使用道具 举报

82

主题

589

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1255
金钱
1255
注册时间
2017-11-18
在线时间
296 小时
 楼主| 发表于 2018-1-14 14:57:37 | 显示全部楼层
yuneizhilin 发表于 2018-1-14 14:25
字符串初始化会自动加结束符,字符数组不会

1.写个代码验证下不就好了
没有脑袋
回复

使用道具 举报

82

主题

589

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1255
金钱
1255
注册时间
2017-11-18
在线时间
296 小时
 楼主| 发表于 2018-1-14 14:58:44 | 显示全部楼层
yuneizhilin 发表于 2018-1-14 14:25
字符串初始化会自动加结束符,字符数组不会

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

int main(int argc, char *argv[])
{
        char SendBuff[] = "ABCDEFGH";
        int len_1 = 0;
        int len_2 = 0;
       
        len_1 = strlen(SendBuff);
        len_2 = sizeof(SendBuff);
       
        printf("strlen = %d\n", len_1);
        printf("sizeof = %d\n", len_2);
       
        return 0;
}


输出结果:
strlen = 8
sizeof = 9
没有脑袋
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165536
金钱
165536
注册时间
2010-12-1
在线时间
2117 小时
发表于 2018-1-15 01:02:22 | 显示全部楼层
仿真,看sendbuff的实际地址,然后看后面是否有0?直接看地址,比如0X0800xxxx之类的。
回复

使用道具 举报

82

主题

589

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1255
金钱
1255
注册时间
2017-11-18
在线时间
296 小时
 楼主| 发表于 2018-1-15 08:15:39 | 显示全部楼层
正点原子 发表于 2018-1-15 01:02
仿真,看sendbuff的实际地址,然后看后面是否有0?直接看地址,比如0X0800xxxx之类的。

&SendBuff的值是:0x20000010,好像跟你说的地址格式0X0800xxxx有些出入
请问一下原子哥,查看这个实际地址有什么用意吗?
没有脑袋
回复

使用道具 举报

16

主题

204

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1904
金钱
1904
注册时间
2015-7-5
在线时间
484 小时
发表于 2018-1-15 08:45:48 | 显示全部楼层
本帖最后由 huyounong 于 2018-1-15 09:00 编辑

sizeof  和 len  不是一个概念吧
C语言里面  字符串是个比较麻烦的东西。有的C语言  字符串用纯粹的ASCII存储,有的将"ABCD“变化成某种编码再存储,也就是在实际的内存里面增加了东西。要看C编译器版本了
回复

使用道具 举报

82

主题

589

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1255
金钱
1255
注册时间
2017-11-18
在线时间
296 小时
 楼主| 发表于 2018-1-15 09:03:19 | 显示全部楼层
huyounong 发表于 2018-1-15 08:45
sizeof  和 len  不是一个概念吧
C语言里面  字符串是个比较麻烦的东西。有的C语言  字符串用纯粹的ASCII ...

我发帖求助不是为了区分sizeof和len这个概念,先看看我帖子里描述的
没有脑袋
回复

使用道具 举报

6

主题

60

帖子

0

精华

高级会员

Rank: 4

积分
863
金钱
863
注册时间
2016-2-17
在线时间
192 小时
发表于 2018-1-15 11:35:43 | 显示全部楼层
美丽的时光机器 发表于 2018-1-15 09:03
我发帖求助不是为了区分sizeof和len这个概念,先看看我帖子里描述的

头像是本人吗
回复

使用道具 举报

14

主题

44

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
386
金钱
386
注册时间
2016-9-5
在线时间
66 小时
发表于 2018-1-15 13:28:16 | 显示全部楼层
你定义sendbuf字符串数组时没有指定内存分配大小,而strlen函数的参数是指针型char*,所以计算的时候会出错,你试试看再定义一个char *p = sendbuf,然后 strlen(p);
回复

使用道具 举报

82

主题

589

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1255
金钱
1255
注册时间
2017-11-18
在线时间
296 小时
 楼主| 发表于 2018-1-15 13:48:23 | 显示全部楼层
huyounong 发表于 2018-1-15 08:45
sizeof  和 len  不是一个概念吧
C语言里面  字符串是个比较麻烦的东西。有的C语言  字符串用纯粹的ASCII ...

在这里不讨论其他编译器版本   就是Keil开发平台   请你说具体一点,不要说“有的”,“某种”,如果都是如果所有问题都是很模糊的话就没有讨论必要了,也讨论不出准确的结果,我们在这里就只讨论Keil这个平台
没有脑袋
回复

使用道具 举报

82

主题

589

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1255
金钱
1255
注册时间
2017-11-18
在线时间
296 小时
 楼主| 发表于 2018-1-15 13:52:09 | 显示全部楼层
梨落繁华心 发表于 2018-1-15 13:28
你定义sendbuf字符串数组时没有指定内存分配大小,而strlen函数的参数是指针型char*,所以计算的时候会出错 ...

1.我已经将字符数组初始化了,初始化后已经分配内存大小
2.字符数组也可以不指定分配内存大小,初始化后由编译器自行计算出大小
没有脑袋
回复

使用道具 举报

82

主题

589

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1255
金钱
1255
注册时间
2017-11-18
在线时间
296 小时
 楼主| 发表于 2018-1-15 13:52:53 | 显示全部楼层

是滴呀  介绍里说明清楚了,头像本人
没有脑袋
回复

使用道具 举报

3

主题

73

帖子

0

精华

初级会员

Rank: 2

积分
196
金钱
196
注册时间
2017-5-4
在线时间
21 小时
发表于 2018-1-15 15:36:06 | 显示全部楼层
你看下数组的实际地址,比如实际地址是0x20000010,那看下这个地址里面的值是不是都是0x00,有没有不是0x00的值,有可能加入某个值默认是0xFF,在strlen计算的时候,0xFF也当做实际的数组长度进行计算了,理论是你说的没错,但是嵌入式编译器有时候和实际情况就是不一样
回复

使用道具 举报

82

主题

589

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1255
金钱
1255
注册时间
2017-11-18
在线时间
296 小时
 楼主| 发表于 2018-1-15 16:41:21 | 显示全部楼层
mill 发表于 2018-1-15 15:36
你看下数组的实际地址,比如实际地址是0x20000010,那看下这个地址里面的值是不是都是0x00,有没有不是0x00 ...

我搬出理论的原因是因为回帖的好多人理论都没掌握好,甚至有些人都不知道我问的是什么,所以呀   不管这个问题是啥原因导致的,理论始终是依据,而且发帖求助的同时也是希望大家都能有收获,帮到我的同时我也可以帮到回帖的人,毕竟大家还是提出了很好的分析方法来参考的嘛。这个问题就暂时讨论到这里吧,原因大概就是编译器问题(因为Keil毕竟是破解版的),要么就是我自己代码都问题,因为工程里面还有其他文件代码可能会产生干扰,也暂时没办法给大家发出来全面分析相关代码,总之,sizeof和strlen这两个我还是相信它们不会算错的~~~~~~
谢谢大家百忙之中回帖~~~~~~~~~~~~~
没有脑袋
回复

使用道具 举报

82

主题

589

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1255
金钱
1255
注册时间
2017-11-18
在线时间
296 小时
 楼主| 发表于 2018-1-15 16:42:36 | 显示全部楼层
结贴了  感谢大家
没有脑袋
回复

使用道具 举报

82

主题

589

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1255
金钱
1255
注册时间
2017-11-18
在线时间
296 小时
 楼主| 发表于 2018-1-15 16:53:29 | 显示全部楼层
正点原子 发表于 2018-1-15 01:02
仿真,看sendbuff的实际地址,然后看后面是否有0?直接看地址,比如0X0800xxxx之类的。

回想了一下,突然明白你的意思了
没有脑袋
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-12 22:41

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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