Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C语言中缓冲区数组的使用_C_Arrays - Fatal编程技术网

C语言中缓冲区数组的使用

C语言中缓冲区数组的使用,c,arrays,C,Arrays,我的想法告诉我这里有一些错误,比如我可能无法将值附加到数组中的最后一个元素,或者在执行cbuf_length++和崩溃时它将超过UINT8?我的头脑认为有什么不对劲,但我就是看不出是什么。使用数组的最佳方式是什么,它允许我在数组中添加所有256个元素,而不会使下一个程序员崩溃或困惑 #define CBUF_SIZE 256 static UINT8 cbuf[CBUF_SIZE]; static UINT8 cbuf_length; void CBUF_AppendChar(char c)

我的想法告诉我这里有一些错误,比如我可能无法将值附加到数组中的最后一个元素,或者在执行cbuf_length++和崩溃时它将超过UINT8?我的头脑认为有什么不对劲,但我就是看不出是什么。使用数组的最佳方式是什么,它允许我在数组中添加所有256个元素,而不会使下一个程序员崩溃或困惑

#define CBUF_SIZE 256 
static UINT8 cbuf[CBUF_SIZE];
static UINT8 cbuf_length;

void CBUF_AppendChar(char c)
{
    if (cbuf_length < CBUF_SIZE) { 
        cbuf[cbuf_length] = c;
        cbuf_length++;
    }
}

唯一的错误是cbuf_length的类型-255之后,它将溢出到0。将其定义为更大的类型UINT16,甚至是不带符号的类型都可以修复它


除此之外,它是完全有效和可理解的代码。不过,您可能希望从该函数返回一些内容—一些布尔结果告诉调用方值是否已成功追加。

唯一的错误是cbuf_长度的类型—在255之后,它将溢出为0。将其定义为更大的类型UINT16,甚至是不带符号的类型都可以修复它


除此之外,它是完全有效和可理解的代码。不过,您可能希望从该函数返回一些内容—一些布尔结果告诉调用方是否成功追加了值。

首先,您的代码存在一些问题

UINT8不是标准类型,我怀疑它是Microsoft类型。除非你有充分的理由

其次,cbuf_length
test.c:10:21: warning: comparison of constant 256 with expression of type 'uint8_t'
      (aka 'unsigned char') is always true [-Wtautological-constant-out-of-range-compare]
    if (cbuf_length < CBUF_SIZE) { 
        ~~~~~~~~~~~ ^ ~~~~~~~~~
有关缓冲区的所有信息都收集在一个结构中。现在很明显,cbuf_append对buf有效。如果愿意,您可以有多个缓冲区

如果您真的想要一个静态分配的缓冲区,稍微修改一下,您就可以选择控制内存分配

cbuf *cbuf_new_from_buf( uint8_t *buf, size_t capacity ) {
    cbuf *self = malloc( sizeof(cbuf) );
    self->size = 0;
    self->capacity = capacity;
    self->buf = buf;

    bzero( self->buf, self->capacity );

    return self;
}

cbuf *cbuf_new( size_t capacity ) {
    return cbuf_new_from_buf(
        malloc( capacity * sizeof(uint8_t) ),
        capacity
    );
}
现在您仍然可以使用cbuf_new,让它为您分配内存。或者您可以使用cbuf_new_from_buf来使用已经分配的现有缓冲区

uint8_t mybuf[2];
cbuf *buf = cbuf_new_from_buf(mybuf, sizeof(mybuf));
但是你不应该自己写缓冲区! 这对于学习练习来说是很好的。但在生产环境中,如果您只想添加一个大小合适的数组,那么就不要编写一堆代码,您或其他人将不得不记录、维护、测试、修复并向其中添加功能。使用现有库。喜欢它可以满足你的需要,甚至更多

#include <glib.h>
#include <stdio.h>
#include <stdint.h>

int main(void) {
    // Start with a size 2 buffer, it will grow as needed.
    GArray *buf = g_array_sized_new(FALSE, FALSE, sizeof(uint8_t), 2);

    uint8_t c = 'f';
    g_array_append_val(buf, c);
    c = 'o';
    g_array_append_val(buf, c);
    c = 'o';
    g_array_append_val(buf, c); // It will grow the buffer.

    for( guint i = 0; i < buf->len; i++ ) {
        printf("%c", g_array_index(buf, uint8_t, i));
    }
    puts("");
}
虽然GArray有一些怪癖,比如不能附加文字,但它有很好的文档记录,功能强大,速度快。这意味着您可以将时间花在真正的代码上,而不是基本的数据结构上


更好的是,如果需要,数组将增长,因此不会出现缓冲区溢出,也不需要检查追加是否成功。您最初对缓冲区大小的担心已经消除,缓冲区将根据需要增长。

首先,您的代码存在一些问题

UINT8不是标准类型,我怀疑它是Microsoft类型。除非你有充分的理由

其次,cbuf_length
test.c:10:21: warning: comparison of constant 256 with expression of type 'uint8_t'
      (aka 'unsigned char') is always true [-Wtautological-constant-out-of-range-compare]
    if (cbuf_length < CBUF_SIZE) { 
        ~~~~~~~~~~~ ^ ~~~~~~~~~
有关缓冲区的所有信息都收集在一个结构中。现在很明显,cbuf_append对buf有效。如果愿意,您可以有多个缓冲区

如果您真的想要一个静态分配的缓冲区,稍微修改一下,您就可以选择控制内存分配

cbuf *cbuf_new_from_buf( uint8_t *buf, size_t capacity ) {
    cbuf *self = malloc( sizeof(cbuf) );
    self->size = 0;
    self->capacity = capacity;
    self->buf = buf;

    bzero( self->buf, self->capacity );

    return self;
}

cbuf *cbuf_new( size_t capacity ) {
    return cbuf_new_from_buf(
        malloc( capacity * sizeof(uint8_t) ),
        capacity
    );
}
现在您仍然可以使用cbuf_new,让它为您分配内存。或者您可以使用cbuf_new_from_buf来使用已经分配的现有缓冲区

uint8_t mybuf[2];
cbuf *buf = cbuf_new_from_buf(mybuf, sizeof(mybuf));
但是你不应该自己写缓冲区! 这对于学习练习来说是很好的。但在生产环境中,如果您只想添加一个大小合适的数组,那么就不要编写一堆代码,您或其他人将不得不记录、维护、测试、修复并向其中添加功能。使用现有库。喜欢它可以满足你的需要,甚至更多

#include <glib.h>
#include <stdio.h>
#include <stdint.h>

int main(void) {
    // Start with a size 2 buffer, it will grow as needed.
    GArray *buf = g_array_sized_new(FALSE, FALSE, sizeof(uint8_t), 2);

    uint8_t c = 'f';
    g_array_append_val(buf, c);
    c = 'o';
    g_array_append_val(buf, c);
    c = 'o';
    g_array_append_val(buf, c); // It will grow the buffer.

    for( guint i = 0; i < buf->len; i++ ) {
        printf("%c", g_array_index(buf, uint8_t, i));
    }
    puts("");
}
虽然GArray有一些怪癖,比如不能附加文字,但它有很好的文档记录,功能强大,速度快。这意味着您可以将时间花在真正的代码上,而不是基本的数据结构上


更好的是,如果需要,数组将增长,因此不会出现缓冲区溢出,也不需要检查追加是否成功。您最初对缓冲区大小的担心已经消除,缓冲区将根据需要增长。

这是有效的代码,但不合理的功能,因为缓冲区空和缓冲区满都是cbuf_长度==0.UINT8对于cbuf_长度来说太小了,它只能存储0-255。谢谢chux,我不知道UINT8255++会返回到0 Hanks Sister Fister,因此UINT8中基本上有256个值,但不能使用其中的1个,因为在这种情况下它被用作空标志。知道了!很高兴知道。这是有效的代码,但不合理的功能,因为缓冲区空和缓冲区满都是cbuf_length==0。UINT8对于cbuf_length来说太小了,它只能存储0-255。多亏了chux,我不知道UINT8255++会回到0的姐妹Fister,所以我基本上有256个值
n UINT8,但不能使用其中的1个,因为在这种情况下它用作空标志。知道了!很高兴知道。对于内存有限的系统上的glib,唯一要注意的是glib在初始化时可能会消耗相当多的内存,并且在初始分配方面非常自由。这不是一件坏事,对于那些在嵌入式系统上工作的人来说,这可能是一个惊喜,或者是在超高速硅管道上工作的内存很少的东西,比如树莓,等等,需要考虑热因素,静态缓冲区可能是合适的。一些系统使用types.h代替ifndef types\u h define types\u h typedef unsigned long UINT32;typedef无符号短UINT16;typedef无符号字符UINT8;typedef签名长INT32;typedef签名短INT16;typedef签名字符INT8;typedef无符号字符库;定义真1定义假0endif@hamishh是不可移植的,POSIX sys/types.h没有定义UINT8。除非您另有特殊原因,否则如果有符合标准的选项,最好使用它以实现可移植性和可读性。如果你正在研究超高速硅管,考虑到热因素,或者是一个内存受限的系统,这是一个非常特殊的情况,这将是一个很有用的背景来补充你的问题。否则,请使用良好的实践。虽然GLib可能不合适,但您可以使用类似于my struct code的静态缓冲区,甚至是静态结构(如果需要)。在内存有限的系统上使用GLib时,唯一需要注意的是GLib在初始化时可能会消耗相当多的内存,并且在初始分配时特别自由。这不是一件坏事,对于那些在嵌入式系统上工作的人来说,这可能是一个惊喜,或者是在超高速硅管道上工作的内存很少的东西,比如树莓,等等,需要考虑热因素,静态缓冲区可能是合适的。一些系统使用types.h代替ifndef types\u h define types\u h typedef unsigned long UINT32;typedef无符号短UINT16;typedef无符号字符UINT8;typedef签名长INT32;typedef签名短INT16;typedef签名字符INT8;typedef无符号字符库;定义真1定义假0endif@hamishh是不可移植的,POSIX sys/types.h没有定义UINT8。除非您另有特殊原因,否则如果有符合标准的选项,最好使用它以实现可移植性和可读性。如果你正在研究超高速硅管,考虑到热因素,或者是一个内存受限的系统,这是一个非常特殊的情况,这将是一个很有用的背景来补充你的问题。否则,请使用良好的实践。虽然GLib可能不合适,但您可以使用类似于my struct代码的静态缓冲区,如果需要,甚至可以使用静态结构。