Very beginner question about defining "variables"

Discussion in 'Mac Programming' started by Refugee, Oct 28, 2010.

  1. macrumors newbie

    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
    NSCalendarDate *today

    but I also see
    int firstNumber
    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.
  2. TEG
    macrumors 604


    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.

  3. Moderator


    Staff Member

    The first two are not arrays. They are pointers. In this case to objects.
  4. macrumors newbie

    How do you know when you're defining it?

    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.

  5. macrumors 65816

    Bernard SG

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


    Staff Member

    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.
  7. macrumors newbie

    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.
  8. macrumors 65816

    Bernard SG

  9. macrumors 65816

    Bernard SG

    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"
  10. macrumors 68040

    Just to add to this, what you are refering to as a definition is actually a declaration. ;)
  11. macrumors 65816

    Bernard SG

  12. macrumors newbie

    (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.
  13. macrumors 603


    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.

    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

    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.
  14. macrumors G5


    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.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
  15. macrumors 6502a

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


    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.
  17. macrumors 65816

    Bernard SG

    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.
  18. macrumors 68000


    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.
  19. macrumors 68030


    Yeah but... char nameOfSpouse couldn't hold the name of a spouse. It couldn't even hold a pointer to the actual nameOfSpouse.
  20. macrumors 68000


    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.
  21. macrumors 65816

    Bernard SG

    Ugh, sorry, I forgot the [] brackets.

Share This Page