What is the difference between float[] and float*?
Also, how can I convert a float array to float *? I need to get a float * and open it, then apply a filter and send it as a float * into my FFT method, but I don't know how to do it because I don't know the real difference between them.
An array usually is a pointer to the first member of the list. When using Array[Identifier], you are accessing to *(p+Identifier).
Making a new array will define a series of pointer next to another, which will make it's use way easier.
You can set your float array in the following ways:
float array1[100] = { 0 };
float *dataArray = (float*)malloc(sizeof(float) * 100);
float *pointerToFloatArray = array1;
These points all relate to C:
the name of an array can be decomposed — i.e. implicitly converted — to a pointer to its first element;
in an array, elements are stored contiguously;
the syntax a[8] is just shorthand for *(a + 8); and
adding n to a pointer, p, is defined to add n * sizeof(*p).
So an array differs from a pointer by being a semantically different thing. But you can supply the name of an array anywhere a pointer is required as it'll be converted.
Separately, you can also add an offset to any pointer using subscript syntax.
Objective-C is a strict superset of C. So these rules also apply to the use of the primitive types in Objective-C.
To understand the distinction, think in terms of mutability. The following is invalid:
char array[];
char value;
array = &value;
You can't reassign array. It is the name of an array. array itself is not mutable at runtime, only the things within it are. Conversely the following is valid:
char *pointer;
char value;
pointer = &value;
You can reassign pointer as often as you like. There's a mutable pointer and you can use it to point to anything.
You can use C-style arrays, like described in this answer: https://stackoverflow.com/a/26263070/3399208,
but better way - is using Objective-C containers and Objective-C objects, for example NSNumber * :
NSArray *array = [#1, #2, #3];
or
NSMutableArray *array = [NSMutableArray array];
NSNumber *number1 = [NSNumber numberWithFloat:20.f];
NSNumber *number2 = #(20.f);
[array addObject:number1];
[array addObject:number2];
Related
while adding a integer to object at index of an array, I am getting an error of "arithmetic on pointer to interface id which is not a constant size for this architecture and platform", didn't know how to resolve it.
Please help.
my code is -
if (arrayTotalAmount.count>0) {
int sum = 0;
for (int i = 0; i<=arrayTotalAmount.count; i++) {
sum = (sum+[arrayTotalAmount objectAtIndex:i]);
}
In 4th line I am getting that error.
Thanks
Objective C array only accepts NSObject type. That means it is impossible to insert a primitive value into an NSArray. You are getting an error because objectAtIndex method returns a pointer which points to that NSObject, the arithmetic operations are still valid on pointers but the thing is that the size of a pointer as integer (32bit, 64bit) may differ on device. So one of the solution is typecasting the pointer sum+(int)[arrayTotalAmount objectAtIndex:i] which makes no sense in your case.
The solution you are looking for is probably sum+[[arrayTotalAmount objectAtIndex:i] intValue] or similar. Assuming that array contains NSNumber objects. If the object inside an array is not an NSNumber then your app will fail in runtime showing an error indicating that an object X does not have a method called intValue in which case you will need to figure how to convert object X to your int.
You just need to convert your array object to integer and then add it will work for you.
if (arrayTotalAmount.count>0) {
int sum = 0;
for (int i = 0; i<=arrayTotalAmount.count; i++) {
sum = (sum+[[arrayTotalAmount objectAtIndex:i] intValue]);
}
I had a NSDictionary contains 2 key/value pairs:
NSDictionary *dic = #{#"tag":#2, //NSNumber
#"string":#"someString"}; //NSString
NSLog(#"%i",(int)[dic objectForKey:#"tag"]); //print out 34
NSLog(#"%i",[dic objectForKey:#"tag"] intValue]); //print out 2
Why does "converting id value to int with (int)"get me the wrong result but not the other way? are they in different levels of conversion?
Why does "converting id value to int with (int)"get me the wrong result but not the other way? are they in different levels of conversion?
id is a pointer type. id pointers point to Objective-C objects in memory. By casting id to (int), you are merely reinterpreting (some of) the pointer's bit pattern as an int, which is quite meaningless. You have to call the proper conversion methods of NSString and NSNumber if you want to reliably get the primitive values out of the Objective-C object.
If you ever seemingly get the "correct" value of 2 in the case of pointer-casting with NSNumber, that may be because the Objective-C runtime makes use of an optimization technique called tagged pointers, whereby small objects are not really created and allocated, but their semantics (the number's bits which the NSNumber object stores) is stuffed into the unused bits of the pointer.
#2 is not an int but a NSNumber you can't cast an NSNumber into an int. You have to use intValue method to get the correct result.
The method objectForKey: returns a pointer to the NSNumber object #2, not the value stored in the object itself. So you're typecasting the pointer, not the value 2. In the last line you don't typecast the object but you access a property called intValue which returns the value of the object expressed as an int.
NSDictionary contains Object with Key value pairs,but you passed int(#2) into object
NSDictionary *dic = #{#"tag":#2, //NSNumber
#"string":#"someString"};
so Change int to NSNumber like
NSDictionary *dic = #{#"tag":[NSNumber numberWithInt:2];,#"string":#"someString"};
and you can get it..
int number = [[dict objectForKey:#"tag"] intValue];
When I do an operation like this:
self.slider.value = randomArray[0][0];
I would like to be able to do this:
self.slider.value = randomArray[randomVariable][0];
Basically, how do you put that "randomVariable" in the brackets? When I try to do this on Xcode, I get:
Code: self.detail1.text = detailsForNotesUse[x][0];
Error:Expected Method to read dictionary element not found in object
of type 'NSArray *'
The variable I put in the brackets is NSString, the array is NSArray, and detail1 is a text field.
Declarations:
NSString *x = 0;
NSArray *detailsForNotesUse;
You've defined x as an NSString. You should define your index variable like this:
NSUInteger x = 0;
I'm just reposting the answer I gave in my comment below the question:
x needs to be an int if you're using it as an index. ex. int x = 0;
But I'm also writing to note that many of the answers are misleading. You can in fact access a nested array in this way, i.e. randomArray[x][y];, because if randomArray[x] returns an array (as is syntactically valid in obj-c), the items of that array can then be similarly accessed by appending [y] (though you may have to cast randomArray[x] to an NSArray to prevent a warning).
So I have a basic array:
NSMutableArray *answerButtonsArrayWithURL = [NSMutableArray arrayWithObjects:self.playView.coverURL1, self.playView.coverURL2, self.playView.coverURL3, self.playView.coverURL4, nil];
The objects inside are strings. I want to access a random object from that array
int rndValueForURLS = arc4random() % 3;
and assigning it a value. I've tried manny different approaches but my recent one is
[[answerButtonsArrayWithURL objectAtIndex:rndValueForURLS] stringByAppendingString:[self.coverFromRightAnswer objectAtIndex:self.rndValueForQuestions]];
Any help will be much appreciated. Thanks
You need to assign it. You're already building the new value like that:
NSString *oldValue = answerButtonsArrayWithURL[rndValueForURLS];
NSString *newValue = [oldValue stringByAppendingString:[self.coverFromRightAnswer objectAtIndex:self.rndValueForQuestions]];
The part you're missing :
answerButtonsArrayWithURL[rndValueForURLS] = newValue;
Above would be the way to replace the immutable string with another. If the strings are mutable, that is, they were created as NSMutableString, you could do:
NSMutableString *value = answerButtonsArrayWithURL[rndValueForURLS];
[value appendString:[self.coverFromRightAnswer objectAtIndex:self.rndValueForQuestions]];
Note:
Everywhere I replace the notation :
[answerButtonsArrayWithURL objectAtIndex:rndValueForURLS];
with the new equivalent and IMO more readable:
answerButtonsArrayWithURL[rndValueForURLS];
I am trying to store a c-float array in an NSDictionary to use later.
I was initially using an NSArray to store the C-data but NSArray is to slow for my intentions.
I am using the following code to wrap the arrays in the NSDictionary:
[self.m_morphPositions setObject:[NSValue valueWithBytes:&positionBuff objCType:#encode(float[(self.m_countVertices * 3)])] forKey:fourCC];
And retrieving the C-Float array using:
float posMorphs[(self.m_countVertices*3)];
NSValue *posValues = [self.m_morphPositions objectForKey:name];
[posValues getValue:&posMorphs];
When I retireve the array, the values are all set to 0.0 for each index which is wrong.
How can I fix this?
I also think that NSData is probably the best solution here. But just if anybody is interested: You cannot use #encode with a variable sized array, because it is a compiler directive. Therefore
#encode(float[(self.m_countVertices * 3)])
cannot work. Actually the compiler creates the encoding for a float array of size zero here, which explains why you get nothing back when reading the NSValue.
But you can create the type encoding string at runtime. For a float array,
the encoding is [<count>^f] (see Type Encodings), so the following would work:
const char *enc = [[NSString stringWithFormat:#"[%d^f]", (self.m_countVertices * 3)] UTF8String];
NSValue *val = [NSValue valueWithBytes:positionBuff objCType:enc];
NSValue is probably intented for scalar values, not arrays for them. In this case, using NSData should be much easier
NSData* data = [NSData dataWithBytes:&positionBuff length:(self.m_countVertices * 3 * sizeof(float))];
[data getBytes:posMorphs length:(self.m_countVertices * 3 * sizeof(float))];
Another solution is to allocate the array on the heap and use NSValue to store the pointer.
You can feed the bytes into an NSDictionary if they're wrapped in an NSData.
If you want to skip that, you would use an NSMapTable and NSPointerFunctionsOpaqueMemory (or MallocMemory) for the value pointer functions.
I'm not sure if it is the way you are encoding your value, but it might help to encapsulate your array into a struct.
// Put this typedef in a header
typedef struct
{
float values[3];
} PosValues;
In your code:
// store to NSValue
PosValues p1 = { { 1.0, 2.0, 3.0 } };
NSValue *val = [NSValue valueWithBytes:&p1 objCType:#encode(PosValues)];
// retrieve from NSValue
PosValues p2;
[val getValue:&p2];
NSLog(#"%f, %f, %f", p2.values[0], p2.values[1]. p2.values[2]);
The benefit to this approach is that your array is kept as an array type. Also, these structures are assignable even though raw arrays are not:
PosValues p1 = { { 1.0, 2.0, 3.0 } };
PosValues p2;
p2 = p1;