Reputation: 3157
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 ]) ) ...
Upvotes: 6
Views: 5857
Reputation: 523244
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) {
...
Upvotes: 7
Reputation: 215221
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.
Upvotes: 1
Reputation: 101181
I don't know php, but one of two things is going on here
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:
Upvotes: 2
Reputation: 5383
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.
Upvotes: 1
Reputation: 264381
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; }
Upvotes: 6
Reputation: 7159
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.
Upvotes: 2