How to Assign a single value to whole NSMutableArray? - iphone

I have an mutable array of say 20 objects. And it has values like #"TRUE",#"FALSE",#"TRUE"...
Now I want to reset the all values of array to #"FALSE". Means array having all values as #"FALSE" (20 times).
I know how to add, insert at index... But I want to know that How can I set whole array value to #"FALSE" in a sing line ??? `without using loop and replace object at index... ?
For example : is it possible
thArray = [[NSMutableArray alloc] initWithCapacity:20];
theArray = #"FALSE" ;
Thanks...

Can you use a C array? If so, you can use {0, 1} as C-equivalents of {FALSE, TRUE}, initializing a C array with:
unsigned short int cArray[20] = {0};
or:
static unsigned short int cArray[20]; /* all values are zeroes, or FALSEs */
This might be more efficient, instead of using an array of static NSString * const elements like you're doing now. Testing whether two integers are equivalent is usually faster than testing lexicographical equivalence of two strings, where your program will have to compare each string character by character.
To reset the contents of the array, you can use the C function memset():
memset(cArray, 0, 20*sizeof(unsigned short int)); /* set all values of cArray to 0 */
If you need a dynamically-sized array, use a pointer with calloc() and reset it with memset() as previously described. Just remember to free() the pointer afterwards, so that you don't get a memory leak:
unsigned short int *cArray = NULL;
size_t cArrayLength = 20; /* can be passed in as a value from another method, etc. */
cArray = calloc(cArrayLength, sizeof(unsigned short int)); /* values are initialized to 0 */
if (cArray) {
/* use cArray... */
*(cArray + 8) = 1; /* e.g., set ninth element with the value of 1 */
/* we don't need cArray any longer, so we free it */
free(cArray);
}
else
/* error */
If you must use Objective-C with NSString * or NSNumber * instances in an NSArray or NSMutableArray, there is no ready-made method for initialization and you'll need to use a loop or copy a pre-existing array, as described in Justin's answer. He is also correct that a method for creating and populating the array is a good idea, if you want to go in this direction.

If those were mutable strings inside the array you could do this in just one line:
[theArray makeObjectsPerformSelector:#selector(setString:) withObject:#"FALSE"];

Here's one way:
NSArray * initialized = ...array with fifty #"FALSE" values...;
NSMutableArray * a = [initialized mutableCopy];
... mutate a ...
[a setArray:initialized];
If you are actually dealing with bool values, C scalars will be faster (see Alex's answer).
Another alternative would be a CFMutableBitVector.
Finally, this would also be a good case for creating a function.

1) Either this
2) Or this
Otherwise without a loop there is no way.

only way i know is
for(int i = 0;i<[theArray count];i++)
{[theArray replaceObjectAtIndex:i withObject:#"FALSE"];}

Related

How to allocate contiguous memory for dynamic multidimensional arrays in SystemVerilog?

Is there a way in SystemVerilog to create a dynamic array that allocates its memory contiguously? I'm trying to read in data from a file into a dynamic array. The problem appears to be that the dynamic array is not in contiguous memory locations, so the file is not read properly into the array.
When I declare the variable reading the file as a non-dynamic array it works fine, so I assume the problem is contiguous memory. Here's the code:
This works fine, but does not use a dynamic array:
// Reads frame from a binary file
task t_Read_File(input string i_File_Name);
int n_Temp[10][10];
int n_File_ID;
n_File_ID = $fopen(i_File_Name, "rb");
$fread(n_Temp, n_File_ID);
$fclose(n_File_ID);
r_Frame = n_Temp;
endtask : t_Read_File
This uses a dynamic array (r_Frame) but does not work
// Reads frame from a binary file
task t_Read_File(input string i_File_Name);
int n_File_ID;
n_File_ID = $fopen(i_File_Name, "rb");
$fread(r_Frame, n_File_ID);
$fclose(n_File_ID);
endtask : t_Read_File
FYI, r_Frame is declared previously as a local variable to my class as follows:
int r_Frame[][];
Using $fread on a dynamic array is an open issue in the standard. It's even more problematic for multi-dimensional dynamic arrays as there is no way to know how to shape the array. To make matters more complicated, SystemVerilog does not really have multi-dimensional array; instead it has arrays of arrays. This means each indexed dimension could have a different size.
You could try allocating the array first, then calling $fread.
r_Frame = new[10];
foreach (r_Frame[i]) r_Frame[i] = new[10];
Here's the solution that I had to end up implementing. Basically I read the text file one line at a time into n_Temp, which was just a large temporary array structure. Then I put it into the multidimensional dynamic array r_Frame one value at a time. Despite previously calling new for r_Frame and setting the dimensions, $fread was not writing the values into r_Frame. I had to go through this extra step using a temporary variable to get it to work. Also I did have to write an endian swap function to convert the little-endian data file to big-endian format.
task t_Read_File(input string i_File_Name);
int n_Temp[5000]; // arbitrary, large
int n_File_ID;
n_File_ID = $fopen(i_File_Name, "rb");
for (int i=0; i<n_Active_Rows; i++)
begin
void'($fread(n_Temp, n_File_ID, , n_Active_Cols));
for (int j=0; j<n_Active_Cols; j++)
r_Frame[i][j] = Sim_Support_Pkg::f_Endian_Swap(n_Temp[j]);
end
$fclose(n_File_ID);
endtask : t_Read_File

store string in char array assignment makes integer from pointer without a cast

#include <stdio.h>
int main(void){
char c[8];
*c = "hello";
printf("%s\n",*c);
return 0;
}
I am learning pointers recently. above code gives me an error - assignment makes integer from pointer without a cast [enabled by default].
I read few post on SO about this error but was not able to fix my code.
i declared c as any array of 8 char, c has address of first element. so if i do *c = "hello", it will store one char in one byte and use as many consequent bytes as needed for other characters in "hello".
Please someone help me identify the issue and help me fix it.
mark
i declared c as any array of 8 char, c has address of first element. - Yes
so if i do *c = "hello", it will store one char in one byte and use as many consequent bytes as needed for other characters in "hello". - No. Value of "hello" (pointer pointing to some static string "hello") will be assigned to *c(1byte). Value of "hello" is a pointer to string, not a string itself.
You need to use strcpy to copy an array of characters to another array of characters.
const char* hellostring = "hello";
char c[8];
*c = hellostring; //Cannot assign pointer to char
c[0] = hellostring; // Same as above
strcpy(c, hellostring); // OK
#include <stdio.h>
int main(void){
char c[8];//creating an array of char
/*
*c stores the address of index 0 i.e. c[0].
Now, the next statement (*c = "hello";)
is trying to assign a string to a char.
actually if you'll read *c as "value at c"(with index 0),
it will be more clearer to you.
to store "hello" to c, simply declare the char c[8] to char *c[8];
i.e. you have to make array of pointers
*/
*c = "hello";
printf("%s\n",*c);
return 0;
}
hope it'll help..:)

objective-c variable length array global scope

is it possible to declare a variable length array with global scope in objective-c?
I'm making a game with a world class, which initializes the world map as a three dimensional integer array. while it's only a two dimensional side scroller, the third dimension of the list states which kinda of block goes at the coordinate given by the first two dimensions
after the initialization function, a method nextFrame: is scheduled (I'm using cocos2d and the CCDirector schedule method). I was wondering how to pass the int[][][] map array from the initialization function to the nextFrame function
I tried using global (static keyword) declaration, but got an error saying that global arrays cannot be variable length
the actual line of code I'm referring to is:
int map[xmax][ymax][3];
where xmax and ymax are the farthest x and y coordinates in the list of coordinates that defines the stage.
I'd like to somehow pass them to nextFrame:, which is scheduled in
[self schedule:#selector(nextFrame:)];
I realize I can use NSMutableArray, but NSMutableArray is kinda a headache for 3-dimensional lists of integers (I have to use wrapper numbers for everything...). is there any way to do this with integer arrays?
You can't have a statically allocated global array of dynamic dimensions in C (of which Objective C is a clean superset). But you can use a global array of any length or size (up to available memory) at runtime by using a global pointer, malloc, and array indexing arithmetic.
static int *map = NULL;
...
map = malloc (dim1 * dim2 * dim3 * sizeof(int)); // in some initialization method
if (map == NULL) { /* handle error */ } // before first array access
...
myElement = map[ index3 + dim2 * ( index2 + dim1 * index1 ) ]; // some macro might be suitable here
Or you could make Objective C getter and setter methods that checks the array and array bounds on every access, since a method can return plain C data types.
Another option, if you know the max dimensions you want to have available and are willing to use (waste) that amount of memory, is to just statically allocate the max array, and throw an exception if the program tries to set up something larger than your allowed max.
I tried using global (static keyword)
declaration, but got an error saying
that global arrays cannot be variable
length
But global array pointers can point to arrays of variable length.

I get incompatible types in the assignment?

int k[4] = {1,2,3,4};
int kk[4];
kk=k;
I get incompatible types in the assignment??
Do I have to loop and assign each value in the array, or is there an easier way?
Thank you
You have to loop, or use a library call.
One option would be memcpy(kk, k, sizeof(k));. For this you must #include <string.h>.
Yes. Arrays don't behave like primitive data types in C. You have to loop over the array and assign each value. You can't just assign one array to another (especially since kk is really an int pointer). Not too hard though:
int i;
for (i = 0; i < 4; i++)
kk[i] = k[i];
There is no copy assignment of good old C arrays. So yes, you have to loop through and copy each element.

Adding integer values as contents of an array,iphone

I need to store some integer values as the contents of an array. But when i try to do so, it throws a warning,
passing argument 1 of 'addObject' makes pointer from integer without a cast.
And obviously the value is not stored in the array.
Here's thecode.
NSUInteger i;
for (i=0;i<5;i++){
[array addObject:i];}
NSArray-s cannot store non-id objects. You have to box it into an NSNumber:
NSUInteger i;
for (i=0;i<5;i++) {
[array addObject:[NSNumber numberWithUnsignedInteger:i]];
}
or use a CFArray with custom callbacks (but you sacrifice readability for performance), or use std::vector<NSUInteger> (but you need to use Objective-C++).