#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2012
    Posts
    7
    Rep Power
    0

    General C and C++ learning question


    I have several questions related to learning C and C++ :

    1. I know learning C before C++ isn't necessary but is there any benefit of learn C first and then C++ or it is just waste of time ?
    2. Is it worth to learn both C and C++ or just C++ ?
    3. For which programming task C is better then C++ and vice versa ? (yes I know it may be confused but I am looking for clear cases where is better to use C over C++ and vice versa. Something like perl and php are similar and both can do almost the same but perl is better for text processing)
    4. I've heard "Learning C you will understand how a computer actually works" well may you explain what exactly (which feature of C) are involved in this thought ?
    5. If I learned C first and then move to C++ and write code learned from C will it works or take me another half a year learning differences ?
    6. So far I wrote console aplication how to create real OS aplication with graphic like buttons, fields etc ?

    If you feel you are able to answer these question I will appreciate it ;)

    Thanks for reasonable answers.
  2. #2
  3. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,254
    Rep Power
    2222
    There are differing opinions about some of those questions that can touch off religious wars (and very nearly have). My opinion is not considered hep and with-it, but I will render it.

    #1. I support learning C first and then C++. The main reason is that there are features of C that still exist in C++, but which C++ textbooks and tutorials will tell you nothing at all about. You will encounter those features very often in the source code of others, so knowledge of those features must be part of a C/C++ programmer's education. I became aware of this gaping hole in C++ instruction when experienced C++ programmers had to post their questions here for working with C-style strings and these experienced C++ programmers were totally lost.

    These features include:
    a. C-style strings. There is a definite discipline that must be learned and practiced with working with strings in C, plus there is a library of string functions that you can use to work with strings. And in C++'s first decade, C++ did use C-style strings -- consider the C++ methods in iostreams that require C-style strings as their arguments, as well as the strstream class which is for C-style strings.

    Because of the discipline required and because it is easy to make mistakes, practically every C++ programmer would have as his first project the implementation of a string class. Then the 1998 standard introduced the basic string class, string, which replaced C-style strings. Then nearly every C++ textbook would only teach the basic string class and never mention C-style strings nor even that such a thing exists.

    C++ still fully supports C-style strings. The basic string class is a better choice since it is easier, safer, and more intuitive to use. However, you should still be aware of C-style strings and how to use them, since you will encounter them often.

    b. C-style I/O. C has a set of input/output functions that includes support for formatted I/O. C++ still supports all those functions, plus it has a class library called iostream, which does not support formatted I/O. C++ instructional materials only teach iostreams and make no mention of C-style I/O. Therefore, when C++ programmers who lack any C background encounter the C I/O functions, they are unable to comprehend what's going on.

    In my professional work, I started out with Pascal and graduated to PC programs in Turbo Pascal. In order to display or even create a string with variable values embedded in them, I'd have to write several separate procedure calls (ie, write the first part of the string, write the first variable, write the next part of the string, write the next variable, etc), making the code cumbersome, but then that was all that I knew. One of the first things I learned in C was the *printf function, in which I was able to display or create a string with any number of embedded variable values all in one single function call. That was when I fell in love with C.

    iostreams requires you to break up the same process into separate pieces, just as I had to do in Turbo Pascal, except I didn't need to make separate function calls. In addition, any formatting of a variable's value has to be chained in as yet another separate piece to be followed by another separate piece to change the format back. To me, iostreams was a big step backwards, back to Turbo Pascal, only more cumbersome. I learned C++ in 1990. I still don't use iostreams. Sure, there are a few advantages to it, such as defining how to output an object, but I simply have no need for it.

    c. malloc/free. You should only see these in a C program. Even though C++ can still support them, you should only use the C++ equivalents, new and delete. This is not a gaping hole, but just something that's different that you should be familiar with.

    The first part of learning C++ is to learn the C syntax that C++ inherited. If you learn that syntax without learning C, then you will have gaping holes in your knowledge. If you learn that syntax by learning C first, then you will have a much more complete education.

    The main disadvantage that has been cited for learning C first is that some of the techniques that you would learn in C could cause you form bad habits that you would need to unlearn in C++. I do not consider that to outweigh the benefits of a more complete education, but others will disagree.

    #2. When my brother-in-law, a EE student, asked his father, an electrical engineer, what areas of EE he should learn, his father told him, "All of them." Similarly, I advocate learning as much about everything as you possibly can. Therefore, I would advise learning both C and C++, even though I would also advise working mainly in C++.

    But you may not have a choice in which language you use. Most of my work is in embedded programming, plus some support GUI apps. All our embedded work is in C while our GUI apps are in C++. If I could only work in C++, then I wouldn't have a job here. Also, for the C code I might research C++ code or for C++ I might research C code. In such cases, my knowledge of both C and C++ enable me to translate between the two languages.

    #3. In tasks where C is well-suited, so is C++. However, C does not directly support object-oriented programming (OOP), so for applications where you're using OOP (eg, in the development frameworks for GUI applications), you must use C++ (or another OOP language such as Java or C#).

    #4. In both C and C++, you do need to understand what the code is doing. Both use pointers, which are memory addresses. In both languages, you need to be aware of the size of your data types and how they are formatted. In both languages, you need to understand such things as how local variables are stored and what the consequences of that are. Plus both languages offer you the same low-level access to your computer.

    #5. I'd say you could do it in less than a day, easily. To get an idea, read the Wikipedia article, Compatibility of C and C++.

    #6. Console applications are real OS applications. GUI apps are little more than syntactic sugar.

    You can write Windows applications in C. At a used bookstore or in your school library track down a copy of Charles Petzold's book, "Programming Windows X.x" (for X.x, substitute any version of Windows up to 3.1 and including 95; it's basically the same book updated for each successive version of Windows). His approach used the Software Development Kit (SDK) and is hence referred to in general as "SDK". This is the lowest level programming of Windows; you have to set everything up and you have to handle everything, but at the same time you will learn what's going on in a Windows application.

    Most programmers use a framework, such as Microsoft Foundation Classes (MFC) or now .NET. These frameworks handle the details of SDK programming for you, hiding those details (and hence keeping you from learning as much). These frameworks are object-oriented and hence require you to use C++ or another suitable language that supports OOP.
  4. #3
  5. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,413
    Rep Power
    1871
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  6. #4
  7. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2012
    Posts
    7
    Rep Power
    0
    @dwise1_aol's thank you for your answer, it helped a lot.

    I wonder how linux or windows built their GUI ? I mean now we have API support and so on, but they didn't. How it works ?
  8. #5
  9. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,254
    Rep Power
    2222
    Research it.

    Linux per se does not have a GUI. Linux is an OS. It has a kernel, a number of drivers, and some utilities, which includes shells and X Windows. Read up on X Windows.

    As for Microsoft Windows, research the history of its development. Windows 1.0 through 3.11 ran on top of MS-DOS. Each of those versions had an API. Then with Windows 95 (though that started earlier with Windows NT), the GUI became part of the OS, but it was still the case that there's a kernel with the GUI running on top of it. And the current API is just a further evolution of the earlier APIs, so your presumption that the developers didn't have one is baseless. In any such project, even in the creation of the very first version, the developers create the API as part of the design phase, before they even start to code any of it.

    There have been books on the subject and, I'm sure, articles and web pages on-line. Research the question.
  10. #6
  11. Contributing User

    Join Date
    Aug 2003
    Location
    UK
    Posts
    5,117
    Rep Power
    1803
    1. Learning C before C++ is often counter-productive, it can make it more difficult to "get" the OOP paradeigm, and for many C idioms, there are better solutions in C++, so you may just end up writing C++ with C acquired "bad habits". C++ is all of C and more - what's wrong with a bigger tool bag? You don't have to use or even learn to use all of the tools.
      .
    2. C remains dominant in embedded systems development. If that is likley to be what you will do, then learning C has benefts. Having said that most of the arguments for not using C++ in embedded systems are misinformed nonsense.
      .
    3. C has almost no benefits over C++. If you write C code and compile it as C++, it is C++ code, and will perform identically and occupy the same memory footprint to the same code compiled as C. Again in embedded systems, good C++ compilers may not be available on some (mostly 8 bit) architectures. The suitability for one task over another is largely dependent on libraries, and C++ can use C libraries directly as well as a large choice of C++ libraries and a standard library that includes the C library and more.
      .
    4. C is a "systems language" so is suited to directly programming hardware (though an OS may impose some restrictions on that in user level code), and working at the machine level with respect to data types and memory organisation. C++ is also a systems language, so C has no advantages there, its more extensive standard and third-party libraries abstract away from the purely systems level to make it well suited to applications level development in a way that C is arguably less suited to.
      .
    5. Its not learning the differences that would take the time, most well formed C code will compile unchanged in C++. What takes the time is learning the better way in which things may be done in C++ and the simple fact that C++ is a much larger language with a more extensive standard library. The language is distinct from the standard library, and the steepest learning curve perhaps is understanding the effective use of the library and the STL in particular. C++x11 adds even more complexity and moves C++ much further away from C - but again, you do not need to learn all of it to be effective.
      .
    6. If GUI application development is what you want to do, then C++ is what you should go with over C - most portable native code GUI frameworks use C++. Tools such as Code::Blocks and QtDesigner integrate compiler, linker, code editor, visual GUI designer and GUI framework/library in a single package making it easy to get started. Code::Blocks includes wxWidgets while QtDesigner uses Qt. Qt uses language extensions that require a preprocessing stage (through its "meta-object compiler" and "UI compiler" - moc and uic tools respectively) to turn Qt extensions into standard C++, so can be a bit daunting and may be confusing if your aim is to learn C++. There are numerous other choices for GUI development, but in C your choices are more limited and GUI development in particular lends itself to OOP.
    Last edited by clifford; December 3rd, 2013 at 04:21 PM.
  12. #7
  13. Contributing User

    Join Date
    Aug 2003
    Location
    UK
    Posts
    5,117
    Rep Power
    1803
    Originally Posted by Martin90
    I wonder how linux or windows built their GUI ? I mean now we have API support and so on, but they didn't. How it works ?
    Layers upon layers of code. Starting from low level graphics drivers writing directly to video RAM (or on a modern graphics hardware, instructing the GPU or graphics accelerator to render an object), to the window manager, and up.

    C and C++ are systems level languages, at the OS kernel and device driver privilege level, you can write directly to physical memory and memory and I/O mapped device registers, as well as communicate with graphics hardware and input devices.

    For example, at its simplest level (and this is not how modern systems work necessarily due to hardware acceleration of graphics tasks), writing a specific RGB value to an address in video RAM would set a specific pixel to a specific colour, knowing how the VRAM is mapped to the screen coordinates it is possible to implement algorithms for plotting a series of pixels to form lines, polylines, and polygons, and to fill those shapes. At yet another level you might add window management, and region clipping etc. building up a stack of software up to the UI API presented to application developers. The application code then is just yet another layer. Each layer in this software (and ultimately hardware) stack abstracting from the lower layer providing increasing functionality with each layer.

    The APIs are just interfaces to libraries of code developed just like any other. That code is likely to have been generated from a mix of assembler, C and C++ (or in Linux more likely just assembler and C, and in OSX perhaps assembler, C, C++ and Objective-C) , in the end though because these are compiled languages, it is all machine-level code by the time you get to use it.
    Last edited by clifford; December 3rd, 2013 at 04:17 PM.
  14. #8
  15. Banned ;)
    Devshed Supreme Being (6500+ posts)

    Join Date
    Nov 2001
    Location
    Woodland Hills, Los Angeles County, California, USA
    Posts
    9,643
    Rep Power
    4248
    Originally Posted by dwise1_aol
    b. C-style I/O. C has a set of input/output functions that includes support for formatted I/O. C++ still supports all those functions, plus it has a class library called iostream, which does not support formatted I/O. C++ instructional materials only teach iostreams and make no mention of C-style I/O. Therefore, when C++ programmers who lack any C background encounter the C I/O functions, they are unable to comprehend what's going on.
    Actually, the iostream stuff does support formatted I/O. There is not a single format type that printf() supports that I/O stream does not. They are just supported in different ways. As a matter of fact, the C++ way is sometimes a bit more flexible. For instance, if you want to print a number upto 4 digits long, left padded with 0s as needed:
    Code:
    C:
    int foo = 4;
    printf("%04d", foo);
    
    C++:
    int foo = 4;
    std::cout << std::setw(4) << std::setfill('0') << foo;
    Of course, the C version is much more compact than the C++ version. But does that mean it is necessarily more powerful?

    Ok, let's say foo is a string instead of int, and you want to do the same thing:
    Code:
    C:
    char *foo = "4";
    printf("%04s", foo); // <---- This won't work and compiler may warn about the format specifier
    // output is printed with leading spaces instead of 0
    
    C++:
    std::string foo = "4"; // or char *foo = "4";
    std::cout << std::setw(4) << std::setfill('0') << foo; // Works fine
    Even more fun, say I want to left-pad a string with some other fill character instead of space (say, I want to use '*'). With C, the printf() family doesn't support this:
    Code:
    C++:
    string foo = "abc";
    std::cout << std::setw(4) << std::setfill('*') << foo; // Works fine
    And now for a much more painful example:
    Code:
    C:
    #include <time.h>
    time_t now;
    time(&now); // Get current time
    printf("timestamp = %d\n", now); // This may or may not work
    
    C++
    #include <ctime>
    time_t now;
    time(&now); // Get current time
    std::cout << "timestamp = " << now << "\n"; // This will always work
    Why does the C version say it "may or may not work". Well, that's because the ISO C standard defines time_t as an integral type, but does not specify the specific type. Therefore, depending on your compiler and OS, time_t may be int, unsigned int, long etc. and the format string has to be adjusted based on your environment. Of course, people can say that with gcc, they will be warned if the format string is incorrect for the type (assuming they're compiling with -Wall AND using a more recent gcc compiler), but this particular one is painful for me because in the real-world case, the code was more like:
    Code:
    if (error) {
        log_message(ERROR, "Error happened: timestamp = %d, error = %d, value = %\n", now, error, value);
        return;
    }
    
    /* Custom logging function */
    void log_message(int error_level, const char *fmt, ...) {
        // Do some stuff based on error_level and ...
        // then call fprintf() and pass fmt and rest of args to it.
    }
    In this case, the gcc compiler cannot catch that the format string was incorrect, since it doesn't see the actual format string at the point where fprintf() is called (only sees the variable 'fmt' passed to fprintf()). Now, the guy who wrote this bit of code wrote it on a 32-bit laptop. However, it broke in production on a 64-bit machine and yours truly was called to investigate the cause of the daemon crash. Incidentally, since the function was only called if an error happened, it didn't happen very often.

    To make the gcc compiler warn about the format string, you need to add some non-standard keywords to the function prototype:
    Code:
    void log_message(int error_level, const char *format, ...) __attribute__ ((format (printf, 2, 3)));
    This is a very gcc specific extension and not everyone knows about it either. Once I discovered how to get the gcc compiler to check the format strings, a quick recompile discovered about 150+ instances of calling log_message() with incorrect format strings in the code, written by multiple programmers over the years!

    With C++ iostreams, this is not an issue at all.

    Happy holidays y'all and stay safe!
    Up the Irons
    What Would Jimi Do? Smash amps. Burn guitar. Take the groupies home.
    "Death Before Dishonour, my Friends!!" - Bruce D ickinson, Iron Maiden Aug 20, 2005 @ OzzFest
    Down with Sharon Osbourne

    "I wouldn't hire a butcher to fix my car. I also wouldn't hire a marketing firm to build my website." - Nilpo
  16. #9
  17. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,254
    Rep Power
    2222
    Yep, as I said. It's like chaining Turbo Pascal procedure calls together. Giant stumble backwards.

    Plus the documentation for those formatting functions was terrible. This was back around 1990, years before there was any Web for me to search. If one of the C++ books you had didn't just happen to have the function you needed, you were SOL. I even had a fairly good book dedicated to iostreams and even its coverage of ios was sketchy.

    Still have no use for it.

IMN logo majestic logo threadwatch logo seochat tools logo