• Welcome to Powerbasic Museum 2020-B.
 

C/C++ Programming Primer For PowerBASIC Programmers

Started by Frederick J. Harris, November 04, 2009, 02:03:04 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Frederick J. Harris

     This tutorial series is to familiarize you with enough C/C++ programming knowledge to intelligently use Microsoft's voluminous Application Programming Interface documentation, and to get you started writing C or C++ programs if you desire to explore those languages.  There are several reasons why knowing some C or C++ will help you in your PowerBASIC programming.  First and most obvious is the fact that the Application Programming Interface to Windows is documented in C.  And if you ever search on the internet for code you'll likely find C or C++ examples and maybe nothing else. 

     Secondly, but just as important in my mind, C & C++ have origins and design goals very different from the BASIC family of languages.  Oftentimes in the world of computer languages you'll find that there are two fundamentally different ways of performing some task or building some language element.  BASIC family languages invariably take a path diametrically opposite from C family languages.  To cite just one example lets consider strings.  There are basically only two general ways to define a string; one way is to define it as a contiguous sequence of bytes starting at some specific address and with some marker at the end to denote its last byte; the other way is to also define its beginning but to keep track of its length as opposed to marking its end.  The C family languages have always chosen the first method and the BASIC family of languages invariably the latter.  In terms of passing function parameters, C passes by value and BASIC by reference.  The list could go on and on.  The point however is that understanding how operations are performed in a different programming language from the one you are most accustomed to will give you a deeper understanding of memory processes and algorithms in the same way that learning a second spoken language will give you broader insights into human communication and spoken/written language structure in general. 

     Thirdly, if you are at all interested in Linux you'll become an instant Linux programmer if you learn a little C or C++.  Most of the programs in this tutorial series will compile exactly as is under Linux with no changes.  The only ones that won't are those where you'll find an...

                                                           #include <windows.h>

at the top of the program in the includes.  To compile the programs under debian based systems I believe you just need to install the build-essential package.

     Fourthly, if you are interested in Windows CE/Mobile development, you'll find C language skills invaluable.  That is actually the main reason I do C/C++; About 50% of my job is developing applications for my organizations handheld devices.  With that platform PowerBASIC isn't really a choice.  Its C or nothing.  Towards the end of this tutorial I'll show a simple Windows CE C++ app and discuss it some, show differences, etc.

     My intent here is to show you very short but complete programs that explain one language element at a time, and to contrast them with similar PowerBASIC programs – mostly using the Console Compiler.  I believe I've kept most of the example programs down to a dozen lines or so for quick digestion.  However, as you know, languages naturally build on themselves, so its critical to understand even simple programs completely.   

     If you're convinced and want to get started you'll need a C/C++ compiler and development environment, i.e., a code editor.   The four that I frequently use and am more than a little familiar with for desktop work are Dev-C++, CodeBlocks, Visual C++ 6.0 and Visual C++ 9 (Visual Studio 2008).  The first two are GNU software available for free download; Visual C++ 6 is no longer available but is still in fairly widespread use through its incorporation in Visual Studio 6; and Visual C++ 9 can be downloaded for free from Microsoft at least in its Express edition.   Here are links to the Dev-C++ download...

http://www.bloodshed.net/devcpp.html

     In several ways this is my favorite development environment – especially for small testing programs like these here.  I developed these tutorials with Dev-C++.  It is the fastest and easiest environment to get started in of any C++ compiler I know.  Also, the download is only around 10 MB and the program upon install won't fill up your hard drive.

     The new CodeBlocks development environment is really nice too, but is slightly larger than Dev-C++ and a bit more involved to use (not much though).  The biggest thing CodeBlocks has going for it though is that it is cross platform and runs really well under Linux.  It can be downloaded from here...

http://www.codeblocks.org/downloads

     Choose this package -- codeblocks-8.02mingw-setup.exe.  Its around 20MB.  Visual C++ 9 Express (part of Visual Studio 2008) can be downloaded for free from this address...

http://www.microsoft.com/Express/VC/

     It is by far the largest and most complicated development environment you could choose.  Someone has even written a whole book about using Visual Studio as a completely separate topic apart from the programming you can do with it.  It'll also cost you hundreds of megabytes of storage and take up massive amounts of RAM.  Naturally, its slow as molasses in January.  However, if you are going to attack this topic in a rigorous manner over the long term it might be the route to take.

     Following are directions for starting projects to make use of the code in these tutorials assuming you've downloaded and installed one of these development environments.

Dev-C++


1)  Open Dev-C++;

2)  Go To File >> New  >> Project;

3)  Highlight 'Console Application' in the list of Project Types.  Note that  you also have the choice of 'Windows Application' or 'Dll Project'.  We may use some of those later in this series.  In the Name Textbox enter the name of your  project, such as 'ProgEx01';

4)  After clicking OK a Save As Dialog Box will appear where you'll save the Project File which will have an extension of *.dev.  I'd first recommend though that you use the Create New Directory button at top right in the Save As Dialog Box to create a new directory for the project's various files such as *.dev, *.cpp, *.h, and *.rc files.  This is just simply good housekeeping.  In fact, I'd recommend a separate directory for all  projects;

5)  Finally, you'll be presented with an initial screen where you can enter code.  It will have this in it...

   
    #include <cstdlib>
    #include <iostream>

    using namespace std;

    int main(int argc, char *argv[])
    {
     system("PAUSE");
     return EXIT_SUCCESS;
    }
   


6)  I always remove that gunk.  However, it will compile as is.  The last step is to save this source code file as Main.cpp.  You can actually save it to any name you like but I usually name my entry point file as Main.cpp.


CodeBlocks


1) In the opening screen click on hyperlink 'Create New Project';

2) A 'New From Template' Dialog will appear where you can choose the type of project to create.  For this tutorial series the right selection will be Console Application, Dynamic Link Library, or Win32 GUI Project;

3) Next you'll be presented with a dialog where you can choose whether you want a C or C++ project.  Various compiler switches are affected by this choice.  Some of my CPrimer projects are C projects (especially the first several),  and the later ones are C++.  So check my tutorials before you create a project for one;

4) Next step you need to fill in several text boxes, specifically the project title, and the directory you want the project created.  In all these tutorials named like so...

    ProgEx##

I specified a containing directory named CPrimer.  Therefore, CodeBlocks would create a ProgEx## folder under CPrimer for the project.  CodeBlocks project files are of the form *.cbp;

5) The next dialog you can specify the various configurations you want built, i.e., Debug configuration and/or Release configuration.  I'm not going to cover C++ debugging in this series and in any case I always remove the debug  configuration and just specify to create Release builds;

6) When you get through that you'll finally be presented with a  code editor window.  I find it convenient to maintain what CodeBlocks calls its 'Manager' window open and docked to the left of my code editor window.  In that window you can switch between file view and symbol view. 


Visual C++ 2008 Express/Professional

1) Microsoft's Visual C++ has various initial configuration options so your initial screen probably won't look like mine.  However, you need to do whatever you have to initially to set up a C++  project.  When I click on an option to create a new project I eventually get to a screen where I can highlight Win32 C++ project of type Win32 Console Application.  Then fill in the project name such as 'ProgEx1 and choose a directory such as CPrimer.  Also, there is a check box where you can specify to create a directory for the solution or not.  I'd say check it.

2) The next screen that comes up is titled Win32 Application Wizard - Project Name.  In the left pane are two important toggle selections entitled Overview and Application Settings.  Click on  Application Settings.  This is an important dialog.  You will be able to choose whether you want a Console Application, Windows Application, or Dll Project.  For these tutorials make sure MFC and ATL aren't checked.  Its OK to check Precompiled Headers.

Another useful type is 'Empty Project'.  That is definitely the one you would be best off checking for these tutorials, because otherwise you are going to end up with tons of junk
wizard code.  So make sure 'Empty Project' and 'Console Application' are checked.  After clicking OK you'll be presented with your 'Solution Explorer' showing your project, but there won't be any source or header files in the project yet.  You can easily create a source file by  right clicking on the 'Source Files' node in the Tree View control and choosing 'Add  >> New Item'.  Then you'll be presented with a dialog where there should be an option to select a C++ source file.  Do that and you've finally
reached the point where you can write code;

3)  At this point you should be able to paste any of the C or C++ tutorial programs of mine into your code editor window and compile them.  However, VC++ 2008 is really complicated, and there are various configuration options I think you should know about that I find useful to set, so I want to cover them for you.

4)  Note on your main menu you have a 'Build' selection.  Open that and one of the selections near the bottom is 'Configuration Manager'.  Go ahead and open that.  In the Configuration Manager Dialog under  Configuration you'll see a Debug selection.  Open that with the dropdown and choose Edit.  Then you'll get an Edit Project Configuration dialog where you can remove the Debug configuration.  I always do this.  It will only produce Release builds then which are smaller and won't contain voluminous debug symbols;

5)  Another major menu selection of which you should be aware is the 'Project' menu.  Near the bottom of that is the 'Properties' selection and there are literally hundreds of configuration settings there to control how the compiler does things.  In the left part of the Dialog is a Tree View Control with various nodes for such things as C++ code Generation, Linker settings, etc.  Under the 'General' tab you can set which character set the program should use and the choices are 'Not Set', 'Unicode', or 'MultiByte Set'.  This can be an important setting.

Under the C++ 'Optimization' heading you can choose to compile for speed or small program size, and this setting can have a major effect on program size. 


Petr Schreiber

Thanks Frederick,

your tutorials are highly welcomed from my side :)
AMD Sempron 3400+ | 1GB RAM @ 533MHz | GeForce 6200 / GeForce 9500GT | 32bit Windows XP SP3

psch.thinbasic.com

Patrice Terrier

#2
Yes, thank you!

As you stated already, sooner or later we will need to get accustomed to C, C++, especially when dealing with low level SDK programming, because C is the core meat of the API.

...
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Theo Gottwald

I still hope we will not need it in the future, when it comes to make an x64 executable. But actually we would have to ...

Frederick J. Harris

I think that's one of those things (64 bit) PowerBASIC doesn't really have a choice about - no more than in the move from 16 bit to 32 bit.  Now is probably like 1994.  Almost everybody had a 32 bit processor running a 16 bit OS. 

James C. Fuller

#5
Fred,
  Good stuff but I'm getting a number of warnings on Linux.
James

Using: gcc(g++) version 4.4.1 on ubuntu 32 bit 9.10
gcc -Wall -o Main Main.c

****************************************************************************
Project #2
Main.c: In function  main :
Main.c:33: warning: too few arguments for format
Main.c:34: warning: format  %u  expects type  unsigned int , but argument 3 has type  char *
****************************************************************************
Project #3
Main.c: In function  main :
Main.c:58: warning: type defaults to  int  in declaration of  i
Main.c:63: warning: format  %u  expects type  unsigned int , but argument 3 has type  unsigned int *
Main.c:69: warning: format  %u  expects type  unsigned int , but argument 3 has type  unsigned int *
Main.c:72: warning: format  %u  expects type  unsigned int , but argument 2 has type  unsigned int *
Main.c:73: warning: format  %u  expects type  unsigned int , but argument 2 has type  unsigned int *
****************************************************************************
Project #4
Main.c: In function  main :
Main.c:33: warning: implicit declaration of function  strlen
Main.c:33: warning: incompatible implicit declaration of built-in function  strlen
Main.c:34: warning: format  %u  expects type  unsigned int , but argument 3 has type  char *
Main.c:35: warning: format  %u  expects type  unsigned int , but argument 3 has type  char *
Main.c:36: warning: format  %u  expects type  unsigned int , but argument 3 has type  char *
****************************************************************************
Project #5
Main.c: In function  IncrOne :
Main.c:53: warning: format  %u  expects type  unsigned int , but argument 2 has type  int *
Main.c: In function  main :
Main.c:66: warning: format  %u  expects type  unsigned int , but argument 2 has type  int *
****************************************************************************
Project #6
Main.c: In function  IncrOne :
Main.c:63: warning: format  %u  expects type  unsigned int , but argument 2 has type  int *
Main.c: In function  main :
Main.c:72: warning: format  %u  expects type  unsigned int , but argument 2 has type  int
****************************************************************************
Project #7
Main.cpp: In function  int IncrOne(int&) :
Main.cpp:55: warning: format  %u  expects type  unsigned int , but argument 2 has type  int*
Main.cpp: In function  int main() :
Main.cpp:65: warning: format  %u  expects type  unsigned int , but argument 2 has type  int*
****************************************************************************
Project #9
Main.cpp:62: warning: format  %u  expects type  unsigned int , but argument 3 has type  char*
****************************************************************************
Project #10
Main.cpp: In function  int main() :
Main.cpp:25: warning: deprecated conversion from string constant to  char*
Main.cpp:26: warning: deprecated conversion from string constant to  char*
Main.cpp:27: warning: deprecated conversion from string constant to  char*
****************************************************************************


Frederick J. Harris

Hello James!

      Just tried ProgEx02 with CodeBlocks in Windows and that shows the same thing.   Apparently the latest version of printf wants this...

printf("%s", "Hello, World!");

instead of this...

printf("Hello, World!");

If there is only a string puts() (put string) can be used...

puts("Hello, World!");

Line 34 as well as most of the others are probably casting issues.  For example, this will get rid of line 34's warning...

printf("\n\n  %s\t%u\n\n", szBuffer, (unsigned int)szBuffer);

If you don't mind looking at hex 'p' is actually the format specifier for pointers...

printf("\n\n  %s\t%p\n\n", szBuffer, szBuffer);

I'm wondering if maybe I ought to go through them and add all the casts.  When I'm actually doing something with these languages I hate warnings so I always do whatever it takes to get rid of them. 

It depends on the warning levels set too.  I just checked in the CodeBlocks IDE under Build Options and I saw that the warning level was set at [-Wall], i.e., produce all possible warnings.  If you uncheck that and just check standard compiler warnings, [-W], all those casting issues go away.

Glad you are testing them on Linux. 

Frederick J. Harris

Huh!  Just learned something!  When I set up my little test above in Windows using CodeBlocks I accidentally chose a C++ program instead of a C program.  When I saw I had done that I was going to delete the project and start over but then thought "What the Heck!" and left it go. 

Then I decided to test ProgEx03 in CodeBlocks and when I did I took care to make sure to set it up as a C program instead of C++.  CodeBlocks and Dev-C++ both try to be helpful by providing a little template for you to start with and the C one looks like this...


#include <stdio.h>
#include <stdlib.h>

int main()
{
    printf("Hello world!\n");
    return 0;
}


Note they used printf just like I did without providing a format specifier, i.e., "%s"; and it compiles fine in C.  In fact, that's just about Kerrigan & Ritchie's original Hello, World! program right from C's first book and its original creators.

So the moral of the story is that there are all kinds of little discrepancies between C & C++ that keep cropping up.  I didn't know about that one though.

In C though it still produces the casting issue.  I added a little to the template above and got the warning about unsigned int...


#include <stdio.h>
#include <stdlib.h>

int main()
{
    char szBuffer[]="Frederick J. Harris";

    printf("Hello world!\n");
    printf("%s\t%u\n",szBuffer,szBuffer);
    return 0;
}


C:\Code\CodeBlks\CPrimer\ProgEx03\main.c|9|warning: unsigned int format, pointer arg (arg 3)|

Maybe I ought to go through and fix them I'm thinking now.

James C. Fuller

I got rid of the warnings in example #10 using:


const  char* pszStr1="Frederick ";
const  char* pszStr2="John ";
const char* pszStr3="Harris";


James



Frederick J. Harris

Thanks again for pointing this out Jim.  I think I'm going to go through them all and provide the casts, only use C style comments in C programs, bend over backwards, whatever it takes to remove the warnings.  Havn't gotten to 10 yet.  I'm just going to fix 5 & 6 now.  I fixed the 1st couple already.  From now on I'll run them all in CodeBlocks because that one appears much pickier than Dev-C++.

Frederick J. Harris

#10
Were you compiling #10 as a C++ program Jim?  I just tried it with CodeBlocks and didn't get any warnings on that one even with the warning level maxed out.  I havn't done any Linux command line compiling for about a year, so my memory is a littly rusty.  I think gcc is for c and g++ for C++?

James C. Fuller

Fred,
I was using Geany (ide) on Linux and it is configured to use gcc for .c  and g++ for .cpp extensions.

I just tried it on windows using MSYS and get the same warnings. What compiler is your CODEBLOCKS configured to use? If gcc what is the  version? My MSYS gcc (g++) version is 4.4.0

James


Frederick J. Harris

Hi Jim!

    I can't get that warning you are telling me about regarding ProgEx10 no matter what Warning Level I use or which of my four C/C++ compilers I use, so I guess I'll forget about it.  Not that I don't believe you, its just that I can't reproduce it here.  The CodeBlocks gccI'm using is mingw32-gcc-3.4.5    2/6/2008.  However, this past summer I wiped my XP laptop and downloaded the latest CodeBlocks, so what I'm using can't be much out of date.

    You know, that very first warning I worked on regarded the 'printf takes more than one parameter...' thing.  That got working on my mind.  I got to thinking..."That can't be right".  I went back to the original books I learned C from back in the nineties, and sure enough there are tons of printf examples like so...

printf("Hello, World\n");

I've actually never seen anything like this...

printf("%s\n","Hello, World!");

     Digression time!  I'm actually a forester, and early in my academic training I had to learn the taxonomy, identification and scientific name (Family, Genus and species) of essentially every tree, shrub, and plant that grows natively (and many non-natives) in Pennsylvania.  One of the justifications of this was that scientific names are more permanent and technically correct identifiers of plants than common names, such as, for example, Sweet birch.

     Well, let me tell you something, the scientific name of Sweet birch 'Betulaceae Betula lenta', as well as most of the rest of the plants I know has changed at least once since I learned them in the 1970s, but Sweet birch is still Sweet birch.

     Its the same deal with these stupid C/C++ functions.  Can't they just leave them alone?  That printf warning serves no useful purpose.

James C. Fuller

Fred,
  It must be a version thing. I remember now I updated my Windows gcc so it would be closer to the version on all recent Linux distros.
I think it broke (or at least it had more warnings)some code that worked with the MinGW/CodeBlocks version.
I was experimenting with cross use code at the time.

James



Frederick J. Harris

All I can think about why placing a const keyword in front of the char* pStr; declaration is that such a declaration of a pointer to associate with a literal text string constant would prevent the pointer from attempting to change the constant.  To be honest I know I've run into warnings/errors concerning that sort of thing before.  It seems though that I only get errors/warnings when I don't want them.  When I'm trying to get one I don't!