Basic questions about C

T

TefJlives

Hi all,

I'm learning a bit about C, and I have a few questions. I'm not trying
to insult C or anything with these questions, they're just honestly
things I don't get.

It seems like pointers to chars are just how you deal with strings, and
pointers to pointers to char just give you arrays of strings. What is
the advantage of this vs. languages with a string type?

What is the advantage of things like malloc to allocate memory, vs.
languages that just do it for you?

What the heck is up with static memory allocation vs. dynamic? And,
again, why does one want to deal with this vs. just having a computer
do it for you? Especially now with computers having so much memory.

Does C lie somewhere between assembly language and most others in some
sense? As in, is C closer to assembly language than most others?

Thanks.

Greg
 
M

Malcolm McLean

TefJlives said:
Hi all,

I'm learning a bit about C, and I have a few questions. I'm not trying
to insult C or anything with these questions, they're just honestly
things I don't get.

It seems like pointers to chars are just how you deal with strings, and
pointers to pointers to char just give you arrays of strings. What is
the advantage of this vs. languages with a string type?
C has to all intents and purposes no strings. A string is just an array of
chars with a zero char as a sentinel for string end.
So char *str = "Fred"
declares 'F' 'r' 'e' 'd' 'zero' at the place pointed to by str.

If you need several strings, collect several pointers in an array and then
piont to them. So you need an extra *.

The advantge is that the processor has no support for strings, at least in
all probability. So you know what the processor is doing.
What is the advantage of things like malloc to allocate memory, vs.
languages that just do it for you?
You know what the program is doing. So if you want to move to a small
embedded platform with little memory, as long as you make no calls to
malloc() you know your program will work.
What the heck is up with static memory allocation vs. dynamic? And,
again, why does one want to deal with this vs. just having a computer
do it for you? Especially now with computers having so much memory.
Computer nowadays have virtually infinite memory so there is far less reason
to use static memory areas. Not too long ago there was a real threat of the
computer running out of resources, so it made sense to hog a chunk of memory
for the program's exclusive use.
Does C lie somewhere between assembly language and most others in some
sense? As in, is C closer to assembly language than most others?
Yes. C is basically an abstraction of an assembler with a bit of support for
calling functions. If you know assembler, it normally possible to look at a
C program and say roughly what the processor will be doing. However that is
getting less true with very fancy processors with branch prediction,
parallel execution, and other features.
 
I

Ian Collins

Malcolm said:
Computer nowadays have virtually infinite memory so there is far less reason
to use static memory areas. Not too long ago there was a real threat of the
computer running out of resources, so it made sense to hog a chunk of memory
for the program's exclusive use.
Space isn't the issue, lifetime of the object is.
 
D

David T. Ashley

TefJlives said:
Does C lie somewhere between assembly language and most others in some
sense? As in, is C closer to assembly language than most others?

'C' compiles EXTREMELY well.

Most of the data types, operators, and control flow constructs in 'C' are
quite close to the machine instruction set. Even pointers and array
operations often map to one or a small number of machine instructions. This
is by design.

Notice that data sizes are platform-dependent. This is by design.

It is somewhat accurate to describe 'C' as a higher-level assembler. It
goes strongly in that direction.

With a capable machine, it is fair to say that most 'C' compilers will in
most places do a better job than you can in assembly-language.

'C' is very suitable for writing operating system internals and
performance-critical systems.
It seems like pointers to chars are just how you deal with strings, and
pointers to pointers to char just give you arrays of strings. What is
the advantage of this vs. languages with a string type?

The advantage is unmitigated brutal efficiency.

Note that you are free to write your own string functionality if you want.
And the efficiency of 'C' guarantees that it will probably work as fast as
anything built-in to the language would be.
What is the advantage of things like malloc to allocate memory, vs.
languages that just do it for you?

Speed, control. In a typical language that allocates memory for you (a
typical scripting language, for example), it is hard to build advanced data
structures.
What the heck is up with static memory allocation vs. dynamic? And,
again, why does one want to deal with this vs. just having a computer
do it for you? Especially now with computers having so much memory.

Speed, control, ability to build arbitrarily-complex data structures.
 
M

matevzb

'C' compiles EXTREMELY well.

Most of the data types, operators, and control flow constructs in 'C' are
It is somewhat accurate to describe 'C' as a higher-level assembler. It
With a capable machine, it is fair to say that most 'C' compilers will in
'C' is very suitable for writing operating system internals and
And the efficiency of 'C' guarantees that it will probably work as fast as
<snip>

<OT>
Just out of curiosity: why do you insist on writing 'C', but not, say,
'assembler'? =)
</OT>
 
S

Stephen Sprunk

David T. Ashley said:
The advantage is unmitigated brutal efficiency.

Note that you are free to write your own string functionality if you
want. And the efficiency of 'C' guarantees that it will probably work
as fast as anything built-in to the language would be.

Well, if you do something decidedly unlike C strings, then there'll be a
performance cost to that, just like all the languages with built-in
strings suffer a performance hit -- it's just hidden from the
programmer. Ditto for garbage collection vs. manual memory management.

Any time you let a language do something for you, it comes at the cost
of speed, predictability, etc. That may be a decent trade-off;
developer cost is high and many organizations prefer languages that do
most of the work for them, basically paying for CPU cycles instead of
human cycles. However, each layer of abstraction you add reduces
performance, control, and flexibility, and there are instances where
that simply isn't an option.

Anecdote: I once raced a guy to perform a very string-intensive task.
He wrote in Perl, I wrote in C. He finished coding in about a quarter
of the time I did, but my program still finished execution first -- by
several hours. How do you measure who won? It depends what's
important, and that varies.

S
 
D

David Wade

TefJlives said:
Hi all,

I'm learning a bit about C, and I have a few questions. I'm not trying
to insult C or anything with these questions, they're just honestly
things I don't get.

It seems like pointers to chars are just how you deal with strings, and
pointers to pointers to char just give you arrays of strings. What is
the advantage of this vs. languages with a string type?

What is the advantage of things like malloc to allocate memory, vs.
languages that just do it for you?

What the heck is up with static memory allocation vs. dynamic? And,
again, why does one want to deal with this vs. just having a computer
do it for you? Especially now with computers having so much memory.

Does C lie somewhere between assembly language and most others in some
sense? As in, is C closer to assembly language than most others?

I think its much down to history. "C" was designed to allow you to quickly
and efficiantly write code at a low level.
It was designed to provide access to all the features of assembler via a
high level language. It does this well.
Look at Linux. there is virtually no assembler in it. For producing low
level code I don't think there is anything to challenge it...
 
D

David T. Ashley

matevzb said:
<snip>

<OT>
Just out of curiosity: why do you insist on writing 'C', but not, say,
'assembler'? =)
</OT>

I don't know why I do that. I need to stop. I also don't know why it looks
right to me, or how I started that.

Just to justify my practice, I searched to see if I could find anyone else
who does it. I can't.

You are right. I am wrong.
 
D

David T. Ashley

Stephen Sprunk said:
Well, if you do something decidedly unlike C strings, then there'll be a
performance cost to that, just like all the languages with built-in
strings suffer a performance hit -- it's just hidden from the programmer.
Ditto for garbage collection vs. manual memory management.

Any time you let a language do something for you, it comes at the cost of
speed, predictability, etc. That may be a decent trade-off; developer
cost is high and many organizations prefer languages that do most of the
work for them, basically paying for CPU cycles instead of human cycles.
However, each layer of abstraction you add reduces performance, control,
and flexibility, and there are instances where that simply isn't an
option.

Anecdote: I once raced a guy to perform a very string-intensive task. He
wrote in Perl, I wrote in C. He finished coding in about a quarter of the
time I did, but my program still finished execution first -- by several
hours. How do you measure who won? It depends what's important, and that
varies.

My only point in pointing out that you can roll your own string
functionality is that in a language that does this for you, the underlying
mechanisms aren't going to be much better than in a compiled 'C' program.
So, there is really no penalty for rolling your own, other than your time
investment and perhaps awkward syntax, i.e. who wants to write:

VstringCat(&target, &obj1, &obj2);

when they might be able to write (in PHP)

$target = $obj1 . $obj2;

Should be just about as efficient.
 
R

Richard Heathfield

TefJlives said:
It seems like pointers to chars are just how you deal with strings,

Well, no. We use arrays of char to deal with strings. Pointers to char are
what you end up with when you try to pass an array to a function.
and
pointers to pointers to char just give you arrays of strings.

Well, no. What they give you is a headache, until you've worked out just how
astoundingly simple C's type system is (and simple doesn't mean easy).
What is
the advantage of this vs. languages with a string type?

The advantage I see to C's string model is that there is no magic involved.
It's obvious how they work, no hand-waving has to happen, and once you've
sussed out how the C string model works, you can choose whether you like it
or not. If not, it's pretty easy to write something else.
What is the advantage of things like malloc to allocate memory, vs.
languages that just do it for you?

You get to choose when to do it and how much to do it with. It's about
control. Some languages say to you, "this is important and you might get it
wrong - let me do it". In C, *you* get to say "this is important and you
might get it wrong - let me do it".
What the heck is up with static memory allocation vs. dynamic?

static = "As I write this program, I know how many bytes of memory I need".
dynamic = "I won't know how many bytes I need until runtime".
And,
again, why does one want to deal with this vs. just having a computer
do it for you? Especially now with computers having so much memory.

Control again. If you'd rather wave a hand and let the computer make it so,
there's nothing wrong with that, but C isn't your language. Try Python,
Perl, PHP, or other languages beginning with P.

Does C lie somewhere between assembly language and most others in some
sense? As in, is C closer to assembly language than most others?

There is no such thing as a portable assembly language, and therefore C is
not a portable assembly language. It is, however, the only language for
which such a denial is considered necessary.
 
S

santosh

TefJlives said:
Hi all,

I'm learning a bit about C, and I have a few questions. I'm not trying
to insult C or anything with these questions, they're just honestly
things I don't get.

It seems like pointers to chars are just how you deal with strings, and
pointers to pointers to char just give you arrays of strings. What is
the advantage of this vs. languages with a string type?

No real advantage. Nul terminated strings might consume less space than
other more exotic string types, but that's rarely an issue these days.

It's a historical and design issue. C is like this, because it was
designed like this, and the standards have largely followed the spirit
of the original design. It probably made sense at that time,
particularly given it's original purpose as a langauge for writing
portable system code.

Obviously, applications these days expect more automation for such
basic types as strings. Though C has no built in mechanism for this, it
can be done with library routines, and in a portable manner.
What is the advantage of things like malloc to allocate memory, vs.
languages that just do it for you?

Gives you more control regarding allocation and deallocation. Bolting
them into the synatx of the language may reduce it's flexibility and
portability, for example, free standing implementations may not be
possible anymore.
What the heck is up with static memory allocation vs. dynamic? And,
again, why does one want to deal with this vs. just having a computer
do it for you? Especially now with computers having so much memory.

It's a trade-off between efficiency and flexibility. Static memory
consumes less resources, is possible even on freestanding
implementations, and it's lifetime is associated with it's scope, thus
simulating garbage collection.

Dynamically allocated memory is more flexible, (in that you can
allocate larger amounts than with static memory, allocate exactly as
much as is needed, free it whenever you want, not just when the block
terminates etc.), gives control over non-portable extensions like
locking pages, mmaping files, setting access permissions etc.

Does C lie somewhere between assembly language and most others in some
sense? As in, is C closer to assembly language than most others?

C is an HLL. It is not assembler. It's not required to be close to the
architecture of the underlying hardware, though this has historically
been the case.
 
S

santosh

The advantge is that the processor has no support for strings, at least in
all probability. So you know what the processor is doing.

There's no neccessary connection between processor support for strings
and C's nul terminated string representation or a counted strings type.
Counted string types or other more abstract string types do not need
processor support. OTOH, many of the standard library string functions
can, and probably do, take advantage of any SIMD instructions, when
present.

<snip>
 
S

santosh

David said:
'C' compiles EXTREMELY well.

Most of the data types, operators, and control flow constructs in 'C' are
quite close to the machine instruction set. Even pointers and array
operations often map to one or a small number of machine instructions. This
is by design.

Notice that data sizes are platform-dependent. This is by design.

Wasn't it the ANSI standard that did this?
It is somewhat accurate to describe 'C' as a higher-level assembler. It
goes strongly in that direction.

No. An assembly langauge, higher or lower level, is one which exposes
you to the underlying memory model and the full instruction set of the
processor. Period. C does niether of these. It's accurate to say that
most implementations of C are close to the host machine's architecture,
but not to say that C is portable assembler or whatever.
With a capable machine, it is fair to say that most 'C' compilers will in
most places do a better job than you can in assembly-language.

The crowd in alt.lang.asm will be very interested in this comment.
'C' is very suitable for writing operating system internals and
performance-critical systems.


The advantage is unmitigated brutal efficiency.

Except when calculating the string length. Note that this weakness is
not inherent in the language, but the lack of automatic tracking of
string length can lead a naive programmer to calculate a string's
length over and over when storing it would've been better.

As a side issue, is it feasible for compilers to track changes to a
string and if there're no changes, to optimise multiple calls to
strlen() for that string to a single call and a stored value? I think
the aliasing issue will prevent this sort of optimisation. Maybe the
restrict qualifier can help.
Note that you are free to write your own string functionality if you want.
And the efficiency of 'C' guarantees that it will probably work as fast as
anything built-in to the language would be.

Yes, but one of the advantages of a builtin or standardised string
type, is precisely that they're builtin or standardised, eliminating
reinvention of the wheel and portability considerations.

<snip>
 
S

santosh

David said:
I think its much down to history. "C" was designed to allow you to quickly
and efficiantly write code at a low level.
True.

It was designed to provide access to all the features of assembler via a
high level language.

I don't think so. It doesn't provide _any_ feature of the underlying
processor's assembler language. It's purpose was precisely to abstract
out this layer, but still retain closeness to the machine's hardware
architecture. Most implementations fulfill this very successfully.

But C doesn't provide the features of assembler, unless you write
inline assembly, and that's not C anymore.
It does this well.
Look at Linux. there is virtually no assembler in it.

There're significant amount of assembler code in the Linux source. But
your point is right. C generally does a good job of minimising the
amount of assembler required.
For producing low
level code I don't think there is anything to challenge it...

Ada, Forth?
 
M

matevzb

I don't know why I do that. I need to stop. I also don't know why it looks
right to me, or how I started that.

Just to justify my practice, I searched to see if I could find anyone else
who does it. I can't.

You are right. I am wrong.
You may have misunderstood me, I didn't mean to imply anything. I don't
see it as right or wrong, it just caught my attention.
Sidenote: check this thread for a different, double-quoted version.
 
C

Chris Dollin

TefJlives wrote:

(late to the party)
It seems like pointers to chars are just how you deal with strings, and
pointers to pointers to char just give you arrays of strings. What is
the advantage of this vs. languages with a string type?

You don't need a string type: you build string things from the
pointer-to-whatever and array-of-whatever specialised to `whatever`
being `char`, plus a tiny bit of syntactic dust.

(Remember that C was developed in the early /70s/.)
What is the advantage of things like malloc to allocate memory, vs.
languages that just do it for you?

You're in charge. And languages that "just do it for you" often have a
malloc-equivalent: eg, in Java it's called `new`. What makes a
significant difference in power is whether or not the language
does /free/ for you automagically. This power has a price, and its
the kind of price not appropriate for many of the uses that C has.

[I am a Certified Fan of garbage collection; but I wouldn't want
it automagically in my C code, which is where I'm more likely to
/implement/ it.]
What the heck is up with static memory allocation vs. dynamic?

Static memory stays around. Dynamic memory doesn't. Static memory
can be initialised at program startup -- handy for constant tables.
Dynamic memory isn't.
And,
again, why does one want to deal with this vs. just having a computer
do it for you? Especially now with computers having so much memory.

That's not the issue.
Does C lie somewhere between assembly language and most others in some
sense? As in, is C closer to assembly language than most others?

Yes. In some sense.
 
T

Thad Smith

Ian said:
Space isn't the issue, lifetime of the object is.

Another issue, especially for low-end processors used in embedded
applications, is that static variables can be addressed directly, which
dynamic memory must be addressed through indirect addressing or
indexing. While not usually a significant cost on large processors, it
can be substantial on small processors with poor indexing support.
 
K

Keith Thompson

santosh said:
David T. Ashley wrote: [...]
Notice that data sizes are platform-dependent. This is by design.

Wasn't it the ANSI standard that did this?
[...]

No, data sizes were platform-dependent long before the ANSI standard.
There's a table of data sizes near the beginning of K&R1, published in
1978 IIRC.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,131
Latest member
IsiahLiebe
Top