[C语言] 定义变量后是不是默认为0?

[复制链接]
 楼主| any012 发表于 2016-7-15 10:13 | 显示全部楼层 |阅读模式
本帖最后由 any012 于 2016-7-15 10:30 编辑

调试程序遇到问题。
程序走到adcValue[mearChalNum+1] = GetAdcDate();这一步不往下走了。
后来将mearChalNum通过串口输出出来,发现不为0,是个比较大的数,而adcValue[4]只是个存放4个8位数的数组。

mearChalNum是通过函数的参数传递过来的。
void GetTemptValue(u8 mearChalNum)
{
    ...
    adcValue[mearChalNum+1] = GetAdcDate();
    ...
}

而主函数是这样的:
void main()
{
    ...
    u8 ad7193ChalNum;
    ...
    while(1)
   {
    ...
    GetTemptValue(ad7193ChalNum);
    printf("\r\n\r\nad7193ChalNum: %d", ad7193ChalNum);
    ...
    }
}

将主函数里u8 ad7193ChalNum;改成u8 ad7193ChalNum = 0;程序就可正常执行了。

----------------------------------------------------------------

印象中C语言的变量定义后默认是0吧?

 楼主| any012 发表于 2016-7-15 10:16 | 显示全部楼层

proceState: 1

ad7193ChalNum: 134242684

proceState: 2

ad7193ChalNum: 134242684/r/n waitMISOtoLow

未给ad7193ChalNum赋值时,串口输出的数。
mcu5i51 发表于 2016-7-15 10:25 | 显示全部楼层
如果你的变量放在0初始化段上,初次就是0,没有就是一个随机数
 楼主| any012 发表于 2016-7-15 10:26 | 显示全部楼层
mcu5i51 发表于 2016-7-15 10:25
如果你的变量放在0初始化段上,初次就是0,没有就是一个随机数

0初始化段指的是?
mcu5i51 发表于 2016-7-15 10:32 | 显示全部楼层
C编译时初始化数据中的一种,看看编译信息中一般都有"初始化数据"这个段;
你要了解一下RAM上电是不为0的,C的启动代码中没有对所有RAM清零,就算是全部清零了,还有一个变量覆盖技术,在你使用一个变量之前,这个变量地址可能是其它的变量在使用;
oayzw 发表于 2016-7-15 10:34 | 显示全部楼层
c新手吧?请试试
GetTemptValue(&ad7193ChalNum);
 楼主| any012 发表于 2016-7-15 10:41 | 显示全部楼层
本帖最后由 any012 于 2016-7-15 10:47 编辑
oayzw 发表于 2016-7-15 10:34
c新手吧?请试试
GetTemptValue(&ad7193ChalNum);
感谢回复。

ad7193ChalNum这个变量,本意是用来定义芯片内部通道号,其值应该限定在0-3.

不明白为什么要让我GetTemptValue(&ad7193ChalNum)这样尝试呢?
 楼主| any012 发表于 2016-7-15 10:44 | 显示全部楼层
mcu5i51 发表于 2016-7-15 10:32
C编译时初始化数据中的一种,看看编译信息中一般都有"初始化数据"这个段;
你要了解一下RAM上电是不为0的,C的 ...

谢谢你了。
还有疑惑。
RAM不是掉电消失的吗?

反复上电了几次,串口都是输出ad7193ChanlNum为134242684,转为16进制为800617C。
程序里有让ad7193ChalNum不断增1的地方,但一旦大于3就将其清零。其余的地方暂时还没想到有其他地方对其赋值。
oayzw 发表于 2016-7-15 10:50 | 显示全部楼层
非常抱歉,看得不够仔细

void main()
{
    ...
    u8 ad7193ChalNum;
    ...
    while(1)
   {
    ad7193ChalNum++;
ad7193ChalNum &= 3;
    GetTemptValue(ad7193ChalNum);
    printf("\r\n\r\nad7193ChalNum: %d", ad7193ChalNum);
    ...
    }
}
 楼主| any012 发表于 2016-7-15 11:00 | 显示全部楼层
oayzw 发表于 2016-7-15 10:50
非常抱歉,看得不够仔细

void main()

程序里原来有这个变量的自增部分。
只是上电后串口只输出了2次数据就不动了。

感觉好像是这个变量初始值太大,超出了数组的定义范围,程序跑飞了...
JasonWangSE 发表于 2016-7-15 11:24 | 显示全部楼层
未初始化的全局变量是在bss段中,如果系统启动做得好会在启动时将bss段清零,这样没有初始化的全局变量就会是0;函数中的变量是在栈中,如果没有初始化,使用时的值就是不确定的,但好的编译器应该会有告警,可以查一下你编译时的log看是不是有使用未初始化变量的告警
mcu5i51 发表于 2016-7-15 14:25 | 显示全部楼层
回LS:
函数中的变量是在堆栈中,或说在堆中,堆和栈是两个不同的东东,不过多数是一起说的;
玄德 发表于 2016-7-15 15:43 | 显示全部楼层

从来不管默认是多少,
自己初始化就是。

JasonWangSE 发表于 2016-7-15 16:17 | 显示全部楼层
mcu5i51 发表于 2016-7-15 14:25
回LS:
函数中的变量是在堆栈中,或说在堆中,堆和栈是两个不同的东东,不过多数是一起说的; ...

函数中的局部变量是在栈中,不是在堆中;堆是系统用来分配内存的,malloc出来的内存是在堆中
mcu5i51 发表于 2016-7-15 16:33 | 显示全部楼层
JasonWangSE 发表于 2016-7-15 16:17
函数中的局部变量是在栈中,不是在堆中;堆是系统用来分配内存的,malloc出来的内存是在堆中 ...

局部变量多数是在堆中;
堆是编译器分配的一个空间,用于局部变量的动态变量,一定是在用户可操作的内存中的;
栈是硬件操作的内在,用户可能无法直接操作,有些单片机没有SP指针对用户公开;只能对栈用POP,PUSH等指令操作"弹出"和"压入";用户可能不知道栈的地址;
在有多任务的系统中每个任务会有自己的堆栈,可以这样实现的芯片SP是公开的;
在有些MCU中会在突破口中分配少量的局部 变量,可以提高速度和代码效率
mcu5i51 发表于 2016-7-15 16:38 | 显示全部楼层
JasonWangSE 发表于 2016-7-15 16:17
函数中的局部变量是在栈中,不是在堆中;堆是系统用来分配内存的,malloc出来的内存是在堆中 ...

好像没有意义,应用和编译器定的,86芯片中多数连参数都是用的栈,MCU中多数是寄存器或堆(公用变量)
JasonWangSE 发表于 2016-7-15 17:02 | 显示全部楼层
mcu5i51 发表于 2016-7-15 16:33
局部变量多数是在堆中;
堆是编译器分配的一个空间,用于局部变量的动态变量,一定是在用户可操作的内存中的 ...

这段话是哪里写的?是关于什么架构的CPU的,难道跟我们说的堆和栈不是一回事?
datouyuan 发表于 2016-7-15 18:00 | 显示全部楼层
在keil中假如变量定义后,不赋值直接使用,会出现警告.
shcshc1234 发表于 2016-7-15 20:45 | 显示全部楼层
可以认为主函数里的变量默认为0其他函数为随机值
不过为了系统稳定和可读性最好全部赋值初始化
姜Gary 发表于 2016-7-15 21:57 | 显示全部楼层
学学。。。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

35

主题

232

帖子

6

粉丝
快速回复 在线客服 返回列表 返回顶部