I am considering learning C
There is no specific reason not to learn C but I would suggest C++. It offers much of what C does (since C++ is a super set of C), with a large amount of "extras". Learning C prior to C++ is unnecessary -- they are effectively separate languages.
Put another way, if C were a set of woodworking tools, it would likely be:
- hammer
- nails
- hand saw
- hand drill
- block sander
- chisel (maybe)
You can build anything with these tools -- but anything nice potentially requires a lot of time and skill.
C++ is the collection of power tools at your local hardware store.
If you stick with basic language features to start, C++ has relatively little additional learning curve.
But why do people use C (or C++) if it can be used 'dangerously'?
Because some people don't want furniture from IKEA. =)
Seriously though, while many languages that are "higher" than C or C++ may have things that make them (potentially) "easier" to use in certain aspects, this isn't always a good thing. If you don't like the way something is done or a feature isn't provided, there likely isn't much you can do about it. On the other hand, C and C++ provide enough "low-level" language features (including pointers) that you can access many things fairly directly (esp. hardware or OS-wise) or build it yourself, which may not be possible in other languages as implemented.
More specifically, C has the following set of features that make it desirable for many programmers:
Speed - Because of it's relative simplicity and compiler optimizations over the years, it is natively very fast. Also, a lot of people have figured out a lot of shortcuts to specific goals when using the language, which makes it potentially even faster.
Size - For similar reasons as the ones listed for speed, C programs can be made very small (both in terms of executable size and memory usage), which is desirable for environments with limited memory (i.e embedded or mobile).
Compatibility - C has been around for a long time and everyone has tools and libraries for it. The language itself is not picky either - it expects a processor to execute instructions and memory to hold stuff and that is about it.
Furthermore, there is something known as an Application Binary Interface (ABI). In short, it is a way for programs to communicate on a machine-code level, which can have advantages over an Application Programming Interface (API). While other languages such as C++ can have an ABI, typically these are less uniform (agreed upon) than C's, so C makes a good foundation language when you want to use an ABI to communicate with another program for some reason.
Why do programmers not just use Java or Python or another compiled language like Visual Basic?
Efficiency (and occasionally memory management schemes that cannot be implemented without relatively direct access to memory).
Directly accessing memory with pointers introduces a lot of neat (usually quick) tricks when you can put your grubby paws on the little ones and zeros in your memory cubbyholes directly and not have to wait for that mean ol' teacher to hand out the toys just at playtime then scoop them up again.
In short, adding stuff potentially creates lag or otherwise introduces unwanted complexity.
Regarding scripted languages and that ilk, you have to work hard to get languages requiring secondary programs to run as efficiently as C (or any compiled language) natively does. Adding an on-the-fly interpreter inherently introduces the possibility for decreased execution speed and increased memory usage because you are adding another program to the mix. Your programs efficiency relies as much on the efficiency of this secondary program as how well (poorly =) ) you wrote your original program code. Not to mention your program is often completely reliant on the second program to even execute. That second program doesn't exist for some reason on a particular system? Code no go.
In fact, introducing anything "extra" potentially slows or complicates your code. In languages "without scary pointers", you are always waiting for other bits of code to clean up behind you or otherwise figure out "safe" ways to do things - because your program is still doing the same memory access operations as might be done with pointers. You just aren't the one handling it (so you can't f*ck it up, genius =P ).
By dangerous, I mean with pointers and other similar stuff.
[...]
Like the Stack Overflow question Why is the gets function so dangerous that it should not be used?
Per the accepted answer:
"It remained an official part of the language up to the 1999 ISO C standard, but it was officially removed by the 2011 standard. Most C implementations still support it, but at least gcc issues a warning for any code that uses it."
The notion that because something can be done in a language, it must be done is silly. Languages have flaws that get fixed. For compatibility reasons with older code, this construct can still be used. But there is nothing (likely) forcing a programmer to use gets() and, in fact, this command was essentially replaced with safer alternatives.
More to the point, the issue with gets() isn't a pointer issue per se. It's a problem with a command that doesn't necessarily know how to use memory safely. In an abstract sense, this is all pointer issues - reading and writing stuff your not supposed to. That isn't a problem with pointers; it's a problem with pointer implementation.
To clarify, pointers aren't dangerous until you accidentally access a memory location that you weren't intending to. And even then that doesn't guarantee your computer will melt or explode. In most cases, your program will just cease to function (correctly).
That said, because pointers provide access to memory locations and because data and executable code exist in memory together, there is enough of a real danger of accidental corruption that you want to manage memory correctly.
To that point, because truly direct memory access operations often provide less benefit in general than they might have years ago, even non-garbage collected languages like C++ have introduced things such as smart pointers to help bridge the gap between memory efficiency and safety.
In summary, there is very little reason to fear the pointer as long as it's used safely. Just take a hint from South Park's version of Steve "The Crocodile Hunter" Irwin -- don't go around sticking your thumb in crocs' bumholes.