Thread: Marching coordinates

  1. #16
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    It is. It's a minimum of 512 AFAIK, though on some of my computers it's 8192. It's used for setbuf etc. I like to use it as the amount of memory to increase a string by when I run out (see codeform).

    [edit] What's that about a double-linked list? (I think it's "double-linked" and not "doubly-linked" BTW. It's like "fine-toothed comb", which is actually "fine tooth-comb"; there was once a fine type of tooth-comb. ) [/edit]
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  2. #17
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by twomers View Post
    Wow. A doubly listed list! You should be proud, dwks!

    >> STRING_LEN = BUFSIZ
    Is BUFSIZ a #define ... ? I would be very amused if it was.
    I think it's exactly that realization that eventually convinces most people to just use #define :-)

  3. #18
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Well, here are the arguments that I'm aware of (for anonymous enums):

    FOR
    enum values are compile-time constants, so the compiler can give you better error messages if, for example, you try something like this:
    Code:
    enum { X = 10 };
    int X = 10;  /* whoops */
    Also, debuggers are better with enum values (which is more readable, 10 or X?)

    AGAINST
    enums are not supposed to be used in that way, so it could become harder to read or something.

    And for #defines:

    FOR
    #defines are processed by the preprocessor, so you can change their values via the command line and Makefiles etc.

    AGAINST
    See FOR for enums.

    I think I'd prefer to use enums for values like string lengths, but #defines for things like the path to ls (that you might want to change without edited the source).

    [edit] Basically a restatement of brewbuck's post above. [/edit]
    Last edited by dwks; 04-11-2007 at 03:11 PM.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  4. #19
    The superhaterodyne twomers's Avatar
    Join Date
    Dec 2005
    Location
    Ireland
    Posts
    2,273
    >> [edit] What's that about a double-linked list? (I think it's "double-linked" and not "doubly-linked" BTW. It's like "fine-toothed comb", which is actually "fine tooth-comb"; there was once a fine type of tooth-comb. ) [/edit]

    It was in your first point where it went into 1(a) and 1(b). Very impressive. Two lists. But in one. And I said a doubly listed list. Not linked.

    >> It is.
    But then why not simply use that instead of your enum? Seems similar to hearing a zebra run!

  5. #20
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Quote Originally Posted by twomers View Post
    >> [edit] What's that about a double-linked list? (I think it's "double-linked" and not "doubly-linked" BTW. It's like "fine-toothed comb", which is actually "fine tooth-comb"; there was once a fine type of tooth-comb. ) [/edit]

    It was in your first point where it went into 1(a) and 1(b). Very impressive. Two lists. But in one. And I said a doubly listed list. Not linked.

    >> It is.
    But then why not simply use that instead of your enum? Seems similar to hearing a zebra run!
    Sorry, I'm so used to reading "double-linked list" that I see it everywhere . . . but I bet you'd have said "doubly-linked list" if you'd mentioned one.

    Because I might want to change it.
    Code:
    enum { STRING_LEN = BUFSIZ*2 };
    enum { STRING_LEN = USHRT_MAX };
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  6. #21
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by dwks View Post
    And for #defines:

    AGAINST
    See FOR for enums.
    Whaddaya mean?

    Code:
    #define X 10
    int X = 10;
    The preprocessor will turn that into "int 10 = 10;" and the compiler will barf. No problem there.

    I think I'd prefer to use enums for values like string lengths, but #defines for things like the path to ls (that you might want to change without edited the source).
    I actually use "const char *" for constant strings. The problem is this: a string literal has type "char *" (i.e. NOT const), but on most platforms it resides in read-only memory (despite the fact that it isn't known to be "const") I.e.:

    Code:
    /* This will probably crash. */
    char *foo = "Hello";
    foo[0] = 'A';
    Whereas if you assign it to a const char * from the get-go:

    Code:
    const char *foo = "Hello";
    foo[0] = 'A'; /* Compiler throws error */
    This saves you from the peril of passing a string literal to a function which takes a non-const char pointer, which then tries to modify the string, which then crashes. Instead you get a compile error and go fix the problem.

  7. #22
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    The preprocessor will turn that into "int 10 = 10;" and the compiler will barf. No problem there.
    No, but it will give you an error like "invalid variable name" you you'll think, "what? X? invalid???". Whereas if you have an enum by the same name it will give you a much more palatable error. (I should imagine anyway.)

    I'm aware of the const-ness of string literals. I just use #defines for them because I like inserting them into strings with the preprocessor's string concatenation.
    Code:
    fprintf(stderr, PROGRAM " version " VERSION " by " AUTHOR "\n");
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  8. #23
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by dwks View Post
    I'm aware of the const-ness of string literals. I just use #defines for them because I like inserting them into strings with the preprocessor's string concatenation.
    Code:
    fprintf(stderr, PROGRAM " version " VERSION " by " AUTHOR "\n");
    That's fine until one day one of the strings has a "%s" or something in it.

    Why not just:

    Code:
    fprintf(stderr, "%s version %s by %s\n", PROGRAM, VERSION, AUTHOR);

  9. #24
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Because I usually use puts() instead. It's a case of premature optimization. You're right, it's not a good idea . . . I think I'll avoid it in the future.

    I still like enums though. The main reason being that, in C++, you can put them in namespaces etc. No doubt const variables would be a better idea in that case, though.

    It was in your first point where it went into 1(a) and 1(b). Very impressive. Two lists. But in one.
    You could always say a "nested list".
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  10. #25
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by dwks View Post
    Because I usually use puts() instead. It's a case of premature optimization. You're right, it's not a good idea . . . I think I'll avoid it in the future.
    Well, I agree that string concatenation is a pretty useful thing to do. The problem is really printf-specific -- the format string to printf() should always be a literal in my opinion so that you can SEE what it is and make sure there are no stray conversion specifiers lurking in it. But I use string concatenation all the time when printing out long messages.

  11. #26
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Me too, for multiple lines usually. Sometimes I run into a GCC error message to the effect of "string length is longer than the C89 standard of 509 characters". I think that's for 509 chars + 1 NULL + 2 chars for string length to fit into 512 characters, but I'm just guessing.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  12. #27
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by dwks View Post
    Me too, for multiple lines usually. Sometimes I run into a GCC error message to the effect of "string length is longer than the C89 standard of 509 characters". I think that's for 509 chars + 1 NULL + 2 chars for string length to fit into 512 characters, but I'm just guessing.
    I have a vague recollection of reading somewhere that the choice of 509 was actually a typo in the original standard, which wasn't considered important enough to fix. But take that with a truck-sized grain of salt.

  13. #28
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Quote Originally Posted by joerg View Post
    x[0]=0;
    y[0]=0;

    for(i=0;i<N-1;i++)
    {
    if(x[i]<1) x[i+1]=x[i]+Vx*dt;
    else x[i+1]=x[i]-Vx*dt;

    Help! I want the coordinates x[i] change from 0 over +1 to -1 and back as often as i<N. The program counts from 0 up to 1 - O.K. - but then oscillates from 1 to 0.9 and so on.
    Have you considered a lookup-table type of thing for the x[]?
    Code:
    #include <stdio.h>
    
    double foo(int i)
    {
       static const double a[] = 
       {
          +0.0,+0.1,+0.2,+0.3,+0.4,+0.5,+0.6,+0.7,+0.8,+0.9,
          +1.0,+0.9,+0.8,+0.7,+0.6,+0.5,+0.4,+0.3,+0.2,+0.1,
          +0.0,-0.1,-0.2,-0.3,-0.4,-0.5,-0.6,-0.7,-0.8,-0.9,
          -1.0,-0.9,-0.8,-0.7,-0.6,-0.5,-0.4,-0.3,-0.2,-0.1,
       };
       return a[i % (sizeof a / sizeof *a)];
    }
    
    int main(void)
    {
       int i;
       for ( i = 0; i < 1000; ++i )
       {
          printf("%4g%c", foo(i), i % 10 == 9 ? '\n' : ' ');
       }
       return 0;
    }
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  14. #29
    Registered User
    Join Date
    Jan 2007
    Posts
    40
    Actually that's what I was suggesting with the memoization, but figured it wasn't worth it since the lookup table would be 40 elements. Plus I was using an algorithm to generate the lookup table, which I realized I could just bypass the lookup table and just use that algorithm to calculate the values themselves by modulating them over 40.

    What's the "static" do when you say "static const double a[]"? I'm familiar with static from Java, but have never seen it used in my short time with C, since C isn't object oriented, and static from Java is an object-oriented term.
    Last edited by IsmAvatar2; 04-12-2007 at 10:41 AM.

  15. #30
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by IsmAvatar2 View Post
    What's the "static" do when you say "static const double a[]"? I'm familiar with static from Java, but have never seen it used in my short time with C, since C isn't object oriented, and static from Java is an object-oriented term.
    The static causes the array to be allocated statically (like global variables) instead of on the stack. If it were on the stack, the program would have to copy the contents of the array into a new array on the stack for every single call to the lookup function. But because it is static, the array "just exists" and the function refers to it without having to construct it.

    EDIT: In this case, it means pretty much the same thing as "static" in Java -- the data belongs to the "class" (running program) instead of the "instance" (function invocation). The "static" keyword was taken from C for use in Java, so it's no surprise the idea is similar.

    If something is a static global variable, it means something slightly different -- the global variable is exactly like any other module-level variable (e.g. globals) but it cannot be referenced outside the module it is declared in. So "static" means two different things in C.
    Last edited by brewbuck; 04-12-2007 at 10:45 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How to get relative mouse coordinates when GLUT return absolute
    By joeprogrammer in forum Game Programming
    Replies: 14
    Last Post: 02-10-2009, 06:35 PM
  2. marching coordinates II
    By joerg in forum C Programming
    Replies: 2
    Last Post: 04-11-2007, 02:13 PM
  3. Global coordinates in OpenGL?
    By IcyDeath in forum C++ Programming
    Replies: 1
    Last Post: 11-25-2004, 06:29 PM
  4. Converting from Screen to World Coordinates
    By DavidP in forum Game Programming
    Replies: 9
    Last Post: 05-11-2004, 12:51 PM
  5. Size of 1 pixel
    By ooosawaddee3 in forum C++ Programming
    Replies: 4
    Last Post: 07-26-2002, 08:06 PM