我正在为微控制器编写代码。
到目前为止,我有以下示例:
// weekly table[timeslot][day]
const int _rows = 7;
const int _cols = 12;
const int _num_weekly_table = _rows * _cols;
uint32_t weekly_table[_rows][_cols];
// pointer pointing start of array weekly array
uint32_t *ptr_weekly_table = &weekly_table[0][0];
int progress_weekly_table = 0;
bool weekly_table_full = false;
/*
* according to progress_weekly_table save a value in the weekly_table
*/
void append_weekly_table( uint32_t value)
{
//insert element
printf(*ptr_weekly_table);
*(ptr_weekly_table + progress_weekly_table) = value;
//increase progress
progress_weekly_table++;
//if the table is full set flag
if (progress_weekly_table > _num_weekly_table) {
weekly_table_full = true;
}
}
在主循环期间,我运行这一行:
append_weekly_table(1);
但是结果数组没有1作为第一个元素,而是3200171746(可再现)。如果我继续运行append_weekly_array,则数组中的所有其他元素都是1。
我的错误是什么?这是一个很新的指针,所以我不知道这是不是问题。
答案 0 :(得分:1)
主要问题很可能就是这个:
printf(*ptr_weekly_table);
表达式*ptr_weekly_table
和uint32_t
值。不是printf
期望的字符串(char *
)。因为你实际上传递了一个空指针(因为ptr_weekly_table[0]
应该是零),那么你会要求printf
打印任何"字符串"位于零位置,这将导致undefined behavior。
要打印正确的值,请使用
之类的内容printf("%"PRIu32"\n", ptr_weekly_table[0]);
参见例如有关PRIu32
的信息,请this format specifier macro reference。
正如您所看到的,我使用ptr_weekly_table[0]
来获取数组的第一个值。表达式ptr_weekly_table[0]
和*ptr_weekly_table
相同。
事实上,对于任何指针或数组p
和索引i
,表达式p[i]
完全等于*(p + i)
。这意味着*(ptr_weekly_table + progress_weekly_table)
可以写成ptr_weekly_table[progress_weekly_table]
(写入的字符少了几个,而且通常更易读)。
答案 1 :(得分:1)
对于初学者来说这些声明
const int _num_weekly_table = _rows * _cols;
uint32_t weekly_table[_rows][_cols];
如果是全局命名空间中的声明,则它们无效,因为1)您可能不会使用非常量表达式初始化具有静态存储持续时间的变量,并且2)您可能不会使用静态存储持续时间声明可变长度数组。 / p>
您似乎正在将程序编译为C ++程序而不是C程序。
在任何情况下,函数append_weekly_table
都无效。
例如这句话
printf(*ptr_weekly_table);
没有意义,因为函数的第一个参数的类型为const char *
。
int printf(const char * restrict format, ...);
^^^^^^^^^^^^
最初,对象*ptr_weekly_table
具有不确定值(如果程序是C程序且数组没有静态存储持续时间;否则对象初始化为零)。
也是这种情况
if (progress_weekly_table > _num_weekly_table) {
weekly_table_full = true;
}
也是错的。它应该写成
if (progress_weekly_table == _num_weekly_table) {
weekly_table_full = true;
}
如果要将程序编译为C程序,则变量_rows和_cols必须至少声明为
enum { _rows = 7, _cols = 12 };
在变量名中使用前导下划线也是一个坏主意,因为这些名称是由系统保留的。
这是一个可以编译的演示C程序。
#include <stdio.h>
#include <stdbool.h>
#include <stdint.h>
enum { _rows = 7, _cols = 12 };
const int _num_weekly_table = _rows * _cols;
uint32_t weekly_table[_rows][_cols];
// pointer pointing start of array weekly array
uint32_t *ptr_weekly_table = &weekly_table[0][0];
int progress_weekly_table = 0;
bool weekly_table_full = false;
void append_weekly_table( uint32_t value)
{
*(ptr_weekly_table + progress_weekly_table) = value;
//increase progress
progress_weekly_table++;
//if the table is full set flag
if (progress_weekly_table == _num_weekly_table) {
weekly_table_full = true;
}
}
int main(void)
{
append_weekly_table( 1 );
printf( "ptr_weekly_table[0] = %d\n", *ptr_weekly_table );
return 0;
}
程序输出
ptr_weekly_table[0] = 1
您可以替换这两个陈述
*(ptr_weekly_table + progress_weekly_table) = value;
//increase progress
progress_weekly_table++;
//if the table is full set
有一个陈述
ptr_weekly_table[progress_weekly_table++] = value;