Beginner question about main().

Discussion in 'Mac Programming' started by GoKyu, Feb 19, 2009.

  1. macrumors 65816

    GoKyu

    Joined:
    Feb 15, 2007
    Location:
    New Orleans
    #1
    Hi all,

    I've been getting back into the basics of C, and I'm remembering a lot more than I thought I would (the last time I had a class in C was around 10 years ago.)

    All of the simple programs I'm writing at the moment are just that - simple, and only require a main() function that looks like this:

    Code:
    main() 
    {
       // code goes here
    }
    I know that you can pass arguments inside the parentheses, but I don't understand much about it yet.

    I'm currently writing code in an editor in Terminal and using gcc to compile. When I go through Xcode, it sets up this code for me:

    Code:
    int main (int argc, const char * argv[])
    {
      // Code goes here
    }
    I know that the 'int' in front of main is generally optional, because main assumes int as its type.

    But my question is...what the heck is all that other stuff in there, and why does Xcode just assume that I need it?

    Thanks,

    -Bryan
     
  2. macrumors regular

    Joined:
    Oct 13, 2008
    Location:
    Achewood, CA
    #2
    The 'other stuff' you're talking about is what allows main() to receive arguments from the command line.

    You don't have to understand it exactly now, since you're just starting out, and it's perfectly acceptable to use "int main()." Feel free to delete it for now.

    In case you're curious:

    When you run a program from your terminal, all the arguments you specify get put into a a list. So if you execute a command like this
    Code:
    $ myProgram -input file1.txt -output file2.txt
    
    then 'myProgram' receives a list containing the strings "myProgram," "-input," "file1.txt," "-output," and "file2.txt." The program is then free to use the arguments from the list as it pleases.

    The main() function receives two arguments. The first is called "argc" and it is an integer. argc means "argument count": it's the number of argument strings that were passed to the program, including the program's name. So in the example above, argc would be 5.

    The second argument, "argv," is the actual text data of the arguments. It is an array of strings (pointers to characters.) It would take too long to explain how pointers and strings work here, but I'm sure you'll learn about them soon. :)
     
  3. macrumors 603

    notjustjay

    Joined:
    Sep 19, 2003
    Location:
    Canada, eh?
    #3
    Code:
    $ myProgram -input file1.txt -output file2.txt
    
    For the sake of completion, here's what you'd get for the above example:

    argc = 5

    argv[0] = pointer to char array "myProgram"
    argv[1] = pointer to char array "-input"
    argv[2] = pointer to char array "file1.txt"
    argv[3] = pointer to char array "-output"
    argv[4] = pointer to char array "-file2.txt"
     
  4. macrumors 603

    Cromulent

    Joined:
    Oct 2, 2006
    Location:
    The Land of Hope and Glory
    #4
    This is incorrect now. C99 (the latest C standard) now requires all functions to explicitly declare their return type. Implicit declarations should be treated as errors by compilers (but often aren't). As a beginner it is probably best just to get in the habit of always using int main(void) if you don't need any of the other stuff.

    int argc is the number of command line arguments supplied to your program (the program name counts as one so the total command line arguments is always argc -1).

    char *argv[] stores the actual arguments themselves as pointed out much clearer than I could write it above :).

    Hope that helps.
     
  5. thread starter macrumors 65816

    GoKyu

    Joined:
    Feb 15, 2007
    Location:
    New Orleans
    #5
    Thanks for all the great info - I have read up to character arrays, and am starting to know a little about them, like:

    Code:
    char month[10];  // Reserve enough space for the longest month name, plus the null zero (\0).
    
    If I've read correctly, C doesn't have string variables, so you need to use a character array to perform the same function.

    That does help a lot, thanks :) I think the '*' marks that particular variable 'argv' as a pointer, doesn't it?

    I've read over pointers, but it's very abstract to me right now. They talk about pointers being links to an already existing variable somewhere in memory.

    C programmers don't know exactly what memory location their programs will be running in, do they? I mean, what's the point (sorry, no pun intended...) of having a pointer to a variable..why not just use the value of that variable?

    Code:
    int age;
    int *pAge;
    age = 21;
    pAge = &age;
    
    If you already know that age = 21, what purpose would it serve to have a link to it as pAge?

    Sorry if this went from beginner to seriously intermediate :) I probably won't be using pointers for awhile, but even as easy as this beginner's C book is, pointers seem to be quite tricky.

    Thanks again for all the replies, I appreciate it :)

    -Bryan
     
  6. macrumors 603

    Cromulent

    Joined:
    Oct 2, 2006
    Location:
    The Land of Hope and Glory
    #6
    Because you can do some very clever things with pointers.

    For instance using your example above:

    Code:
    char month[10];
    this array can hold only one month in it at a time but if we declare it like this:

    Code:
    char *month[12];
    we can now dynamically allocate as much memory as we require for each pointer in that array (month is now an array of pointers) and therefore store all twelve months.

    There are many other things you can do such as dynamic multidimensional arrays.
     
  7. macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #7
    It is pretty rare to have a pointer to a single primitive variable. Normally they are used to point to larger things, such as arrays (an array is really just a pointer to the base element), or a very large structure. In the case of a large structure, and you need to pass the structure around, it is more efficient to pass a 4 or 8 byte pointer than the whole structure by value. Also, if you have a great giant structure you may not want to keep it on the stack (don't worry for now), but on the heap (again, don't worry) instead, which requires that you allocate some memory for it. When you allocate that memory, you have to assign the address to something and that something has to be a pointer.

    You said you're not quite there yet, so a lot of this might not make sense yet, but pointers are absolutely essential once you get a bit further along.

    -Lee
     
  8. macrumors 6502

    Joined:
    Sep 15, 2008
    #8
    Pointers are very useful in function calling. Functions can return only 1 value usually, but by passing pointers as arguments (instead of values) the function is able to return a lot more. The arguments in effect become read/write.
     
  9. thread starter macrumors 65816

    GoKyu

    Joined:
    Feb 15, 2007
    Location:
    New Orleans
    #9
    I just had a quick followup question here...

    When you say "...but if we declare it like this...."

    Do you mean that:

    Code:
    char *month[12];
    
    should be its own variable (*instead* of the original char month[10]; ), or that it's now added onto that one, making it more flexible?

    As I understand it (not very well, admittedly), you can't have a pointer variable unless you already have another variable for it to actually point to.

    Thanks :)

    -Bryan
     
  10. macrumors 603

    Cromulent

    Joined:
    Oct 2, 2006
    Location:
    The Land of Hope and Glory
    #10
    You can have a pointer that is later set to point to something tangible using functions like malloc.

    So for instance:

    Code:
    char *p;
    p = (char *) malloc (128);
    Makes the pointer p point to a 128 bytes of memory. When you are finished with that memory you must call free like so otherwise you get a memory leak:
    Code:
    free(p);
    you can also dynamically resize the amount of memory that p points too using the realloc function.

    I hope I am not confusing you further. Pointers are widely regarded as the most confusing aspect of C.
     
  11. macrumors regular

    Joined:
    Oct 13, 2008
    Location:
    Achewood, CA
    #11
    Here's a diagram I often show to people who have difficulty with pointers.

    A pointer is basically just an 32-bit (or 64-bit) unsigned integer. However, with a pointer, its numeric value is interpreted as a memory address. So pointers just contain the locations in memory of other variables. That way, instead of passing huge chunks of data back and forth between functions in your code, you can just pass a memory address (a pointer) and operate on the data at that address (dereference the pointer).

    The attached file shows a code snippet that declares some variables and some pointers to them. The diagram on the right shows a simplified version of what what the program's memory might look like after the code has executed. Each cell in the grid is one byte. Remember, ints take 4 bytes, doubles take 8, chars take 1, and pointers (regardless of type) take 4 bytes on a 32-bit machine.

    Note that the 'type' of a pointer is used to tell the compiler what kind of data is at that memory location. That way, when you dereference a pointer, the computer knows how many bytes to fetch from that memory address. For example, dereferencing an int * will get the contents of the 4 bytes starting at that address, and dereferencing a double * will get the contents of the 8 bytes starting at that address.

    Since the value of a pointer is always a number, every pointer points "somewhere." However, an uninitialized pointer might contain garbage, and point to some restricted area of memory; trying to dereference it would likely cause a crash. A NULL pointer has a value of 0 (that is, it points to memory address 0) and is, by convention, used to mean "this pointer points to nothing."
     

    Attached Files:

  12. thread starter macrumors 65816

    GoKyu

    Joined:
    Feb 15, 2007
    Location:
    New Orleans
    #12
    Here's a simple program I wrote, but I'm having trouble with one particular line, which is commented out for the moment.

    If I add that line back it, it gives me a compile error:

    error: invalid operands to binary +

    I was trying to add the different lengths together with strlen(), but I thought it needed to be typecast to be an int, so I'm not sure what needs to be done to fix this.

    The program runs without the line, but it gives me a result of like 4096 characters, which is obviously wrong :)

    Any help would be appreciated.

    -Bryan

    Code:
    // This program will take input from the user and tell them how
    // many characters they typed.
    
    // Preprocessor directives
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main (void)
    {
    	int charAmount;
    	char firstName[15];
    	char lastName[20];
    
    	system("clear"); // Clear the screen
    
    	printf("Please enter your first name: "); 
    	scanf(" %s", firstName);
    
    	printf("\nPlease enter your last name: ");
    	scanf(" %s", lastName);
    	
    //	charAmount = (int)strlen(firstName + lastName);
    
    	printf("\n\nYour name is %s %s ",firstName, lastName); 
    	printf("and you typed %d characters.", charAmount);
    
    	return 0;
    }
    
     
  13. macrumors regular

    Joined:
    Nov 24, 2006
    Location:
    The Netherlands
    #13
    Code:
    
    //	charAmount = (int)strlen(firstName + lastName);
    
    
    
    you can't just concatenate strings like that. A quick solution in this case would be:

    Code:
     charAmount = strlen(firstName) + strlen(lastName);
    
    This adds the lengths of the two stings together.

    Check for strcat and strncat to learn more about concatenating strings.
     
  14. thread starter macrumors 65816

    GoKyu

    Joined:
    Feb 15, 2007
    Location:
    New Orleans
    #14
    Thanks, that worked perfectly :) Not too bad for my first attempt at anything more than a "Hello World" program...

    One other question I had about printf() that I haven't seen in my book....

    My original code looked like this:

    Code:
    printf("\n\nYour name is %s %s ",firstName, lastName, "and you typed %d characters.", charAmount);
    
    I thought you could do this....it compiles this way, but it stops after printing the name and never hits the "and you typed...." part.

    Is there a way to put everything into one printf() statement, or do you need to break it into multiple statements and only have one set of argument lists per printf() ?

    Thanks again for your help :)

    -Bryan
     
  15. macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #15

    Code:
    printf("\n\nYour name is %s %s and you typed %d characters.",firstName,lastName,charAmount);
    
    Multiple format strings doesn't jive as far as I know. You could print another string literal using the %s format specifier, but I can't think of a compelling reason to do so.

    -Lee
     
  16. thread starter macrumors 65816

    GoKyu

    Joined:
    Feb 15, 2007
    Location:
    New Orleans
    #16
    Lee:

    Wow, ok, it's been a long time since I last was learning C regularly...I should've thought of just doing it the way you showed.

    Thanks again,

    -Bryan
     

Share This Page