数组的第一个元素不为空,指针取消引用

First Element of array not empty, pointer dereference

我正在为微控制器编写代码。

到目前为止我有以下示例:

// 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。

我这里的错误是什么?对指针很陌生,所以我不知道这是否是问题所在。

主要问题很可能是这个:

printf(*ptr_weekly_table);

表达式 *ptr_weekly_table 一个 uint32_t 值。不是 printf expects. Because you in effect pass a null pointer (since ptr_weekly_table[0] is supposedly zero) then you will ask printf to print whatever "string" is at location zero, and that will lead to undefined behavior.

的字符串 (char *)

要打印正确的值,请使用

printf("%"PRIu32"\n", ptr_weekly_table[0]);

参见例如this format specifier macro reference 获取有关 PRIu32.

的信息

如您所见,我使用 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](少写几个字符,而且通常更易读)。

对于初学者这些声明

const int _num_weekly_table = _rows * _cols;
uint32_t weekly_table[_rows][_cols];

如果它们是全局命名空间中的声明则无效,因为 1) 您不能使用 non-constant 表达式初始化具有静态存储持续时间的变量,并且 2) 您不能使用静态声明可变长度数组存储期限。

您似乎是将程序编译为 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;