Find the answer to your Linux question:
Results 1 to 9 of 9
Code: #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct __verb { int size; char *synonyms[25]; } Verb; Verb verbs[] = { {2, {"help", "assistance!"}}, {3, {"carrying", "inventory", "got"}}, {3, {"go", ...
Enjoy an ad free experience by logging in. Not a member yet? Register.
  1. #1
    Penguin of trust elija's Avatar
    Join Date
    Jul 2004
    Location
    Either at home or at work or down the pub
    Posts
    3,533

    This code just doesn't feel very "c-like"


    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    typedef struct __verb {
        int size;
        char *synonyms[25];
    } Verb;
    
    Verb verbs[] = {
        {2, {"help", "assistance!"}},
        {3, {"carrying", "inventory", "got"}},
        {3, {"go", "walk", "travel"}},
        {2, {"north", "n"}},
        {2, {"south", "s"}},
        {2, {"west", "w"}},
        {2, {"east", "e"}},
        {2, {"up", "u"}},
        {2, {"down", "d"}},
        {4, {"take", "grab", "yoink", "get"}},
        {1, {"open"}},
        {2, {"examine", "look"}},
        {1, {"read"}},
        {2, {"speak", "say"}},
        {8, {"use", "dig", "swing", "climb", "light", "unlight", "spray", "unlock"}},
        {3, {"eat", "munch", "chew"}},
        {2, {"drop", "leave"}},
        {1, {"look"}},
        {1, {"score"}},
        {1, {"quit"}}
    };
    int numVerbs = 20;
    
    int main()
    {
        char input[1000];
        int i, j, l, a = -1;
        gets(input);
        l = strlen(input);
    
        for (i=0; i<numVerbs; i++) {
            for (j=0; j<verbs[i].size; j++) {
                if ('\0' != verbs[i].synonyms[j] && 0 == strcmp(verbs[i].synonyms[j], input) && l == strlen(verbs[i].synonyms[j])) {
                    a = i;
                    break;
                }
            }
        }
    
        if (a > -1) {
            printf("%s\n", verbs[a].synonyms[0]);
        } else {
            printf("not found\n");
        }
    
        return 0;
    }
    It compiles and does what it is supposed to do, yoink returns take, munch returns eat and so on but...

    It just doesn't feel particularly c-like. I still feel there should be more *'s and &'s in it

    Is there a more c-like way of writing this?
    What do we want?
    Time machines!

    When do we want 'em?
    Doesn't really matter does it!?


    The Fifth Continent

  2. #2
    Just Joined!
    Join Date
    Aug 2011
    Posts
    35
    I don't see why you say it doesn't feel c-like it's OK it's C I don't see something bad

  3. #3
    Penguin of trust elija's Avatar
    Join Date
    Jul 2004
    Location
    Either at home or at work or down the pub
    Posts
    3,533
    Quote Originally Posted by allwimb View Post
    I don't see why you say it doesn't feel c-like it's OK it's C I don't see something bad
    It's too easy to read and I've always thought or c as a write-only language or to be slightly less flippant, real c masters can get very terse in their code and that is extremely verbose and finally, it is disappointingly like every other programming language
    What do we want?
    Time machines!

    When do we want 'em?
    Doesn't really matter does it!?


    The Fifth Continent

  4. #4
    drl
    drl is offline
    Linux Engineer drl's Avatar
    Join Date
    Apr 2006
    Location
    Saint Paul, MN, USA / CentOS, Debian, Slackware, {Free, Open, Net}BSD, Solaris
    Posts
    1,286
    Hi.

    Not just c:
    Rule of Clarity: Clarity is better than cleverness ...

    In the Unix tradition, the implications of this advice go beyond just commenting your code. Good Unix practice also embraces choosing your algorithms and implementations for future maintainability. Buying a small increase in performance with a large increase in the complexity and obscurity of your technique is a bad trade not merely because complex code is more likely to harbor bugs, but also because complex code will be harder to read for future maintainers.

    -- The Art of Unix Porgramming,
    Basics of the Unix Philosophy
    Best wishes ... cheers, drl
    Welcome - get the most out of the forum by reading forum basics and guidelines: click here.
    90% of questions can be answered by using man pages, Quick Search, Advanced Search, Google search, Wikipedia.
    We look forward to helping you with the challenge of the other 10%.
    ( Mn, 2.6.n, AMD-64 3000+, ASUS A8V Deluxe, 1 GB, SATA + IDE, Matrox G400 AGP )

  5. #5
    Penguin of trust elija's Avatar
    Join Date
    Jul 2004
    Location
    Either at home or at work or down the pub
    Posts
    3,533
    Quote Originally Posted by drl View Post
    Hi.

    Not just c:

    Best wishes ... cheers, drl
    LOL, yeah that's how I expect code to be written in my day job using PHP. Most of the c code I have seen doesn't seem to follow that though, unless what I'm seeing is simple for c and I'm just not getting it.

    So let's re-phrase things.

    To help my ability to read c, is there a more terse way of writing the above code, regardless of whether it would be better or not?
    What do we want?
    Time machines!

    When do we want 'em?
    Doesn't really matter does it!?


    The Fifth Continent

  6. #6
    Linux Guru Rubberman's Avatar
    Join Date
    Apr 2009
    Location
    I can be found either 40 miles west of Chicago, in Chicago, or in a galaxy far, far away.
    Posts
    11,533
    Elija, you wold have loved the old "Obfuscated C" programming contests produced by the old (no longer in publication, unfortunately) C Users Journal (then later the C/C++ Users Journal). Some of them were awesome in their complexity to do the simplest of things! FWIW, I even had a couple of articles published in the journal, back in the 80's and 90's, on C programming for embedded real-time systems.
    Sometimes, real fast is almost as good as real time.
    Just remember, Semper Gumbi - always be flexible!

  7. #7
    Linux Guru Rubberman's Avatar
    Join Date
    Apr 2009
    Location
    I can be found either 40 miles west of Chicago, in Chicago, or in a galaxy far, far away.
    Posts
    11,533
    To help my ability to read c, is there a more terse way of writing the above code, regardless of whether it would be better or not?
    I don't know about terse (shorter, more compact), but you can certainly use more *'s, &'s, and ->'s... Example, for addressing a specific verb synonym:
    Old code:
    Code:
    verbs[i].synonyms[j]
    New code:
    Code:
    (verbs + i)->synonyms[j]
    Sometimes, real fast is almost as good as real time.
    Just remember, Semper Gumbi - always be flexible!

  8. #8
    Penguin of trust elija's Avatar
    Join Date
    Jul 2004
    Location
    Either at home or at work or down the pub
    Posts
    3,533
    I remember a piece of obfuscated perl that looked like ascii art of a camel which when run drew a piece of ascii art of a tiger's face; frankly that proves that programmers have too much time on their hands. Anyway I found this which in no way helps me read c

    Code:
    (verbs + i)->synonyms[j]
    is no harder to read than my way but lines like
    Code:
    while ((*args++ = (char *)strtok(NULL, " \t")));
    mean I have to think about what the hell is going on!! I do get their in the end. That line is taken form this. The fact that I do understand that code makes me feel that my c-fu has gone up a level.
    What do we want?
    Time machines!

    When do we want 'em?
    Doesn't really matter does it!?


    The Fifth Continent

  9. #9
    Linux Guru Rubberman's Avatar
    Join Date
    Apr 2009
    Location
    I can be found either 40 miles west of Chicago, in Chicago, or in a galaxy far, far away.
    Posts
    11,533
    The trouble with code like this:
    Code:
    while ((*args++ = (char *)strtok(NULL, " \t")));
    is that it is ambiguous whether the increment is being applied to the "args" variable, or "*args". In fact, this is totally dependent upon the compiler. If in fact the post-fix increment is meant to be applied to "args" after the contents are taken ( the address of the string that args[0] references ), then one needs to properly scope it, as in:
    Code:
    while ((*(args++) = (char *)strtok(NULL, " \t")));
    [rant on]
    As you say, C can be made very difficult to read. When I was Principal Engineer at a major software house, and responsible for company-wide coding practices, this sort of cruft would have been quickly purged from the mind-set of the engineer responsible for it. - usually with a good whack upside the head with my handy Louisville Slugger softball bat... I have no idea of the number of hours (days, weeks, months) I have spent rewriting and refactoring code that was impossible to maintain. Dealing with all the pernicious side-effects was the worst of it. My opinion/philosophy? If a grass-green engineer fresh out of college cannot understand what the code is doing, in detail, then it needs to be re-written. That said, there are times when things cannot be obvious, in which case, in-line documentation of what the intention is, and what the effects of a particular function or code block should be, can be critical. It reduces coding and application/library/driver behavioral errors by orders of magnitude. Using the appropriate coding practices, we were able to deliver a high-reliability distributed transaction processing system with over 10M lines of code that runs major manufacturing enterprises on a 24x365 basis. In the last 5 years I was with the company, the code I was responsible for (the framework that all the applications depend upon for distributed transaction processing, plug-in business rule handling, all the local and network IPC's, message handling, database interfacing, etc) had zero major show-stopping errors, even with serious code enhancements and new platform support. The application software likewise had a near-zero major error count. The process was simple.

    1. Document what you are doing - more is better since compilers happily ignore in-line comments, and many tools, such as JavaDocs, can turn the comments into real reference documentation.

    2. Minimize in-line operators (such as pre and post-fix increment/decrement) that alter the state of a variable. In many cases (as experience taught us) the side effects can create bugs are VERY difficult to find and/or fix. I remember one that was put in my queue by the VP of Engineering when an entire team of engineers gave up trying to fix it after a month of effort. It was causing serious production impacts on some big customers (top-tier semiconductor manufacturers - FAB downtime costs about $10M per hour). It took me a solid week of 12 hour days in the debugger to track it down to a function argument that had such a side-effect, but ONLY when certain pre-conditions were met... Arrrrgh! The fix was one line...

    4. Use human-readable and meaningful variable and type names. Use of things like 'i' and 'j' are ok as indexes in for() loops, but are to be avoided for just about every other purpose.

    5. Don't be afraid to rewrite code if your eyes start to glaze over when you review it. But TEST it thoroughly after!

    6. Use available code-coverage test tools and memory checkers such as Pure Coverage and Purify (commercial - now from IBM). There are decent open source tools for these uses as well, but IMO none are as good as the Purify tool suite. Unfortunately, Purify tools are pricey, but worth the price for commercial software development. For open source development on your own time and $$, use the free tools. If you are developing open source software for a commercial enterprise, use the best tools available - we all will bless you for it!

    Myself, I own copies of the ANSI/ISO C and C++ standards documents. Reviewing the sections that mention something like "specific behavior is compiler dependent" can help avoid a LOT of heartache down the line. Personally, I think that all serious software developers that use languages having international standards associated with them, should own copies of the standards for the languages they use in their daily work. They aren't cheap, but generally rate a tax deduction or credit if your company won't buy them for you.
    [rant off]
    Sometimes, real fast is almost as good as real time.
    Just remember, Semper Gumbi - always be flexible!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •