PDA

View Full Version : Very beginner question about defining "variables"




Refugee
Oct 29, 2010, 01:08 AM
I'm working on learning Cocoa and Objective-C, and I'm using the Hillegass book. I haven't gotten very far, but I've run into a question I haven't seen answered yet, and I haven't found any explanation as I've searched on the web.

In the headers, when I'm defining attributes, I'm looking at examples like
IBOutlet NSTextField *textField
or
NSCalendarDate *today

but I also see
int firstNumber
and
float secondNumber

I'm guessing that I need to define a point to objects but I can define variables directly as integer and floats, and I'm looking for confirmation of this assumption. Also, is there a list that gives the variable types that are used directly and not as pointers?

And I apologize if I'm not using the right terminology (and feel free to correct my grammar). I've got lots of programming experience with about 30-40 languages, but this is the first I've done in the C family.



TEG
Oct 29, 2010, 01:13 AM
Your first two examples, with the '*' on them are arrays, ints and floats are not arrays, to they can be explicitly set. This is because they are a set size, where as arrays can be any size.

For example;
int a = 1;
float b = 3.14159;

You can also set the arrays, but you have to indicate the length of the array when you create it. You use the asterisk to reserve a pointer to the array you will eventually create, without actually determining its size, until you need to use it.

TEG

robbieduncan
Oct 29, 2010, 03:27 AM
The first two are not arrays. They are pointers. In this case to objects.

Refugee
Oct 29, 2010, 05:48 AM
Thanks for the rapid help!

I think I see what you're telling me.
NSTextField is an array of CHARs, defined as an object.
I didn't think of NSCalendarDate being an object; can I tell because it has methods assigned to it. Is that how to know whether I'm about to use an object or a primitive data type? I'm guessing that BOOL isn't an object, so I wouldn't define a boolean variable with a pointer.

Chuck

Bernard SG
Oct 29, 2010, 05:53 AM
I didn't think of NSCalendarDate being an object;

NSCalendarDate is a *deprecated* class that creates date objects.

robbieduncan
Oct 29, 2010, 05:54 AM
NSTextField is an array of CHARs, defined as an object.

It really, really isn't. The * tells you it's a pointer. Nothing more, nothing less. It absolutely 100% does not imply it's an array. The item in front of the * tells us what sort of data we are pointing at. In this case it's a NSTextField which is a Cocoa object. Again, nothing to do with arrays.

Refugee
Oct 29, 2010, 05:58 AM
NSCalendarDate is a *deprecated* class that creates date objects.

What's taken its place?
I know the book was published in 2008, but it sounds like this is the reference boo most people point to as most helpful.

Bernard SG
Oct 29, 2010, 06:59 AM
What's taken its place?
I know the book was published in 2008, but it sounds like this is the reference boo most people point to as most helpful.

http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/DatesAndTimes/Articles/LegacyNSCalendarDate.html

But you still *can* use it for learning purposes - on Mac OS X. It's not valid in iOS.

Bernard SG
Oct 29, 2010, 09:57 AM
I'm guessing that I need to define a point to objects but I can define variables directly as integer and floats, and I'm looking for confirmation of this assumption. Also, is there a list that gives the variable types that are used directly and not as pointers?

And I apologize if I'm not using the right terminology (and feel free to correct my grammar). I've got lots of programming experience with about 30-40 languages, but this is the first I've done in the C family.

All types of variables can be declared directly or through pointers.
The point of pointers (no pun intended) is to avoid allocating memory to a variable unless the execution of the program requires it, that is when the variable needs to be used.

Generally in Obj-C you declare your objects (and global variables) in the "Interface file" (something.h) using that line

NameOfClass *nameOfObject;

The object itself is to be created, if needed, in the "Implementation file" (something.m) with a line like:

nameOfObject = [[NameOfClass alloc] init];

Which actually involves two steps: "alloc" allocates memory for the object and "init" initializes (creates) an instance of the object with all its instance variables.

However you can combine the declaration and the creation of the object with the syntax:

NameOfClass *nameOfObject = [[NameOfClass alloc] init];

This will be used when you're absolutely sure that creating the instance of object is necessary throughout the execution of your class.

But you always need to resort to a pointer to the object. Objects being generally containers for multiple instance variables, they are heavy on memory so you don't want to create them unless it's necessary; preferably on Runtime rather than at compilation.

For more insight about pointers, google "stack & heap"

subsonix
Oct 29, 2010, 10:07 AM
Just to add to this, what you are refering to as a definition is actually a declaration. ;)

Bernard SG
Oct 29, 2010, 10:23 AM
Just to add to this, what you are refering to as a definition is actually a declaration. ;)

True!

Refugee
Oct 29, 2010, 12:01 PM
All types of variables can be declared directly or through pointers.
The point of pointers (no pun intended) is to avoid allocating memory to a variable unless the execution of the program requires it, that is when the variable needs to be used.


(I already typed this post once but then got logged off and had to get back on -- so I'm sorry if this is a repeat post.)

I think I understand what you're saying, but let me see. And I've got a followup question while I read through this book's next exercise.

1) I was wondering why anyone would write a program that declares unnecessary variables. Would this be the reason: I've got a class with ten methods, each using variables. When someone runs the program, he may only call a feature that needs two of the methods, so the variables in the other, unused, methods aren't needed. Am I right?

2) I'm looking at a piece of code in the file called <i>lottery.m</i>
#import <Foundation/Foundation.h>
#import "LotteryEntry.h"

int main (int argc, const char *argv[]) {
Basically, why is argc an integer and argv a pointer? Maybe I've only seen simple examples so far, but every time I've seen an integer variable, it's declared as a variable and not a pointer. Is this just a simplification for these exercises? Is the "preferred" way to declare everything as a pointer?

3) Side question is regarding the import command for LotteryEntry.h. There's no reference to LotteryEntry.m in this module or in the LotteryEntry.h file. Is it a default/convention that every .h file always references a .m file? (I don't remember what the .m stands for anymore.)

Thanks for taking your time and answering very basic questions.

whooleytoo
Oct 29, 2010, 12:23 PM
1) I was wondering why anyone would write a program that declares unnecessary variables. Would this be the reason: I've got a class with ten methods, each using variables. When someone runs the program, he may only call a feature that needs two of the methods, so the variables in the other, unused, methods aren't needed. Am I right?


Yeah, true. For example, you may use the NSString class to deal with strings, but that doesn't mean you'll call every single method in that class, or reference every instance variable within in. Classes typically are designed for reuse, so even though you might only be using a subset of the methods/variables, doesn't mean they're not useful elsewhere/to other people.


2) I'm looking at a piece of code in the file called <i>lottery.m</i>
#import <Foundation/Foundation.h>
#import "LotteryEntry.h"

int main (int argc, const char *argv[]) {
Basically, why is argc an integer and argv a pointer? Maybe I've only seen simple examples so far, but every time I've seen an integer variable, it's declared as a variable and not a pointer. Is this just a simplification for these exercises? Is the "preferred" way to declare everything as a pointer?


Ok, this could be a little confusing :)

argc is an int. It will contain the number of command-line arguments being passed into this program.
argv is an array of C strings, each string holding one command-line parameter. So argc is the number of items in argv. (And C strings are essentially an array of characters, with the last character being a zero to mark the end. So argv is actually an array of arrays of characters).

If you're using Cocoa, you probably won't use C strings too much, you're more likely to use the NSString/NSMutableString classes. Easier to use, fewer memory issues, and they handle Unicode (such as non-English) characters


3) Side question is regarding the import command for LotteryEntry.h. There's no reference to LotteryEntry.m in this module or in the LotteryEntry.h file. Is it a default/convention that every .h file always references a .m file? (I don't remember what the .m stands for anymore.)

Thanks for taking your time and answering very basic questions.

Typically, you don't reference the .m file from the .h; you do it the other way around. The .m file will reference the .h file. You define the class, and implement the methods in the .m class, while declaring the class and its instance variables/methods in the corresponding .h class.

gnasher729
Oct 29, 2010, 12:47 PM
(I already typed this post once but then got logged off and had to get back on -- so I'm sorry if this is a repeat post.)

I think I understand what you're saying, but let me see. And I've got a followup question while I read through this book's next exercise.

1) I was wondering why anyone would write a program that declares unnecessary variables. Would this be the reason: I've got a class with ten methods, each using variables. When someone runs the program, he may only call a feature that needs two of the methods, so the variables in the other, unused, methods aren't needed. Am I right?

2) I'm looking at a piece of code in the file called <i>lottery.m</i>
#import <Foundation/Foundation.h>
#import "LotteryEntry.h"

int main (int argc, const char *argv[]) {
Basically, why is argc an integer and argv a pointer? Maybe I've only seen simple examples so far, but every time I've seen an integer variable, it's declared as a variable and not a pointer. Is this just a simplification for these exercises? Is the "preferred" way to declare everything as a pointer?

3) Side question is regarding the import command for LotteryEntry.h. There's no reference to LotteryEntry.m in this module or in the LotteryEntry.h file. Is it a default/convention that every .h file always references a .m file? (I don't remember what the .m stands for anymore.)

Thanks for taking your time and answering very basic questions.

1. You usually create files in pairs: One file for your code (the implementation file) and one file telling everyone (you and the compiler) how to use the code (header file). The header file would be LotteryEntry.h. The implementation file depends on the programming language you use: C = LotteryEntry.c, C++ = LotteryEntry.cpp, Objective-C = LotteryEntry.m, Objective-C++ = LotteryEntry.mm.

LotteryEntry.m would include or import LotteryEntry.h, so the compiler can check that the header file and the actual code match. Everyone else who needs to use the code in LotteryEntry.m would also include LotteryEntry.h, because that tells the compiler how to use it.

2. Variables and types can obviously be confusing. There are "simple" values, like an int, or float, which just exist by themselves. If you write a simple expression like 1 + 2, there is one int with a value of 1, another int with a value of 2, and the sum is a third int with a value of 3. Then there are more complicated values like an NSObject. An NSObject doesn't just exist, it has to be explicitly created, and it has to be explicitly destroyed. You never use an NSObject directly: When it is created (with the "alloc" method), the compiler will put it somewhere into the memory of your computer, and it will give you a pointer with the address where that object is. Analogy: You ask a builder "please build a house for me". When he is done, you doesn't give you a house, he gives you a piece of paper with the address of the house written on it. That is what a pointer is (in this case: NSObject* ). A pointer itself is a "simple" value.

3. Variables can only contain simple values. Try this:

void myfunction (void)
{
int x;
double y;
NSObject* z;
NSObject doesntwork;
}


int, double, and NSObject* are simple types - you can have a variable that holds any of them. NSObject is not a simple type, therefore you cannot have a variable that holds an NSObject (hope you see difference between NSObject and NSObject* - one is the house, the other is the piece of paper with the address written on it).

3. You can have pointers to any kind of types. You can have a pointer to an int (an int* ). Such a pointer is not an int, it is a piece of paper with the address of an int written on it.

void myfunction (void)
{
int x = 1;
int y = 2;
int* p = &x; // p is the address of x
p = 3; // Doesn't work because p is not an int - it is the address of an int
*p = 3; // Works - it changes x because p is the address of x
p = &y; // Now p is the address of y
*p = 4; // This changes y to 4 because now p is the address of y
}

lloyddean
Oct 29, 2010, 01:16 PM
Ok, this could be a little confusing :)

argc is an int. It will contain the number of command-line arguments being passed into this program.

argv is an array of C strings, each string holding one command-line parameter. So argc is the number of items in argv. (And C strings are essentially an array of characters, with the last character being a zero to mark the end. So argv is actually an array of arrays of characters).


I feel compelled to correct the part concerning 'argv'. 'argv' is actually an array, 'argc' in length, of pointers to 'C' strings.

Sydde
Oct 29, 2010, 01:33 PM
Generally in Obj-C you declare your objects (and global variables) in the "Interface file" (something.h) using that line

NameOfClass *nameOfObject;

I declare numerous objects in my methods in th .m files - NSString, NSArray, NSDictionary, etc, objects that will only be needed for the method, to be released or autoreleased on exit. Cocoa is creating and destroying objects constantly.

Bernard SG
Oct 29, 2010, 01:44 PM
I was wondering why anyone would write a program that declares unnecessary variables.


Let's suppose you're writing a program that sends invitations for a wedding. Generally, when you do that, you invite the guests with their spouse. Your program will seek information in some simple database that contains the information about the guests, for example: name, address, name of spouse. However, some guests are single.
It makes sense then to globally declare a char *nameOfSpouse[] rather than a char nameOfSpouse[xx]

If guest is married, *nameOfSpouse will point to a string of characters and your program will print something like "Paul and Diana Wilson"; if guest is single *nameOfSpouse will point to nothing and the program will write something like "Brenda Kraft".

In this case the use of a pointer is more elegant, not only in terms of memory management but also for the coding style.

Sydde
Oct 29, 2010, 02:11 PM
Let's suppose you're writing a program that sends invitations for a wedding. Generally, when you do that, you invite the guests with their spouse. Your program will seek information in some simple database that contains the information about the guests, for example: name, address, name of spouse. However, some guests are single.
It makes sense then to globally declare a char *nameOfSpouse rather than a char nameOfSpouse

If guest is married, *nameOfSpouse will point to a string of characters and your program will print something like "Paul and Diana Wilson"; if guest is single *nameOfSpouse will point to nothing and the program will write something like "Brenda Kraft".

In this case the use of a pointer is more elegant, not only in terms of memory management but also for the coding style.

Except that char nameOfSpouse actually can take up less space than the pointer, since you are only declaring a single byte. Yes, I am being picayune: computers tend to be as well, attention to detail is quite important.

jared_kipe
Oct 29, 2010, 07:32 PM
Yeah but... char nameOfSpouse couldn't hold the name of a spouse. It couldn't even hold a pointer to the actual nameOfSpouse.

Sydde
Oct 29, 2010, 10:19 PM
Yeah but... char nameOfSpouse couldn't hold the name of a spouse. It couldn't even hold a pointer to the actual nameOfSpouse.

That depends on your compile flags. Using the default XCode settings, "char" or "BOOL" will occupy 4 bytes, for alignment purposes, so a build for a 32-bit target will have room for a coerced pointer in that variable. Which you should never count on, in case someone else ever has to build from your source and might unknowingly use the wrong settings.

Bernard SG
Oct 30, 2010, 08:17 AM
Ugh, sorry, I forgot the [] brackets.