# FeaturedC/++/# I Learned C, Now What?

1. Nov 21, 2016

### Staff: Mentor

So I'm about to be done with my first class in programming where we learned C programming. Unfortunately, I don't actually know what you can do with it. All of our programs in my class have involved us programming and running everything using Visual Studios, not developing standalone executables or something. The only way we've had our programs interact with the 'outside world' is through the keyboard and screen or through text files.

To be honest I feel like I've been trained to use a lot of specialized tools but don't have any use for them. Perhaps like a carpenter with no wood and no work.

I've also considered learning something like C# and I'm just curious as to what the differences are in what you can develop with each one, if there are any differences of course. I know that C# is a much higher language than C, but the extent of my knowledge mostly ends there. If I'm not looking to develop blazing-fast programs for huge amounts of calculations, is C# a good choice? I don't really have an specific applications that I'm thinking of.

Thanks.

2. Nov 21, 2016

### phyzguy

Rather than learn another language, I would suggest that you get more comfortable with C and figure out how you can apply it. You must have something you would like to calculate. Think of something and try to implement it in C. I think I recall you are interested in astrophotography and image processing, why don't you try to write a program in C that would do some image processing that you are interested in. The people here can help when you get stuck (which you will).

3. Nov 21, 2016

### Staff: Mentor

For the me, the best way to learn a language was to try writing a game. However with your interest in Physics perhaps a simulation would be more fun.

Here's a tutorial on using OpenGL with C programming to do stunning graphics.

http://www.opengl-tutorial.org/beginners-tutorials/

http://www.opengl-tutorial.org/miscellaneous/building-your-own-c-application/

From here, you can start to learn the debugger, graphics and real-time programming, all great skills to have under your belt.

4. Nov 21, 2016

Staff Emeritus
A one question C quiz. If a[3] = 7, what is 3[a]? If it will throw an error, which one?

There are a number of schools where a CS degree involves learning a bunch of languages, but not anything in data structures, algorithms, numerical methods, etc. I don't much care for these programs. Someone who knows one language well and knows how to program can figure out other languages if needed. If you can't code in one language, though, you probably can't code in any. Google "Fizzbuzz" for rants about this.

(And, for fizzbuzz fans, there's this - http://joelgrus.com/2016/05/23/fizz-buzz-in-tensorflow/ )

5. Nov 21, 2016

### Staff: Mentor

V50 makes a good point. C is about structs, pointers and memory allocation and so learning how to use them effectively in implementing lists, stacks and queues would improve your skills greatly. C is also about working with system resources so learning about how to navigate the file system, read/write ascii, binary and random files would also be good.

Which brings me back to games and neural nets that incorporate many of these features.

Also it will require that you learn how to use the debugger at the command line or in your favorite IDE.

6. Nov 21, 2016

### Staff: Mentor

I believe 3[a] will give an error since a is an array whose 4th element holds a value of 7. As for which error, I'm not sure what you're asking. Are you asking about an error when trying to compile?

Ha! I've already made a really, really simple RPG game in C and I've done both video game programming and simulation programming in a video game creator program (one that doesn't require any real 'coding', making it easy to use but nearly impossible to do anything more than the basics with). Just some simple things like make the Earth orbit the Sun without flying off into oblivion using my knowledge of basic mechanics from the physics class I was in at the time.

Indeed. I don't even know what "debugger at the command line" and "favorite IDE" mean.

Thanks, Jedi!

Certainly. I guess I'm currently trying to figure out how to do things without be forced to use text files and a screen output that only does text (at least, that's all we've been taught in class).

7. Nov 21, 2016

### Staff: Mentor

IDE means Integrated Development Environment (ie no more coding with a text editor alone)

Eclipse and Netbeans are the top dogs here, free and powerful:

https://eclipse.org/ide/

https://netbeans.org/

Learn to use them, learn to appreciate them, learn to like them. Others include:

http://codecondo.com/top-10-ide-for-c-and-cplusplus-for-programmers/

Both Eclipse and Netbeans have builtin debuggers for Java and I think for C/C++ too. Here's the one for Eclipse

Command line wise gdb is the debugger most real programmers (when they cant use the IDE) use:

https://www.gnu.org/software/gdb/

And then there's cvs, svn and git but I digress...

8. Nov 21, 2016

### Staff: Mentor

Thanks Jedi. I'll take a look at them.

9. Nov 22, 2016

### Staff: Mentor

No and yes. For the "no" response, 3[a] is perfectly valid, and is the same semantically as a[3]. The reason for this has to do with the near equivalence of arrays, which are a kind of pointer, and pointers. The value of the symbol a is its address of the first byte of the memory allocated for the array. That is, a == &(a[0]). We could also say that a + 0 == &(a[0]). Similarly, a + 1 is an address; namely the address of the element of the array whose index is 1. In short, a + 1 == &(a[1]). Continuing in the same vein, a + 2 == &(a[2]) and a + 3 == &(a[3]).

In the expressions a + 1, a + 2, and a + 2, I'm using an operation called pointer addition, which works differently from normal addition. The result of pointer addition depends on the type of pointer you're working with, so a + i will give different values if a is declared as an array of char versus a being declared as an array of int.
This way of addition might seem odd, but it's consistent with how array indexing works. If we have these declarations:
Code (C):

char str[5];
int list[5];
str[0] is whatever element happens to be the first element in the str array, and str[1] is the next element of this array, located one byte higher in memory.
list[0] is whatever element is the first in that array, but list[1], the next element, is 4 bytes higher in memory, assuming a system with 4-byte int types.

So if str holds the hypothetical address 0x1000, then str[1] will be at location 0x1001. If list holds the hypothetical address of 0x1100, then list[1] will be at location 0x1104. The point is that str + 1 is an address 1 byte higher, while list + 1 is an address 4 bytes higher.

Back to the 3[a] thing:
You clearly understand what a[3] means, which ties into my "yes" response. We could also write this as *(a + 3). Because addition has to be commutative, this is the same as *(3 + a), right? Taking it one step further, that last expression is the same as 3[a], no doubt a bit unsettling, but true nonetheless.
For the yes response, a[3] represents the 4th element of the array a.
Yes, that's what he was asking.

You can use Visual Studio (not Studios) to create executables that can be run standalone. It's not difficult to do.
Which is perfect for focusing on the programming, and not getting tangled up in Windows programming. It's easy to make a very flashy Windows program with lots of visual controls, that doesn't really do much. Writing console apps, which is what it sounds like you've been doing, is just right for a course with a strong focus on actual programming.

10. Nov 22, 2016

### Staff: Mentor

Huh. I've never seen array syntax like 3[a] before, so I wasn't aware of that.

Indeed.

11. Nov 22, 2016

My $0.02: get a copy of (the latest edition of) The C++ Programming Language by the master himself, and work through it. (There are exercises and errata lists on his webpage.) Or, less daunting, try his "Programming -- Principles and Practice Using C++" or "A Tour of C++" (mentioned on the same webpage). It's a limitation of ordinary C language courses that they rarely emphasize how to express one's high level abstract ideas directly in terms of structured programming constructs. With C++, that happens with far more immediacy (e.g., classes, inheritance, etc). 12. Nov 22, 2016 ### Borg 13. Nov 22, 2016 ### Vanadium 50 Staff Emeritus Exactly. Often a class will teach you a language, but never get to why you would pick that language as opposed to some other. What problems is it especially good at solving? Teaching students syntax and expecting them to be good at programming is like handing them the baseball rule book and expecting them to hit homers. 14. Nov 22, 2016 ### Nidum Try some engineering applications where you can control things and monitor things and generally make real devices do what you want . Real world applications programming is a thousand times more challenging and more interesting than just shuffling fictional data sets around and doing pointless graphics . Last edited: Nov 22, 2016 15. Nov 22, 2016 ### anorlunda If your purpose is to learn the concepts rather than become a practitioner, I agree with @strangerep that a book is better than a course. After using C for several years, I learned about the object paradigm from Stroustrup's book.. It was intellectually delightful. But keeping with the KISS principle, I still prefer Bjarne Stroustrup's original 1991 book above his latest book. It explained the rationale and implementation of objects superbly, without distractions from too many details and overblown language features You can still buy a copy of that book for$0.01 plus shipping; that's hard to beat.

16. Nov 22, 2016

### Svein

Now and then you have to program on "bare metal" - no operating system, no libraries, just some hardware. Then you have to use "C" without any libraries...
Code (C):
/*-----------------------------------------------------------------*/
/* The part of the flash programming that functions that stays in  */
/* flash (and must therefore not be allowed to be erased)          */
/*-----------------------------------------------------------------*/

#include "pFlash.h"

/*------------------------------------**
** Write a byte to a given address.   **
** Used in order to avoid optimizing. **
**------------------------------------*/

static void fpUBout(unsigned int addr, unsigned char val)
{
}

/*------------------------------------**
** Used in order to avoid optimizing. **
**------------------------------------*/

{
}

/*****************************************************************************
|*
|*  FUNCTION:           se_initialize_port
|*
|*  DESCRIPTION:
|*
|*      Initializes the serial port
|*
*/

void
se_initialize_port(void)
{
/* First, set up the interrupt vectors to point to the Rx and Tx handlers! */

/* I do not know how to do this... */

/* Then initialize serial port registers */

fpUBout(UxBRG, UB_19200);           /* baudrate 19200 */
fpUBout(UxMR, 0x5);                 /* no parity, 8 data-bits, 1 stop-bit, internal clock */
fpUBout(UxC0, 0x10);                /* no cts/rts, prescaler = F1 */
fpUBout(UxC1, 0x5);                 /* enable receiver and transmitter */

fpUBout(UCON, UxIRS);              /* TX complete */

#ifdef USE_TX_INT
*(unsigned char *)SxTIC |= 0x6;               /* Set UART transmit interrupt priority */
#endif
*(unsigned char *)SxRIC |= 0x6;               /* Set UART receive interrupt priority */

cb_init(&cb_si, INPUT_BUFFER_SIZE);

fpUBout(PD6, (fpUBin(PD6) & 0x0B) | 0x08); /* PD6_3 = 1; PD6_2 = 0; */
}

/*****************************************************************************
|*
|*  FUNCTION:           se_putchar
|*
|*  DESCRIPTION:
|*
|*      Transmits a character
|*
*/

void
se_putchar(unsigned char ch)
{
while ((fpUBin(UxC1) & UART_TI)==(unsigned char)0)
{
/* empty loop */
}
fpUBout(UxTBL, ch);
}

/*****************************************************************************
|*
|*  FUNCTION:           se_putnchar
|*
|*  DESCRIPTION:
|*
|*      Transmits a number of characters
|*
*/

void
se_putnchar(unsigned char *buffer, unsigned int size)
{
unsigned int i;
for (i = 0; i < size; ++i)
{
se_putchar(buffer[i]);
}
}

/*--------------------------------*/
/* Send the character pair CR/LF  */
/*--------------------------------*/

static void txCRLF(void)
{
se_putchar(chCR);
se_putchar(chLF);
}

/*-------------------------------------------*/
/* Transmit a string (terminated by a '\0')  */
/* followed by a CR/LF pair                  */
/*-------------------------------------------*/

static const char OKmsg[] = "OK";

static void println(const char *buf)
{
unsigned char *ptr;

ptr = (unsigned char *)buf;
while (*ptr!=(unsigned char)'\0') {
se_putchar(*ptr);
ptr++;
}
se_putchar(chCR);
se_putchar(chLF);
}

/*****************************************************************************
|*
|*  FUNCTION:           se_getchar
|*
|*  DESCRIPTION:
|*
|*
*/

unsigned char
se_getchar(void)
{
unsigned char ch;

while (cb_isempty(&cb_si)!=0) {
pollRx();
}

ch = si_buf[cb_si.read];     /* get character from serial buffer */

cb_next_rd(&cb_si);
return ch;
}

/*****************************************************************************
|*
|*  FUNCTION:           se_getnchar
|*
|*  DESCRIPTION:
|*
|*
*/

void
se_getnchar(unsigned char *buffer, unsigned int size)
{
unsigned int i;
for (i = 0; i < size; ++i)
{
buffer[i] = se_getchar();
}
}

/*------------------------------------------------*/
/* Read one line into the specified buffer.       */
/* Terminate the string with '\0' and return the  */
/* length of the string.                          */
/*------------------------------------------------*/

static int readln(/*@out@*/ unsigned char *buf, int max)
{
int  j;
unsigned char ch;
ch = '\0';
for (j=0;(j<max-1) && (ch!=chCR);j++) {
ch = se_getchar();
if ((ch!=chCR) && (ch!=chLF)) {
/*          Do not save return or newline */
buf[j] = ch;
}
}
buf[j] = '\0';
return j;
}

/*---------------------------------------------------**
** Insert one hex character in a byte.               **
** We assume that the high nibble arrives before the **
** low nibble, so we shift the previous value left   **
** 4 places before inserting the new value           **
**                                                   **
** Returns: 0 if    conversion OK,                     **
**         -1 for illegal hex character              **
**---------------------------------------------------*/

static int hex2nibble(unsigned char hex, unsigned char *retv)
{
char temp;
temp = '\0';
if ((hex>='0') && (hex<='9'))
temp = hex - '0';
else {
if (hex>='a')     /* We might get lowercase input, so convert */
hex -= HI2LO;
if ((hex>='A') && (hex<='F'))
temp = hex - ALFA2NIB;
else {
return(-1);
}
}
*retv = (*retv << 4)  + (unsigned char)temp;
return(0);
}

/*---------------------------------------**
** Convert two hex characters to a byte. **
** We use hex2nibble above.              **
** Returns: 0 if    conversion OK,         **
**         -1 for illegal hex character  **
**---------------------------------------*/

static int hex2byte(unsigned char *hstring, unsigned char *retv)
{
unsigned char temp;
*retv = '\0';
temp  = '\0';
if (hex2nibble(hstring[0], &temp)!=0)
return(-1);
if (hex2nibble(hstring[1], &temp)!=0)
return(-1);
*retv = temp;
return(0);
}

/*---------------------------------------------------*/
/* Convert four hex characters to an unsigned short  */
/* (MSB first) Use hex2byte above.                   */
/* Returns: 0 if conversion OK,                      */
/*         -1 for illegal hex character              */
/*---------------------------------------------------*/

static int hex2us(unsigned char *hstring, unsigned short *retv)
{
unsigned char  temp;
unsigned short cnvres;
temp = '\0';
*retv = 0;
if (hex2byte(hstring, &temp)!=0)
return(-1);
cnvres = temp;
cnvres <<= 8;
if (hex2byte(hstring+2, &temp)!=0)
return(-1);
cnvres += temp;
*retv  = cnvres;
return(0);
}

/*---------------------------------------*/
/* Helper function: Copy a memory block  */
/*---------------------------------------*/

static void copymem(unsigned char *src, unsigned char *dst, unsigned short len)
{
while (len!=0) {
*dst++ = *src++;
len--;
}
}

/*-------------------------------------------------*/
/* Helper function: set a memory range to a value  */
/*-------------------------------------------------*/

static void fillmemw(unsigned short *addr, int len, const unsigned short fill)
{
while ((len--)!=0) {
}
}

See what I mean?

17. Nov 22, 2016

### Staff: Mentor

Any suggestions for a guy with no money?

18. Nov 22, 2016

### houlahound

Buy some cheap passive components like light dependent resistors and make a data logger and graphing tool, total cost a few bucks.

Problem I was given in undergraduate was to write a program to divide numbers and polynomials without using any special library built in routines.

Harder than you think, its all subtraction.

19. Nov 22, 2016

### rcgldr

You need to pick some algorithms interesting to you, even if it's just for a learning experience. Sort programs are common for students. In the old days when Fortran was the intro language, solving the quadratic equation was a typical learning program. If you are running on Windows, you can use Visual Studio Express editions for free. They include an IDE, source level debugger, ... . I only know enough C# to be able to convert a C program into C#, which I've mostly done to help students. In my case, it's the same with Java, I can help with existing java programs or convert C to Java. For Java I use Netbeans for the IDE.

In my case, most of my actual jobs involved multi-threading operating systems, first with mini-computers, later with embedded software. The operating system stuff was interesting, but most of the time was spent with fairly mundane code for each thread, mostly event driven message handling (what to do next, similar to a Windows app), I/O and data conversion. At a peripheral company, I got heavily involved with Reed Solomon error correction code, but that's an extremely small niche aspect of math / programming.

Most languages are fairly similar. For object oriented languages, once you get to the methods, it's normal procedural based programming. For something really different, there's APL (A Programming Language), with a large number of operators (single greek letters) operate on scalars or multi-dimensional arrays. Some consider APL to be a "write only" language (it's difficult to read someone else's program unless you're really good at APL). COBOL has some high level operators like move corresponding (it moves and formats an input structure to an output structure based on common names in the structures), but unless you're working at a banking related company, there's not much call for it. Database languages are also like a different class of programming, but again, is this something that interests you.

Last edited: Nov 22, 2016
20. Nov 22, 2016