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

时间:2018-04-11 14:06:33

标签: c arrays pointers microcontroller

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

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

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

我的错误是什么?这是一个很新的指针,所以我不知道这是不是问题。

2 个答案:

答案 0 :(得分:1)

主要问题很可能就是这个:

printf(*ptr_weekly_table);

表达式*ptr_weekly_tableuint32_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;