OpenEdv-开源电子网

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

const加不加?

[复制链接]

35

主题

193

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
476
金钱
476
注册时间
2015-12-27
在线时间
116 小时
发表于 2016-1-28 00:16:02 | 显示全部楼层 |阅读模式
1金钱
const u8 TEXT_Buffer[]={"!Good Luck to My Father!"};
为什么要加const,不加可以吗?const表示是固定在flash中,在程序运行时不能改变,那不加会有什么影响吗?

最佳答案

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

不加的话TEXT_Buffer表示是内存里面的数组,会占用!Good Luck to My Father!这么多个字节的内存. 如果加就是放在flash里面,不会占用内存.
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165186
金钱
165186
注册时间
2010-12-1
在线时间
2106 小时
发表于 2016-1-28 00:16:03 | 显示全部楼层
不加的话TEXT_Buffer表示是内存里面的数组,会占用!Good Luck to My Father!这么多个字节的内存.  如果加就是放在flash里面,不会占用内存.
回复

使用道具 举报

9

主题

538

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3371
金钱
3371
注册时间
2015-1-7
在线时间
794 小时
发表于 2016-1-28 07:17:10 来自手机 | 显示全部楼层
不加的话就会放到RAM中,也能正常运行,对于常量而言其值在运行过程中不会发生改变,放在flash中比放到RAM中更合适,RAM要省着用。放在RAM中的好处是可以随意修改其值,且写入速度快,但常量不用修改其值,flash的读取速度和RAM读取差不太多,故放到flash中合理。其次也是出于严谨的要求,表明这个text_buffer是不能更改的,程序员看到的时候会注意不要去修改,编译器也能帮忙发现其值是否改变过并告警
回复

使用道具 举报

81

主题

1002

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1876
金钱
1876
注册时间
2014-9-10
在线时间
208 小时
发表于 2016-1-28 10:36:50 | 显示全部楼层
const是放在flash中吗?我觉得跟存储没关系,加不加都是一个地方。没看到有说放在flash中的资料。
C语言里,const是只读的意思。
加了const,如果程序哪里对其进行写操作,编译就会报错。
例如你不想让a值初始化以后再改变。const int a = 1;

其他地方不能对a赋值,你下面写个a = 2;就报错。

如果你不加,a被改了你也不知道。

还有函数里的形参,如字符串处理那几个,输入的源字符串不改变的最好加const,可以防止意外被改变。
万一哪里修改了就会报错。
小小蜗牛
回复

使用道具 举报

35

主题

193

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
476
金钱
476
注册时间
2015-12-27
在线时间
116 小时
 楼主| 发表于 2016-1-28 10:59:59 | 显示全部楼层
ianhom 发表于 2016-1-28 07:17
不加的话就会放到RAM中,也能正常运行,对于常量而言其值在运行过程中不会发生改变,放在flash中比放到RAM ...

我在昨天测试的时候发现,如果去掉const的话,在调用函数的时候(u8*)TEXT_Buffer,就可以写成TEXT_Buffer,此时,程序是可以运行的,但是如果要是加上const的话,,就必须写成(u8*)TEXT_Buffer这个形式了,在这里我就有个疑问,TEXT_Buffer这个数组本身就是u8类型的,所以这个函数名本身就可以理解成指向u8型变量的指针吧,(u8*)TEXT_Buffer这句话,是表示将TEXT_Buffer强制转化成指向u8*类型变量的指针,这两者有什么区别吗?昨天看了一晚上的C语言,感觉大部分能懂了,就这块有点疑问,去掉const的话,直接写成TEXT_Buffer就是好使的,不去掉const的话,程序就是不好使,这块疑问比较大
回复

使用道具 举报

35

主题

193

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
476
金钱
476
注册时间
2015-12-27
在线时间
116 小时
 楼主| 发表于 2016-1-28 11:00:19 | 显示全部楼层
jiutianshenjian 发表于 2016-1-28 10:36
const是放在flash中吗?我觉得跟存储没关系,加不加都是一个地方。没看到有说放在flash中的资料。
C语言里 ...

我在昨天测试的时候发现,如果去掉const的话,在调用函数的时候(u8*)TEXT_Buffer,就可以写成TEXT_Buffer,此时,程序是可以运行的,但是如果要是加上const的话,,就必须写成(u8*)TEXT_Buffer这个形式了,在这里我就有个疑问,TEXT_Buffer这个数组本身就是u8类型的,所以这个函数名本身就可以理解成指向u8型变量的指针吧,(u8*)TEXT_Buffer这句话,是表示将TEXT_Buffer强制转化成指向u8*类型变量的指针,这两者有什么区别吗?昨天看了一晚上的C语言,感觉大部分能懂了,就这块有点疑问,去掉const的话,直接写成TEXT_Buffer就是好使的,不去掉const的话,程序就是不好使,这块疑问比较大
回复

使用道具 举报

9

主题

538

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3371
金钱
3371
注册时间
2015-1-7
在线时间
794 小时
发表于 2016-1-28 11:04:57 | 显示全部楼层
jiutianshenjian 发表于 2016-1-28 10:36
const是放在flash中吗?我觉得跟存储没关系,加不加都是一个地方。没看到有说放在flash中的资料。
C语言里 ...

这个不是C语言的特性,是单片机编译优化的特性,一般编译的时候,编译器会优化const变量放到flash区域,如果你用volatile const修饰的话,就是指定放到RAM中
机器生汇编,汇编生B,B生C,C生万物.... 经过长期对C语言的研究,目前只有两个方面不懂:这也不懂,那也不懂
https://github.com/ianhom
回复

使用道具 举报

35

主题

193

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
476
金钱
476
注册时间
2015-12-27
在线时间
116 小时
 楼主| 发表于 2016-1-28 11:09:56 | 显示全部楼层
ianhom 发表于 2016-1-28 11:04
这个不是C语言的特性,是单片机编译优化的特性,一般编译的时候,编译器会优化const变量放到flash区域, ...

那为什么去掉const的话,(u8*)TEXT_Buffer就可以在函数调用的时候改成TEXT_Buffer,如果不去掉,就不行呢?
回复

使用道具 举报

9

主题

538

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3371
金钱
3371
注册时间
2015-1-7
在线时间
794 小时
发表于 2016-1-28 11:14:26 | 显示全部楼层
本帖最后由 ianhom 于 2016-1-28 23:25 编辑
q546163199 发表于 2016-1-28 10:59
我在昨天测试的时候发现,如果去掉const的话,在调用函数的时候(u8*)TEXT_Buffer,就可以写成TEXT_Buffer ...

我在昨天测试的时候发现,如果去掉const的话,在调用函数的时候(u8*)TEXT_Buffer,就可以写成TEXT_Buffer,此时,程序是可以运行的,但是如果要是加上const的话,,就必须写成(u8*)TEXT_Buffer这个形式了,在这里我就有个疑问,TEXT_Buffer这个数组本身就是u8类型的,所以这个函数名本身就可以理解成指向u8型变量的指针吧
TEXT_Buffer是数组名,TEXT_Buffer是一个常量,其值为一个地址,这个地址为数组首元素的地址,可以说TEXT_Buffer这个常量的值为一个const u8类型的数据的地址。
TEXT_buffer本身不是指针变量(这一点我之前回答有误,感谢各位指正)。

机器生汇编,汇编生B,B生C,C生万物.... 经过长期对C语言的研究,目前只有两个方面不懂:这也不懂,那也不懂
https://github.com/ianhom
回复

使用道具 举报

9

主题

538

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3371
金钱
3371
注册时间
2015-1-7
在线时间
794 小时
发表于 2016-1-28 11:15:38 | 显示全部楼层
q546163199 发表于 2016-1-28 11:09
那为什么去掉const的话,(u8*)TEXT_Buffer就可以在函数调用的时候改成TEXT_Buffer,如果不去掉,就不行 ...

最好能看到你具体的代码
机器生汇编,汇编生B,B生C,C生万物.... 经过长期对C语言的研究,目前只有两个方面不懂:这也不懂,那也不懂
https://github.com/ianhom
回复

使用道具 举报

81

主题

1002

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1876
金钱
1876
注册时间
2014-9-10
在线时间
208 小时
发表于 2016-1-28 11:16:57 | 显示全部楼层
q546163199 发表于 2016-1-28 10:59
我在昨天测试的时候发现,如果去掉const的话,在调用函数的时候(u8*)TEXT_Buffer,就可以写成TEXT_Buffer ...

这跟你函数形参有关系。形参里没写const,是u8 *,你定义的是const u8类型数组的话,就得跟形参类型匹配。
你把函数形参改成const u8 *类型看看。

小小蜗牛
回复

使用道具 举报

34

主题

805

帖子

4

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1863
金钱
1863
注册时间
2011-3-29
在线时间
139 小时
发表于 2016-1-28 11:17:02 来自手机 | 显示全部楼层
q546163199 发表于 2016-1-28 11:09
那为什么去掉const的话,(u8*)TEXT_Buffer就可以在函数调用的时候改成TEXT_Buffer,如果不去掉,就不行 ...

因为你函数的形参和实参不一致啊。强制类型只是掩盖了错误。如果编译器把const数据放在了flash区,你在函数里面修改数据,是可能导致系统异常、fault的。
回复

使用道具 举报

35

主题

193

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
476
金钱
476
注册时间
2015-12-27
在线时间
116 小时
 楼主| 发表于 2016-1-28 11:22:52 | 显示全部楼层
jiutianshenjian 发表于 2016-1-28 11:16
这跟你函数形参有关系。形参里没写const,是u8 *,你定义的是const u8类型数组的话,就得跟形参类型匹配。 ...

改了的话,错误提示更大,
回复

使用道具 举报

35

主题

193

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
476
金钱
476
注册时间
2015-12-27
在线时间
116 小时
 楼主| 发表于 2016-1-28 11:43:10 | 显示全部楼层
ofourme 发表于 2016-1-28 11:17
因为你函数的形参和实参不一致啊。强制类型只是掩盖了错误。如果编译器把const数据放在了flash区,你在函 ...

那是不是可以理解成,如果不去掉const的话,,TEXT_Buffer是一个指向const u8型数组的指针,而函数的入口参数需要一个指向u8型数组的指针,所以必须将TEXT_Buffer强制转化为,一个指向u8型数组的指针,对吧?

如果去掉const的话,TEXT_Buffer表示一个指向 u8型数组的指针,所以在函数调用的时候,就可以直接写成TEXT_Buffer,我这样理解对吗?
回复

使用道具 举报

35

主题

193

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
476
金钱
476
注册时间
2015-12-27
在线时间
116 小时
 楼主| 发表于 2016-1-28 11:44:50 | 显示全部楼层
jiutianshenjian 发表于 2016-1-28 11:16
这跟你函数形参有关系。形参里没写const,是u8 *,你定义的是const u8类型数组的话,就得跟形参类型匹配。 ...

我改了之后,发现,函数形参,改不成const u8*pBuffer的形式,一改,就发生错误
回复

使用道具 举报

35

主题

193

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
476
金钱
476
注册时间
2015-12-27
在线时间
116 小时
 楼主| 发表于 2016-1-28 11:47:14 | 显示全部楼层
ofourme 发表于 2016-1-28 11:17
因为你函数的形参和实参不一致啊。强制类型只是掩盖了错误。如果编译器把const数据放在了flash区,你在函 ...


我把这个const问题总结下

如果不去掉const的话,,TEXT_Buffer是一个指向const u8型数组的指针,而函数的入口参数需要一个指向u8型数组的指针,所以必须将TEXT_Buffer强制转化为,一个指向u8型数组的指针

如果去掉const的话,TEXT_Buffer表示一个指向u8型数组的指针,所以在函数调用的时候,就可以直接写成TEXT_Buffer
应该就是这个意思了吧?
回复

使用道具 举报

35

主题

193

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
476
金钱
476
注册时间
2015-12-27
在线时间
116 小时
 楼主| 发表于 2016-1-28 11:47:30 | 显示全部楼层
jiutianshenjian 发表于 2016-1-28 11:16
这跟你函数形参有关系。形参里没写const,是u8 *,你定义的是const u8类型数组的话,就得跟形参类型匹配。 ...

我把这个const问题总结下

如果不去掉const的话,,TEXT_Buffer是一个指向const u8型数组的指针,而函数的入口参数需要一个指向u8型数组的指针,所以必须将TEXT_Buffer强制转化为,一个指向u8型数组的指针

如果去掉const的话,TEXT_Buffer表示一个指向u8型数组的指针,所以在函数调用的时候,就可以直接写成TEXT_Buffer
应该就是这个意思了吧?
回复

使用道具 举报

34

主题

805

帖子

4

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1863
金钱
1863
注册时间
2011-3-29
在线时间
139 小时
发表于 2016-1-28 11:50:13 来自手机 | 显示全部楼层
q546163199 发表于 2016-1-28 11:43
那是不是可以理解成,如果不去掉const的话,,TEXT_Buffer是一个指向const u8型数组的指针,而函数的入口 ...

是的。
回复

使用道具 举报

81

主题

1002

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1876
金钱
1876
注册时间
2014-9-10
在线时间
208 小时
发表于 2016-1-28 11:52:28 | 显示全部楼层
q546163199 发表于 2016-1-28 11:47
我把这个const问题总结下

如果不去掉const的话,,TEXT_Buffer是一个指向const u8型数组的指针,而函 ...

不知道,没看到你的函数。
你的数组定义,看起来是字符串,但却加了个大括号,不太常见。
小小蜗牛
回复

使用道具 举报

35

主题

193

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
476
金钱
476
注册时间
2015-12-27
在线时间
116 小时
 楼主| 发表于 2016-1-28 11:54:24 | 显示全部楼层
jiutianshenjian 发表于 2016-1-28 11:52
不知道,没看到你的函数。
你的数组定义,看起来是字符串,但却加了个大括号,不太常见。

这就是字符数组的定义规则啊,我在C语言书上看到的,实际上也可以将大括号去掉的,写成
const u8 TEXT_Buffer[]="!Good Luck to My Father!";这个形式的
回复

使用道具 举报

34

主题

805

帖子

4

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1863
金钱
1863
注册时间
2011-3-29
在线时间
139 小时
发表于 2016-1-28 11:59:04 来自手机 | 显示全部楼层
q546163199 发表于 2016-1-28 11:22
改了的话,错误提示更大,

函数声明与定义不一致导致的吧?或者你在函数里面修改了const数据?
回复

使用道具 举报

35

主题

193

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
476
金钱
476
注册时间
2015-12-27
在线时间
116 小时
 楼主| 发表于 2016-1-28 11:59:46 | 显示全部楼层
ofourme 发表于 2016-1-28 11:59
函数声明与定义不一致导致的吧?或者你在函数里面修改了const数据?

const u8 TEXT_Buffer[]={"Explorer STM32F4 IIC TEST"};
我的意思是对于这个字符数组来说,TEXT_Buffer表示为一个指向const u8型数组的指针,对吧?
而如果去掉const的话,TEXT_Buffer表示为一个指向u8型数组的指针,对吧?
回复

使用道具 举报

34

主题

805

帖子

4

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1863
金钱
1863
注册时间
2011-3-29
在线时间
139 小时
发表于 2016-1-28 19:20:04 | 显示全部楼层
q546163199 发表于 2016-1-28 11:59
const u8 TEXT_Buffer[]={"Explorer STM32F4 IIC TEST"};
我的意思是对于这个字符数组来说,TEXT_Buffer ...

17楼已经回答过你的问题了。
业余程序玩家。
回复

使用道具 举报

1

主题

93

帖子

0

精华

初级会员

Rank: 2

积分
194
金钱
194
注册时间
2014-3-12
在线时间
9 小时
发表于 2016-2-3 08:51:19 | 显示全部楼层
加const你这段数据就存在flash,不加const这段数据就存在ram。如果数据无需修改,建议放到flash,这样可以节省ram。
回复

使用道具 举报

1

主题

93

帖子

0

精华

初级会员

Rank: 2

积分
194
金钱
194
注册时间
2014-3-12
在线时间
9 小时
发表于 2016-2-3 08:53:28 | 显示全部楼层
jiutianshenjian 发表于 2016-1-28 10:36
const是放在flash中吗?我觉得跟存储没关系,加不加都是一个地方。没看到有说放在flash中的资料。
C语言里 ...

你可以尝试着把一段数据加const与不加const进行编译,然后对比两者生成的flash、RAM大小。你会发现const是存储在flash的!
功夫再高、也怕羊刀
回复

使用道具 举报

35

主题

193

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
476
金钱
476
注册时间
2015-12-27
在线时间
116 小时
 楼主| 发表于 2016-2-3 12:03:31 | 显示全部楼层
加速度 发表于 2016-2-3 08:53
你可以尝试着把一段数据加const与不加const进行编译,然后对比两者生成的flash、RAM大小。你会发现const ...

好主意,多谢了啊,哈哈
回复

使用道具 举报

81

主题

1002

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1876
金钱
1876
注册时间
2014-9-10
在线时间
208 小时
发表于 2016-2-18 09:02:08 | 显示全部楼层
加速度 发表于 2016-2-3 08:53
你可以尝试着把一段数据加const与不加const进行编译,然后对比两者生成的flash、RAM大小。你会发现const ...

怎么看生成的flash和ram大小
小小蜗牛
回复

使用道具 举报

35

主题

193

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
476
金钱
476
注册时间
2015-12-27
在线时间
116 小时
 楼主| 发表于 2016-2-20 22:00:15 | 显示全部楼层
恩恩,知道了,谢谢原子哥了
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2024-9-29 07:27

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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