This question already has answers here:
Does an int in Objective-C have a default value of 1?
(4 answers)
Closed 8 years ago.
I am reading a book called "Programming in Objective-C", Sixth Edition, by Stephen G. Kochan. It has the following statement on page 144 which is confusing me:
Local variables that are basic C data types have no default initial value, so you must set them to some value before using them.
Yet when I have the following code, it still works, and displays 0:
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[])
{
int number;
NSLog(#"%i", number);
return 0;
}
Isn't int a basic C data type?
"Basic C data types have no default initial value", it does not mean they will not have a value if you do not initialize them, it is just that you will not know in advance what that value will be.
In your case, that number just happen to have a zero, but it could have other value.
Local variables are allocated on the stack. The initial value of a local variable has no guaranteed value. Instead the value of the local variable depends entirely on whatever random values were left by the previous function that used that particular region of the stack.
In the case of the main function, the initial values of local variables may seem predictable since main is the first function to run and use that region of the stack. However, the compiler makes no effort, and the language specification has no requirement, to guarantee the initial value of the local variables.
In summary, always explicitly initialize local variables before using them.
Related
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[])
{
#autoreleasepool {
NSLog(#"HELLo %i");
}
return 0;
}
I tried to print a integer value in objective-C XCode compiler but i forgot to specify the variable. When i executed it, i got some garbage value like 4144 for integer, 98489866930523080936567411769317361312251531363217687183360.000000 for float and values like that for other data types too.
I'm just really interested in knowing the reason behind this garbage output ??????
This is because the values to print are passed in registers or on the stack/frame to the function that will print the results.
The printf() function (or in your case NSLog), and functions like it, take 1 or more parameters. The maximum number of parameters is not specified by the function header.
This function first gets a pointer to the string to print, and parses it. Every time it encounters %i, %d, %f etc., it starts pulling the values to print off of the stack, one by one.
In your case, the value it is pulling is uninitialized since it isn't specified, and in this case its value translated to 4144 when interpreted as an integer.
There are some good answers here:
How do vararg functions find out the number of arguments in machine code?
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
“static const” vs “#define” in C
In Objective-C what is the difference between the following two lines:
#define myInteger 5
static const NSInteger myInteger = 5;
Assume they're in MyClass.m above the implementation directive.
#define myInteger 5
is a preprocessor macro. The preprocessor will replace every occurrence of myInteger with 5 before the compiler is started. It's not a variable, it's just sort of an automatic find-and-replace mechanism.
static const NSInteger myInteger = 5;
This is a "real" variable that is constant (can't be changed after declaration). Static means that it will be a shared variable across multiple calls to that block.
When using #define the identifier gets replaced by the specified value by the compiler, before the code is turned into binary. This means that the compiler makes the substitution when you compile the application.
When you use const and the application runs, memory is allocated for the constant and the value gets replaced when the applicaton is ran.
Please refer this link:- Difference between static const and #define
There are differences:
Define is textual substitution:
Define is preprocessor textual substitution made before compilation. You will achieve the same effect when you textually replace 5 in every occurrence of define.
Static const is a variable in memory
Static const however is an instance of NSInteger type that resides in program memory. You cannot change it during runtime, but it is a value which is present in the memory and its own address as a variable.
#define myInteger 5 is a macro that declares a constant.
So wherever you use myInteger macro it gets replaced with 5 by the preprocessor engine.
const NSInteger myInteger = 5; declares a variable myInteger that holds the value 5.
But their usage is the same, that is they are constants that can be used to prevent hard coding.
How can I specify that a method should take as parameter a pointer to a location in memory that can hold a specified number of values? For example, if I have:
- (void)doSomethingWith:(int *)values;
I'd like to make it clear that the int * passed in should point to an allocated space in memory that's able to hold 10 such values.
To directly answer your question, use an array argument with a bounds, e.g.:
- (void)takeTenInts:(int[10])array
Which specifies that the method takes an array of 10 integers.
Only problem is the C family of languages do not do bounds checking, so the following is valid:
int a[10], b[5];
[self takeTenInts:a]; // ok
[self takeTenInts:b]; // oops, also ok according to the compiler
So while you are specifying the size, as you wish to do, that specification is not being enforced.
If you wish to enforce the size you can use a struct:
typedef struct
{
int items[10];
} TenInts;
- (void)takeTenInts(TenInts)wrappedArray
Now this doesn't actually enforce the size at all[*], but its as close a you can get with the C family (to which the word "enforcement" is anathema).
If you just wish to know the size, either pass it as an additional argument or use NSArray.
[*] It is not uncommon to see structures in C following the pattern:
typedef struct
{
// some fields
int data[0];
} someStruct;
Such structures are dynamically allocated based on their size (sizeof(someStruct)) plus enough additional space to store sufficient integers (e.g. n * sizeof(int)).
In other words, specifying an array as the last field of a structure does not enforce in anyway that there is space for exactly that number of integers; there may be space for more, or fewer...
Why use "(int *)" when you have the power (and "count") of "NSArray" to work with?
But anyways, looking at this potentially related question, couldn't you just do a "sizeof(values)" to get the size of a statically/globally allocated pointer?
If that doesn't work (which would be in the case of a dynamically allocated array), you really would probably need some kind of "count:" parameter in your "doSomethingWith:" method declaration.
There are a several ways. You could just name the method appropriately:
- (void)doSomethingWithTenInts:(int *)tenInts;
Or you could use a struct:
typedef struct {
int values[10];
} TenInts;
- (void)doSomethingWithTenInts:(TenInts *)tenInts;
Or you could make the user tell you how many ints he is giving you:
- (void)doSomethingWithInts:(int *)ints count:(int)count;
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Constants in Objective C
I'm designing a controller and I'm gonna need some constants inside it (locally, just for that controller). Looking at some sample code provided by Apple, I can see these lines:
#import "Constants.h"
#define kTextFieldWidth 260.0
static NSString *kSectionTitleKey = #"sectionTitleKey";
static NSString *kSourceKey = #"sourceKey";
static NSString *kViewKey = #"viewKey";
const NSInteger kViewTag = 1;
Can anyone explain to me what the difference between them is? Which style should I use? Are they dependent on the type of object/value you assign to them? Meaning use: static NSString * for strings, #define for floats and NSInteger for integers? How do you make the choice?
The #define keyword is a compile time directive that causes the define'd value to be directly injected into your code. It is global across the entire program and all linked libraries. So you can strike that off the list, based on your desire to create a constant for the controller only.
The main difference between static and const is that static variables can be changed after initialization, const ones cannot. If you want to be able to modify your variable after initialization then you should use the static keyword.
Hope that helps.
As Scott and benzado pointed out that is the best way to define your constant values. However as far as defines go it is harder to debug using defines as you can usually not easily see the expanded value in a debugger. You will only need to add an extern declaration to the header file of your class if your intentions are to expose the variable globally. And the next thing to remember is to put the const declaration after the pointer (*) or else you will get warnings of discard qualifiers from pointer in most uses.
I'm still learning, and I'm just stuck. I want the user to enter any number and in result, my program will do this equation:
x = 5*y
(y is the number the user adds, x is outcome)
How would I do this? I'm not sure if I'm suppose to add in an int or NSString. Which should I use, and should I enter anything in the header files?
I'm not sure if I'm suppose to add in an int or NSString.
Well, one of these is a numeric type and the other is a text type. How do you multiply text? (Aside from repeating it.)
You need a numeric type.
I would caution against int, since it can only hold integers. The user wouldn't be able to enter “0.5” and get 2.5; when you converted the “0.5” to an int, the fractional part would get lopped off, leaving only the integral part, which is 0. Then you'd multiply 5 by 0, and the result you return to the user would be 0.
Use double. That's a floating-point type; as such, it can hold fractional values.
… should I enter anything in the header files?
Yes, but what you enter depends on whether you want to use Bindings or not (assuming that you really are talking about Cocoa and not Cocoa Touch).
Without Bindings, declare an outlet to the text field you're going to retrieve the multiplier from, and another to the text field you're going to put the product into. Send the input text field a doubleValue message to get the multiplier, and send the output text field a setDoubleValue: message with the product.
With Bindings, declare two instance variables holding double values—again, one for the multiplier and one for the product—along with properties exposing the instance variables, then synthesize the properties, and, finally, bind the text fields' value bindings to those properties.
If you're retrieving the NSString from a UI, then it's pretty simple to do:
NSString * answer = [NSString stringWithFormat:#"%d", [userInputString integerValue]*5];
This can be done without any objective C. That is, since Objective-C is a superset of C, the problem can be solved in pure C.
#include <stdio.h>
int main(void)
{
int i;
fscanf(stdin, "%d", &i);
printf("%d\n", i * 5);
}
In the above the fscanf takes care of converting the character(s) read on the standard input to a number and storing it in i.
However, if you had characters from some other source in a char* and needed to convert them to an int, you could create an NSString* with the – initWithCString:encoding: and then use its intValue method, but in this particular problem that simply isn't needed.