Division by defined constant in Obj-C does not work - objective-c

If I write
#define ANOTHER_CONSTANT 200
#define MYDIVISOR 1000/ANOTHER_CONSTANT
and then a method
- (void)result {
NSRange range = [#"--BB-------A----" rangeOfString:#"A" options:NSBackwardsSearch];
int rest = range.location % MYDIVISOR;
NSLog(#"Rest is %i", rest);
}
the output is always that rest is 0, no matter where the A occurs. I have solved it by storing the MYDIVISOR into an intermediate integer variable, but I would like to know why it does not work with the predefined constant. Any ideas?

This is because you did not put parentheses around your MYDIVISOR definition:
#define MYDIVISOR (1000/ANOTHER_CONSTANT)
Without parentheses, the code will look like this after the substitution by the preprocessor:
int rest = range.location % 1000 / ANOTHER_CONSTANT;
Because % and / have the same priority and are applied left-to-right, the compiler would generate the code that obtains a remainder of the division by 1000, and then quickly divide the result by 200, which is certainly not what you'd expect.
In general, it is a good idea to always put parentheses around your entire macro. In case of function-like macros with parameters, it is also a good idea to parenthesize each parameter as well.

Related

Do-While Loop in C doesn't repeat

This code doesn't repeat if I answer a negative number like "-1.01". How can I make it loop so that it will ask again for c?
#include <stdio.h>
main()
{
float c;
do {
printf("O hai! How much change is owed? ");
scanf("%.2f", &c);
} while (c < 0.0);
return(0);
}
The format strings for scanf are subtly different than those for printf. You are only allowed to have (as per C11 7.21.6.2 The fscanf function /3):
an optional assignment-suppressing character *.
an optional decimal integer greater than zero that specifies the maximum field width (in characters).
an optional length modifier that specifies the size of the receiving object.
a conversion specifier character that specifies the type of conversion to be applied.
Hence your format specifier becomes illegal the instant it finds the . character, which is not one of the valid options. As per /13 of that C11 section listed above:
If a conversion specification is invalid, the behaviour is undefined.
For input, you're better off using the most basic format strings so that the format is not too restrictive. A good rule of thumb in I/O is:
Be liberal in what you accept, specific in what you generate.
So, the code is better written as follows, including what a lot of people ignore, the possibility that the scanf itself may fail, resulting in an infinite loop:
#include <stdio.h>
int main (void) {
float c;
do {
printf ("O hai! How much change is owed? ");
if (scanf ("%f", &c) != 1) {
puts ("Error getting a float.");
break;
}
} while (c < 0.0f);
return 0;
}
If you're after a more general purpose input solution, where you want to allow the user to input anything, take care of buffer overflow, handle prompting and so on, every C developer eventually comes up with the idea that the standard ways of getting input all have deficiencies. So they generally go write their own so as to get more control.
For example, here's one that provides all that functionality and more.
Once you have the user's input as a string, you can examine and play with it as much as you like, including doing anything you would have done with scanf, by using sscanf instead (and being able to go back and do it again and again if initial passes over the data are unsuccessful).
scanf("%.2f", &c );
// ^^ <- This seems unnecessary here.
Please stick with the basics.
scanf("%f", &c);
If you want to limit your input to 2 digits,
scanf("%2f", &c);

What does "macro" mean in Objective-C?

I am new to iOS development and I just want to know the meaning of macro in Objective-C?
I have found that "macro" is used with #define but still do not get its meaning.
http://www.saturngod.net/ios-macro-define-value-with-condition
Yes, Larme is right. Macros can be used in many languages, it's not a specialty of objective-c language.
Macros are preprocessor definitions. What this means is that before your code is compiled, the preprocessor scans your code and, amongst other things, substitutes the definition of your macro wherever it sees the name of your macro. It doesn’t do anything more clever than that.
Almost literal code substitution. e.g.-
Suppose you want a method to return the maximum of two numbers. You write a macro to do this simple task:
#define MAX(x, y) x > y ? x : y
Simple, right? You then use the macro in your code like this:
int a = 1, b = 2;
int result = 3 + MAX(a, b);
EDIT:
The problem is that the preprocessor substitutes the macro definition into the code before compilation, so this is the code the compiler sees:
int a = 1, b = 2;
int result = 3 + a > b ? a : b;
C order of operations requires the sum 3 + a be calculated before the ternary operator is applied. You intended to save the value of 3 + 2 in result, but instead you add 3 + 1 first, and test if the sum is greater than 2, which it is. Thus result equals 2, rather than the 5 you expected.
So you fix the problem by adding some parentheses and try again:
#define MAX(x, y) ((x) > (y) ? (x) : (y))
A macro is a fragment of code which has been given a name. Whenever the name is used, it is replaced by the contents of the macro. There are two kinds of macros. They differ mostly in what they look like when they are used. Object-like macros resemble data objects when used, function-like macros resemble function calls.
An object-like macro is a simple identifier which will be replaced by a code fragment. It is called object-like because it looks like a data object in code that uses it. They are most commonly used to give symbolic names to numeric constants.
You create macros with the ‘#define’ directive. ‘#define’ is followed by the name of the macro and then the token sequence it should be an abbreviation for, which is variously referred to as the macro's body, expansion or replacement list. For example,
#define BUFFER_SIZE 1024
defines a macro named BUFFER_SIZE as an abbreviation for the token 1024. If somewhere after this ‘#define’ directive there comes a Objective C statement of the form
foo = (char *) malloc (BUFFER_SIZE);
The Objective C compiler will see the same tokens as it would if you had written
foo = (char *) malloc (1024);
You can also define macros whose use looks like a function call. These are called function-like macros. To define a function-like macro, you use the same ‘#define’ directive, but you put a pair of parentheses immediately after the macro name.
Like:
#define isIphone([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
#define GetImage(imageName) [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:imageName ofType:#"png"]]
Macros are compile time constants. That means they will replaced with actual values in the compile time.
#define MIN_VALUE 3 // Definition
if(x > MIN_VALUE) // Usage
{
}
While compiling it actually looks like
if(x > 3) // During compilation
{
}
Wikipedia has the answer, under Macro.
Definition:
The term originated with macro-assemblers, where the idea is to make available to the programmer a sequence of computing instructions as a single program statement, making the programming task less tedious and less error-prone.
Usage:
Keyboard and mouse macros that are created using an application's built-in macro features are sometimes called application macros. They are created by carrying out the sequence once and letting the application record the actions. An underlying macro programming language, most commonly a Scripting language, with direct access to the features of the application may also exist.

How to deal with arguments in macro names in Objective-C?

The idea is to setup several fixed CGPoint values with macros, and read them in code flexibly (randomly or with provided integer value)
I have a header file defining several CGPoints value like this:
#define kSpawnPoint1 {550,20}
#define kSpawnPoint2 {550,80}
#define kSpawnPoint3 {200,175}
I'm generating a random integer in my code between 1 to 3, and plan to read the CGPoint value in the macro according to the integer value. But don't know how to do it. After learning other tutorials about preprocessors, I write my code like following.
#define kSpawnPoint1 {550,20}
#define kSpawnPoint2 {550,80}
#define kSpawnPoint3 {200,175}
#define kSpawnPoint(x) kSpawnPoint##x
in the m file:
int tempInt = 1;
CGPoint tempSpawnPoint = kSpawnPoint(temInt);
However it doesn't work.(with warning: undeclared identifier 'kSpawnPointspawnPoint') How can I make this right? And is it the right way to pre-define several CGPoint? I think I must use the preprocessor to achieve this considering future multi-screen resolution support would be easier to implement in macro too, and my kSpawnPoints would not be the same with different screen resolution.
Macros only operate on text, not the values of variables. When you write kSpawnPoint(an_int), the preprocessor takes the literal string "an_int" and then pastes it, so you end up with kSpawnPointan_int. Thus, you would have to put a literal number as the argument in order to end up with one of your points: kSpawnPoint(1) -> kSpawnPoint1 -> {550, 20}
To choose randomly among your macros, you will have to put them into a structure that will exist at runtime, like an array or a switch statement.

One identifier for multiple values. Is it possible?

i would like to have one identifier responsible for several values for one time. if i had one this is what i could do:
if (myVariable == IDENTIFIER)//instead of if(myVariable == 5 || myVariable == 7) if i need A LOT of values
[myObject doSomething];
Is there a possibility to implement it somehow?
I think the closest you can come is by using bitmasks, so that you represent the set of allowable values with a mask that has all of the values set:
const int ALL_VALUES = (1 << 5) | (1 << 7);
if ((1 << myVariable) & ALL_VALUES)
[myObject doSomething];
Above, bit-wise AND is used to compute the intersection between the current value (seen as a 1-bit mask) and the mask of all allowed values. Note that this will only work if the number of values (and their actual values) is less than the number of bits in an int.
You could have a NSSet of possible values:
NSSet *possibleValues = [NSSet setWithObjects:#"Value1", #"Value2", #"Value3", nil];
if ([possibleValues containsObject:myVariable])
If you need something that works with a raw integer, let me know.
This is what methods are for:
- (BOOL)isFoo(int identifier) {
return identifier == 5 || identifier == 7;
}
Combine the answers. First use a function (variant of grahamparks):
BOOL isFoo(int identifier)
{
...
return ...;
}
For something this simple a function is probably better than a method - calling is a lot quicker and there is no need to ever override. Further if the function is only ever required in the current file declare it static BOOL isFoo... to limit the visibility of isFoo to just the file.
Now pick the body which suits the data - a couple of values, comparisons (grahamparks); more than a few values but all within 0-31 (uint32_t) or 0-63 (uint64_t) consider the bit-mask (unwind); many values all over the range consider sets (Richard J. Ross III); or roll your own. The important point which ever algorithm you choose is isolated within the function and can be changed easily if needed without affecting the rest of your code.
As existing similar examples consider isDigit() et al in the standard C library. Some implementations of these use a pre-allocated arrays of booleans (256 elements as the argument is a character) so testing for membership of the set is just an array index operation.

Unexpected looping in Objective C

I have this code:
unsigned int k=(len - sizeof(MSG_INFO));
NSLog(#"%d",k);
for( unsigned int ix = 0; ix < k; ix++)
{
m_pOutPacket->m_buffer[ix] = (char)(pbuf[ix + sizeof(MSG_INFO)]);
}
The problem is, when:
len = 0 and sizeof(MSG_INFO)=68;
k=-68;
This condition gets into the for loop and is continuing for infinite times.
Your code says: unsigned int k. So k isn't -68, it's unsigned. This makes k a very big number, based around a 4 byte int, it would be 4294967210. This is obviously quite a lot more than 0, so it's going to take your for loop a while to get that high, although it would terminate eventually.
The reason you think that it's -86, is that when you print it out with a function like NSLog, it has no direct knowledge about the arguments passed in, it determines how to treat the arguments, based around the format string, supplied as the first argument.
You're calling:
This:
NSLog(#"%d",k);
This tells NSLog to treat the argument as a signed int (%d). You should be doing this:
NSLog(#"%u",k);
So that NSLog treats the argument as the type that it is: unsigned (%u). See the NSLog documentation.
As it stands, I'd expect your buffer to overrun, trashing memory as the loop runs and your application to crash.
After reflecting, I believe #FreeAsInBeer is correct and you don't want to iterate through the for loop in this situation and you could probably fix this by using signed ints. However, It seems to me like you would be better off, checking len > sizeof(MSG_INFO) and if this isn't the case handling it differently. Most situations I can think of, I wouldn't want to perform any processing after the for loop, if I'd failed to read sufficient information for a message...
I'm not really sure what is going on here, as the loop should never execute. I've loaded up your code, and it seems that the unsigned part of your int declaration is causing the issues. If you remove both of your unsigned specifiers, your code will execute as it should, without ever entering the loop.