如何检查“设置”是否已设置在c中

发布于 2024-09-17 11:39:57 字数 321 浏览 7 评论 0原文

如果我像这样分配一个 C 数组:

int array[ 5 ];

然后,仅设置一个对象:

array[ 0 ] = 7;

如何检查所有其他键( array[1]array[2]、 ...)正在存储一个值? (当然,在本例中,它们不是。)

是否有类似 PHP 的 isset() 的函数?

if ( isset(array[ 1 ]) ) ...

If I allocate a C array like this:

int array[ 5 ];

Then, set only one object:

array[ 0 ] = 7;

How can I check whether all the other keys ( array[1], array[2], …) are storing a value? (In this case, of course, they aren't.)

Is there a function like PHP's isset()?

if ( isset(array[ 1 ]) ) ...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

二智少女 2024-09-24 11:39:58

我喜欢的一种方法是创建 2 个数组,一个是位数组,标记设置了数组的索引,另一个包含实际值。即使在您不需要知道数组中的某个项目是否已“设置”的情况下,它也可能是一种有用的优化。将每个元素 1 位的位数组清零比初始化 size_t 每个元素 8 字节的数组要快得多,特别是当数组在整个数组中保持稀疏(大部分未填充)时寿命。

我使用这一技巧的一个实际例子是在子字符串搜索函数中,使用 Boyer-Moore 风格的坏字符跳过表。该表需要256个size_t类型的条目,但只需要填写与实际出现在针串中的字符对应的条目。在非常短的搜索情况下,1kb(或 64 位上的 2kb)memset 将主导 CPU 使用率,导致其他实现在是否使用该表时采用启发式方法。但相反,我让跳过表未初始化,并使用 256 位位数组(仅 32 字节提供给 memset)来标记哪些条目正在使用。

An approach I like is to make 2 arrays, one a bit-array flagging which indices of the array are set, and the other containing the actual values. Even in cases where you don't need to know whether an item in the array is "set" or not, it can be a useful optimization. Zeroing a 1-bit-per-element bit array is a lot faster than initializing an 8-byte-per-element array of size_t, especially if the array will remain sparse (mostly unfilled) for its entire lifetime.

One practical example where I used this trick is in a substring search function, using a Boyer-Moore-style bad-character skip table. The table requires 256 entries of type size_t, but only the ones corresponding to characters which actually appear in the needle string need to be filled. A 1kb (or 2kb on 64-bit) memset would dominate cpu usage in the case of very short searches, leading other implementations to throw around heuristics for whether or not to use the table. But instead, I let the skip table go uninitialized, and used a 256-bit bit array (only 32 bytes to feed to memset) to flag which entries are in use.

勿忘初心 2024-09-24 11:39:57

C 中没有这样的事情。静态数组的内容始终是“设置”的。但是,您可以填写一些特殊值来假装它未初始化,例如

// make sure this value isn't really used.
#define UNINITIALIZED 0xcdcdcdcd

int array[5] = {UNINITIALIZED, UNINITIALIZED, UNINITIALIZED, UNINITIALIZED, UNINITIALIZED};

array[0] = 7;

if (array[1] != UNINITIALIZED) {
   ...

There isn't things like this in C. A static array's content is always "set". You could, however, fill in some special value to pretend it is uninitialized, e.g.

// make sure this value isn't really used.
#define UNINITIALIZED 0xcdcdcdcd

int array[5] = {UNINITIALIZED, UNINITIALIZED, UNINITIALIZED, UNINITIALIZED, UNINITIALIZED};

array[0] = 7;

if (array[1] != UNINITIALIZED) {
   ...
阳光的暖冬 2024-09-24 11:39:57

你不能

这些值都是未定义的(因此是随机的)。

您可以明确地将所有值归零以开始,这样您至少有一个良好的起点。但是使用幻数来检测对象是否已初始化被认为是不好的做法(但初始化变量被认为是好的做法)。

int array[ 5 ] = {};

但是,如果您想显式检查它们自创建以来是否已显式设置(不使用幻数),您需要将该信息存储在另一个结构中。

int array[ 5 ]   = {};  // Init all to 0
int isSet[ 5 ]   = {};  // Init all to 0 (false)

int getVal(int index)          {return array[index];}
int isSet(int index)           {return isSet[index];}
void setVal(int index,int val) {array[index] = val; isSet[index] = 1; }

You can't

There values are all undefined (thus random).

You could explicitly zero out all values to start with so you at least have a good starting point. But using magic numbers to detect if an object has been initialized is considered bad practice (but initializing variables is considered good practice).

int array[ 5 ] = {};

But if you want to explicitly check if they have been explicitly set (without using magic numbers) since creation you need to store that information in another structure.

int array[ 5 ]   = {};  // Init all to 0
int isSet[ 5 ]   = {};  // Init all to 0 (false)

int getVal(int index)          {return array[index];}
int isSet(int index)           {return isSet[index];}
void setVal(int index,int val) {array[index] = val; isSet[index] = 1; }
榆西 2024-09-24 11:39:57

在 C 中,所有元素在分配时都会有值(垃圾)。所以你不能真正拥有你所要求的功能。

但是,默认情况下,您可以使用 memset() 用一些标准值(例如 0 或 INT_MIN)填充它,然后编写 isset() 代码。

In C, all the elements will have values (garbage) at the time of allocation. So you cannot really have a function like what you are asking for.

However, you can by default fill it up with some standard values like 0 or INT_MIN using memset() and then write an isset() code.

终止放荡 2024-09-24 11:39:57

我不知道 php,但这里发生了两件事之一

  • php 数组实际上是一个哈希映射(awk 就是这样做的)
  • php 数组被填充为可空类型

,无论哪种情况,都有一个有意义的概念“不” set”作为数组的值。另一方面,内置类型的 ac 数组在每个单元格中始终具有一些值。如果数组未初始化并且是自动的或者是在堆上分配的,那么这些值可能是随机的,但它们存在。

要获得 php 行为:

  • 实现(或找到一个库)并在数组上使用 hashmap。
  • 使其成为包含 isNull 字段的结构数组。
  • 将数组的所有单元格初始化为某个哨兵值。

I don't know php, but one of two things is going on here

  • the php array is actually a hash-map (awk does that)
  • the php array is being filled with nullable types

in either case there is a meaningful concept of "not set" for the values of the array. On the other hand a c array of built in type has some value in every cell at all times. If the array is uninitialized and is automatic or was allocated on the heap those values may be random, but they exist.

To get the php behavior:

  • Implement (or find a library wit) and use a hashmap instead on an array.
  • Make it an array of structures which include an isNull field.
  • Initialize the array to some sentinal value in all cells.
伊面 2024-09-24 11:39:57

一种解决方案可能是使用单独的标志数组。当您分配其中一个元素时,请在布尔数组中设置标志。

您还可以使用指针。您可以使用空指针来表示尚未分配的数据。我在下面做了一个例子:

int * p_array[3] = {NULL,NULL,NULL};
        p_array[0] = malloc(sizeof(int));
        *p_array[0] = (int)0;
        p_array[2] = malloc(sizeof(int));
        *p_array[2] = (int)4;
        for (int x = 0; x < 3; x++) {
            if (p_array[x] != NULL) {
                printf("Element at %i is assigned and the value is %i\n",x,*p_array[x]);
            }else{
                printf("Element at %i is not assigned.\n",x);
            }
        }

您可以创建一个分配内存并设置数据的函数,以及另一个与 PHP 中的 isset 函数类似的函数,通过为您测试 NULL 来实现。

我希望这对你有帮助。

编辑:确保完成后释放内存。另一个函数可用于释放某些元素或整个数组。

我之前使用过 NULL 指针来表示数据尚未创建或需要重新创建。

One solution perhaps is to use a separate array of flags. When you assign one of the elements, set the flag in the boolean array.

You can also use pointers. You can use null pointers to represent data which has not been assigned yet. I made an example below:

int * p_array[3] = {NULL,NULL,NULL};
        p_array[0] = malloc(sizeof(int));
        *p_array[0] = (int)0;
        p_array[2] = malloc(sizeof(int));
        *p_array[2] = (int)4;
        for (int x = 0; x < 3; x++) {
            if (p_array[x] != NULL) {
                printf("Element at %i is assigned and the value is %i\n",x,*p_array[x]);
            }else{
                printf("Element at %i is not assigned.\n",x);
            }
        }

You could make a function which allocates the memory and sets the data and another function which works like the isset function in PHP by testing for NULL for you.

I hope that helps you.

Edit: Make sure the memory is deallocated once you have finished. Another function could be used to deallocate certain elements or the entire array.

I've used NULL pointers before to signify data has not been created yet or needs to be recreated.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文