[OT] Application design

Discussion in 'C Programming' started by Tim Cambrant, Sep 6, 2003.

  1. Tim Cambrant

    Tim Cambrant Guest

    I'm very sorry if I'm not allowed to post such a question here, but I really
    don't know where else to ask such a question, and since my language of
    choice is C, I thought I'd post here. You are welcome to ignore this if it's
    really not allowed.

    One of the things that puzzle me about programming isn't the language
    itself, and not the math you have to know, but the simple logic behind it
    all. I have really no idea how to create a program larger than the average
    test-program you see in books. I just don't know how to pull it all together
    to perform a larger task than converting fahrenheit to celsius :) Even the
    medium-sized open source programs make me confused.

    I've been looking for a usenet-group or a web-forum of some sort where
    people discuss the process of building and planning a program, with
    flowcharts, algorithms etc. I know there are books on the subject, but since
    I'm a poor student, I would have to wait for quite a while to get my hands
    on such a book, especially since the library of my town isn't the best.
    However, you are welcome to recommend me books as well. Where do I look for
    help on application design and development?

    Once again, I'm very sorry for cluttering up this great group with an
    off-topic question, but I feel that if I get the opportunity to solve my
    long-lived problem, I could start giving something back to the language
    itself by support etc, and not by asking stupid questions about my puny
    test-programs that fail to run :)

    Thank you in advance.
    Tim Cambrant, Sep 6, 2003
    1. Advertisements

  2. Try the "The Practice of Programming" by Kernighan and Pike. It's oriented
    towards C.

    Allin Cottrell, Sep 6, 2003
    1. Advertisements

  3. Well, presumably we're welcome to ignore it whether it's allowed or not. The
    comp.programming newsgroup is probably a better bet, but let's take a quick
    stab at this anyway.

    Step 1: decide what unsolved problem you are now trying to solve. If you
    have no unsolved problems, proceed from step 5.
    Step 2: is this problem too big for a computer to understand?
    Step 3: if not, tell the computer all about it; otherwise, divide it into
    two or more problems.
    Step 4: proceed from step 1.
    Step 5: time to debug.
    For now, just take any of your existing programs, preferably one that does
    something remotely useful. Think about how you might make it better.

    Make it better. (Come back in a couple of hours, when you're finished.)

    What problems did you have whilst extending that program to incorporate this
    extra functionality? How might you have written the /original/ program in
    such a way that it could be extended more easily?

    Rewrite this new program accordingly.

    Now extend it to do some /other/ useful thing, too. Add another ten features
    or so.

    At each stage, think about why it's hard (if it's hard) to grow this
    program, and how it might be made easier.

    Repeat the experiment, using a different base program.

    Add twenty features to this one. If you can't think of twenty useful
    features, think up some silly ones, but pretend they're useful.
    If you want more immediate feedback, try IRC. The guys in Undernet #c are
    decent enough sorts, provided you follow the usual conventions.
    Richard Heathfield, Sep 6, 2003
  4. Tim Cambrant

    Tim Cambrant Guest

    I have one or two of those, yes...
    This is a very good point. I find planning with pen and paper to be somewhat
    difficult, but it's easier when you have code to improve. I guess I'm the
    "write a function, compile, correct errors, add next function"-type of
    programmer, for good and bad.

    Thank you very much, I'll definately try your method. Infact, i just printed
    out your post and put it infront of me, while trying to extend/improve some
    K&R-exercises I've done :)
    Tim Cambrant, Sep 6, 2003
  5. That can lead to difficulties when it comes to adding new functionality.
    Inelegance, at the very least. The point about extending your exercise
    programs, rather than "real" programs, is that you should not be afraid to
    refactor the whole thing mercilessly, if it leads to a cleaner design. As
    you refactor, you will find yourself discovering good design principles
    more or less automatically (I hope!). Or at least, you'll discover why your
    previous designs were less than perfect. In its own way, that is a step
    Richard Heathfield, Sep 6, 2003
  6. Tim Cambrant

    Tim Cambrant Guest

    I will think about that. Thank you very much for your advices. I suppose I
    should just stick with small programs until i feel 'enlightened' :)

    I have a friend who tought himself C++ by reading one or two online
    tutorials, and then modifying an open source X Window Manager for *nix. His
    version is now superior to the predecessor and he's been working on it
    constantly as an open source project for over two years. Still, he has yet
    to read a book about programming. Some people just catch the logic easily, i

    However, thank you again for the help.
    Tim Cambrant, Sep 6, 2003
  7. On the contrary, start to write bigger programs /now/. Be self-critical, but
    in a constructive way. "Boy, adding that feature was hard work! How could I
    have made it easier? How could I have designed the original program to make
    adding this feature simpler?" Learn the lessons as you encounter them.
    I doubt whether his code would stand up to rigorous scrutiny. Whilst it is
    possible to "grok" a language just by inspection of well-written code, it's
    not terribly easy. A combined approach - theory /and/ practice - is better
    for the vast majority of people.
    Richard Heathfield, Sep 6, 2003
  8. Tim Cambrant

    Malcolm Guest

    I'll give you a C answer (I would have answered differently on
    The first thing to do is to define the core functionality of your program.
    With some programs, like text editors, you can keep on adding features as
    you feel like it, but core functionality is the ability to load, display,
    and modify a text file. Other programs are very closely defined - for
    instance a program to play chess doesn't have much room for new features.

    As Richard Heathfield said, you then need to determine that the core
    function can be done by a computer. It may be that this is almost impossible
    (for instance, face recognition) or it may be that it is possible but beyond
    your technical skills (for instance, writing a C compiler is very hard, but
    obviously not unachievable).

    Often there will be a few functions which are at the heart of your program.
    Design these functions so they are testable, and then write them. For
    instance, a simple chess program will have a function to assess the strength
    of a position.

    You would write

    int pos_strength(BOARD *board, int white)

    you can then write and test that function independently.

    You can write a quick ugly-looking interface that at least allows you to see
    the board and play chess, until you are satisfied that your higher-level
    chess function is playing a legal game and is making sensible moves. Of
    course you can keep on refining it at any time.

    We now have a function

    void playmove(BOARD *board, int white, MOVE *mv)

    this should be completely portable, and it lets us play a game of chess.

    Now we write the interface proper. How to do this depends on your platform,
    but using a typical windowing system you will have to associate game data,
    including the board, with a window. You will need a dispaly function to draw
    chess pieces in the appropriate positions, and you will need to intercept
    mouse clicks when the player moves pieces. You will also need to idiot-proof
    the program by rejecting illegal moves.
    Malcolm, Sep 6, 2003
  9. Tim Cambrant

    Tim Cambrant Guest

    That will be fine :)
    I can't really believe why i havn't thought of this before. Creating the
    core of the program first and then building on to it, that is. That does
    require that the project is big enough to define a core from.
    That's fine, I don't reach for the sky (at least not yet). :)

    Thanks a lot for the help. I'm sure I'll get helped from the
    "core-thinking". It all sounds very reasonable.
    Tim Cambrant, Sep 6, 2003
  10. Tim Cambrant

    Matt Gregory Guest

    I think you want to learn how to identify the different functionings of a
    program that can be written independently of each other. You want to
    strive to create your programs as a bunch of black boxes that allow you to
    forget about the internals of the functions and only give you the interfaces
    (typically function prototypes) to worry about. Then, theoretically, you
    can just glue the boxes together and not worry about it. This can be done
    with both code and data. For example, take the ctype.h header. On my
    machine the isalpha(), isdigit(), etc. functions are implemented as macros
    that perform indexing into a lookup table. If you just had the table it
    would be a pain in the ass to figure out if a character is alphanumeric or
    whatever. You would have to go "if (_pcchar[c] & _ALNUM)" or something
    completely strange. Luckily, ctype.h provides a handy interface so you can
    just say "if (isalnum(c))" and you don't have to worry about remembering
    cryptic names. When programming in C, you want to get into sort of a
    library writing mentality, since most C programming is about building up
    the language to match the problem you are working on, otherwise your
    program logic will be drowning in statements mostly devoted to bookkeeping
    and low level grunge like string handling and error checking.

    There's a poster around here by the name of Phlip, and he always talks
    about the value of unit testing, which is a methodology where you take a
    part of your program and write a separate program that tests that one part
    extensively. The benefit of writing a separate program is that it's easier
    to create different scenarios that bombard the unit without having a bunch
    of extraneous code in the way. Say you were implementing some functions
    like those in ctype.h and you just got done writing an isalnum() function.
    You could write a unit test that cycles through all the characters in
    whatever character set you are using (e.g. ASCII) and prints the results
    of all their isalnum()'s to a file. You then look over the output and say,
    "ok, that looks good" and recompile your main program and continue with
    something else. Maybe later you decide, "oh, this program is real dog...
    this profile says isalnum() is taking up 95% of the execution time! I
    better do something to speed that up!" So you reimplement it with a faster
    algorithm. Now you can just recompile and run your unit test and just use
    diff or something to compare the new output with the old output and if it
    matches you don't need to worry about it. If it doesn't match, you'll have
    a pretty good idea where the bug is. I've just started doing this recently,
    but I've found that it really does save a lot of time. It makes debugging
    far more interactive and gives you more confidence in your code. But the
    reason I went off on this tangent in the first place is that I think it
    also helps you to make your code more modular by having to isolate it enough
    from the rest of your program to make a unit test for it.

    Matt Gregory
    Matt Gregory, Sep 7, 2003
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.
Similar Threads
There are no similar threads yet.