我正在尝试使用C编程语言通过UART发送我的字符串。我是这样做的,将我的角色逐个加载到THR寄存器中:
unsigned char posiljka[] = "Ziga Lausegger";
while(1){
for ( int i = 0 ; i < ( sizeof(posiljka)/sizeof(posiljka[0]) ) ; ++i ){
THR = posiljka[i];
}
这编译并且完全正常。当我将for语句中的<
更改为<=
时,我的程序如下所示:
unsigned char posiljka[] = "Ziga Lausegger";
while(1){
for ( int i = 0 ; i <= ( sizeof(posiljka)/sizeof(posiljka[0]) ) ; ++i ){
THR = posiljka[i];
}
并在编译期间产生警告:
/home/ziga/Dropbox/workspace/mikrokrmilniki/LPC4088/primeri/delujoci/010-uart> make -j2
compiling main.c (gcc)
main.c: In function 'main':
main.c:48:18: warning: iteration 15u invokes undefined behavior [-Waggressive-loop-optimizations]
THR = posiljka[i];
^
main.c:42:3: note: containing loop
for ( int i = 0 ; i <= ( sizeof(posiljka)/sizeof(posiljka[0]) ) ; ++i ){
^
linking executable.elf (gcc)
*****
***** You must modify vector checksum value in *.bin and *.hex files.
*****
arm-none-eabi-size executable.elf
text data bss dec hex filename
26496 188 464 27148 6a0c executable.elf
*** Finished ***
该计划有效,但我仍然想知道这个警告意味着什么?
答案 0 :(得分:2)
在第二种情况下,代码访问posiljka[sizeof(posiljka)/sizeof(posiljka[0])]
,它位于数组范围之外。
在这种情况下,sizeof(posiljka)/sizeof(posiljka[0])
为15
,因此posiljka[15]
是包含空字符的数组元素的一次传递。
该代码&#34;工作&#34;是未定义的行为。
未定义行为的一个有趣方面是,编译器在使用&#34; aggressive-loop-optimizations&#34;时,有时可以检测到这种数组访问。由于它是UB,编译器可以跳过尝试posiljka[15]
(或者它可能不会在星期二。),因此循环比循环少1次迭代。
答案 1 :(得分:1)
数组的最后一个元素是索引sizeof(posiljka)/sizeof(posiljka[0]) - 1
。如果您使用<
更改<=
,请尝试访问循环的最后一次迭代:
THR = posiljka[sizeof(posiljka)/sizeof(posiljka[0])];
是一个超过数组最后一个元素的。访问数组外部的元素会调用未定义的行为,编译器很友好地告诉您。
该计划有效
不,它没有。您的程序是错误的,它可能会在进一步执行时崩溃,或者如果使用不同的编译器进行编译。