C Programming: What's Next After Learning C?

  • Thread starter Drakkith
  • Start date
  • Featured
In summary: If you can't code in one language, though, you probably can't code in any.This is true, but I also think that you can still learn a lot of useful things even if you can't code in a particular language. For example, I think that I've learned a lot about programming by reading code and trying to understand how it works and how to make it do what I want.
  • #1
Drakkith
Mentor
23,093
7,502
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.
 
Technology news on Phys.org
  • #2
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).
 
  • Like
Likes Drakkith
  • #3
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.
 
  • Like
Likes Aufbauwerk 2045, Electron Spin, Buffu and 2 others
  • #4
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/ )
 
  • Like
Likes QuantumQuest, Charles Kottler, cnh1995 and 4 others
  • #5
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
Vanadium 50 said:
A one question C quiz. If a[3] = 7, what is 3[a]? If it will throw an error, which one?

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?

jedishrfu said:
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.

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.

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

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

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

Thanks, Jedi!

phyzguy said:
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.

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
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

http://help.eclipse.org/neon/index.jsp?topic=/org.eclipse.cdt.doc.user/tasks/cdt_t_debug_prog.htm

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

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

And then there's cvs, svn and git but I digress...
 
  • Like
Likes Drakkith
  • #8
Thanks Jedi. I'll take a look at them.
 
  • #9
Vanadium 50 said:
A one question C quiz. If a[3] = 7, what is 3[a]? If it will throw an error, which one?

Drakkith said:
I believe 3[a] will give an error since a is an array whose 4th element holds a value of 7.
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:
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.
Drakkith said:
As for which error, I'm not sure what you're asking. Are you asking about an error when trying to compile?
Yes, that's what he was asking.

Drakkith said:
All of our programs in my class have involved us programming and running everything using Visual Studios, not developing standalone executables or something.
You can use Visual Studio (not Studios) to create executables that can be run standalone. It's not difficult to do.
Drakkith said:
The only way we've had our programs interact with the 'outside world' is through the keyboard and screen or through text files.
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.
 
  • Like
Likes cnh1995
  • #10
Mark44 said:
No and yes. For the "no" response, 3[a] is perfectly valid, and is the same semantically as a[3].

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

Mark44 said:
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.

Indeed.
 
  • #11
Drakkith said:
I've also considered learning something like C# [...]
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).
 
  • Like
Likes anorlunda and Drakkith
  • #13
jedishrfu said:
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.

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.
 
  • Like
Likes symbolipoint and QuantumQuest
  • #14
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:
  • #15
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
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:
/*-----------------------------------------------------------------*/
/* 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)
{
    *(unsigned char *)addr = val;
}

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

static unsigned char fpUBin(int addr)
{
    return(*(unsigned char *)addr);
}   /*****************************************************************************
|*
|*  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:
|*
|*      Receives a character
|*
*/
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:
|*
|*      Receives multiple characters
|*
*/
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) {
        *addr++ = fill;
    }
}
See what I mean?
 
  • Like
Likes Drakkith
  • #17
Nidum said:
Try some engineering applications where you can control things and monitor things and generally make real devices do what you want .

Any suggestions for a guy with no money?
 
  • #18
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
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:
  • Like
Likes Drakkith
  • #22
jedishrfu said:
You've been featured! Congratulations!

I'd like to thank all the code I mangled to get to where I am today...
Without you, there would be no me.

return(0);
 
  • Like
Likes Biker
  • #24
Svein said:
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...
Umm,... but you'll need a cross-compiler. Hence one might as well use a C++ cross-compiler. Some essential libraries usually come with the cross-development environment. :oldbiggrin:
 
  • #25
Drakkith, programming is like riding a bicycle. You don't learn it by reading books you learn it by DOING it. For advanced concepts in data structures and stuff yeah, you DO need to read up on it first, but the most important thing is to find something that really interests you that would involve programming and do that. If it's computer control of lights and relays great. If it's not, great. It really doesn't matter. The only thing that matters is that YOU find it interesting, otherwise it just becomes another exercise.

What kind of things do you do with your computer that do NOT involve programming? See if any of them lend themselves to learning something more about them by doing programming (perhaps of a scaled down version of using formal apps).

EDIT: Oh, and I second the idea that before moving on to OOP (which IS very neat) you should first become totally familiar w/ procedural programming because that is the basis for OOP syntax, system calls, and much other important stuff.
 
  • Like
Likes QuantumQuest and Drakkith
  • #26
You're interested in astronomy right? Why try to write a program that will take TLE data and spit out observation times based on lat/lon using some kind of orbital model? Kinda like https://www.agi.com/products/stk/ or something.

Starting off with a simple command line program shouldn't be too hard, read file in, write data to variables, play with variables. print data.

You can even do graphics, with OpenGL after you've gotten into it a bit.
 
  • Like
Likes Drakkith
  • #27
Some years ago, when I learned object oriented programming, I wrote a program that could convert numbers from any base to any other base. You also could do the four basic operations with two numbers that are in different bases and get the result in a desired base. It was a big class with all the operators overloaded. It was a lot of fun. Maybe you can try that.
 
  • Like
Likes Drakkith
  • #28
strangerep said:
Umm,... but you'll need a cross-compiler. Hence one might as well use a C++ cross-compiler. Some essential libraries usually come with the cross-development environment. :oldbiggrin:
Well, not always. The reason I showed this particular code was that it was intended to be a frontend for downloading patches to a small controller. The resulting code should be inserted in a Flash EPROM that was almost full, so no libraries were allowed (otherwise why would I have bothered re-inventing converting ASCII hex format to binary?).
 
  • #29
You can also do a character based GUI using curses or building your own api from ANSI escape codes:

https://en.wikipedia.org/wiki/ANSI_escape_code

You could build a VI like editor, source code viewer or cool ANSI artwork:

jp2a_image_to_ascii_kitten_screenshot.png

The codes were quite popular before there were graphics cards for monitors.

I use these codes in many of my scripts where I want the script to work even when shelling (via ssh) into another computer.
 
Last edited:
  • Like
Likes dlgoff
  • #30
I never enjoyed programming just for fun. I like it as an automation tool that helps me complete tedious or tricky tasks. If you have something in your job like that, you might look for a way to automate it. That might influence what language you want to work in. If you have a lot of jobs like that, you might find programming addictive. I have always enjoyed Perl programming because it allowed me to easily automate processes that I would otherwise have to do by hand (call a program, parse that program output, do some logic or calculations, output results, call the next program, etc.) It's amazing how many engineering tasks have parts that are tedious and long.

PS. Don't underestimate things like Excel scripts. There are good programmers that do a lot in Excel.
 
Last edited:
  • Like
Likes Drakkith
  • #31
Most of my data collection, numerical modeling, and analysis programming has been done in C, with a bit of Fortran and LabVIEW mixed in for good measure.

The best follow-up on a programming course for a physicist is likely a numerical analysis type course, likely taught in the math department.

I've written code for real time data acquisition, Fourier analysis, integrating differential equations, and lots and lots of other stuff.

Expand that tool box.
 
  • Like
Likes Drakkith
  • #32
Have you written the recursion program for "Newton's method" yet?
It's a good one.
 
  • #33
I'm surprised no one has mentioned Python. I'm learning Python now as part of my grad school curriculum but I chose it initially to do cool physics visualizations ala VPython simulations I found on this guys channel:



A guy that works in my lab has also encouraged me to learn Java. Matlab is good to know too.
 
  • Like
Likes jedishrfu and Drakkith
  • #34
OmCheeto said:
Have you written the recursion program for "Newton's method" yet?
It's a good one.

I get several different hits for that when I search for it. Which one are you referring to?
 
  • #35
DiracPool said:
I'm surprised no one has mentioned Python. I'm learning Python now as part of my grad school curriculum but I chose it initially to do cool physics visualizations ala VPython simulations I found on this guys channel:



A guy that works in my lab has also encouraged me to learn Java. Matlab is good to know too.


Python wasn't mentioned because the thread topic is about doing something in C. Drakith could write some C code that interoperates with Python, Java, MATLAB or Julia as an interesting use of C.
 

Similar threads

Back
Top