Good Tutorials

C

Chad

On many machines that's true; though the standard imposes no such
requirement. There are machines where CHAR_BITS==16, and short is a
one-byte type. There are other machines where char is 8 bits, long
long is 64 bits, and all of the types between char and long long are
32 bits.


On many machines that's true. On other machines they can be one word
long, or a fraction of a word. The standard imposes no requirements on
that kind of thing.


Then you should revise your definition of a pointer to allow for that
possibility.


Yes, which need not be the address of a variable.



There are two different common values that code could print out, and
real machines where it will print 154 because unsigned char and short
int are both 16 bits long, and real machines where it will print
garbage, or possibly simply abort, because all integer types between
(but not including) 'char' and 'long long' are 4 bytes long.

None of which proves that the value of sint points at a variable. Your
point is?

Here is what I got

First on FreeBSD

m-net% more test.c
#include <stdlib.h>
#include <stdio.h>

int main(void)
{
short int *sint=malloc(2);
unsigned char *a=(unsigned char *)sint;
*a=154;
*(a+1)=2;
printf("%d",*sint);

return 0;
}
m-net% gcc -v
Using built-in specs.
Configured with: FreeBSD/i386 system compiler
Thread model: posix
gcc version 3.4.6 [FreeBSD] 20060305
m-net% gcc -Wall test.c -o test
m-net% ./test
666%
m-net%


Now on linux

[cdalten@localhost oakland]$ more test.c
#include <stdlib.h>
#include <stdio.h>

int main(void)
{
short int *sint=malloc(2);
unsigned char *a=(unsigned char *)sint;
*a=154;
*(a+1)=2;
printf("%d",*sint);

return 0;
}
[cdalten@localhost oakland]$ gcc -v
Using built-in specs.
Target: i386-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --
infodir=/usr/share/info --enable-shared --enable-threads=posix --
enable-checking=release --with-system-zlib --enable-__cxa_atexit --
disable-libunwind-exceptions --enable-libgcj-multifile --enable-
languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --
disable-dssi --enable-plugin --with-java-home=/usr/lib/jvm/java-1.4.2-
gcj-1.4.2.0/jre --with-cpu=generic --host=i386-redhat-linux
Thread model: posix
gcc version 4.1.1 20061011 (Red Hat 4.1.1-30)
[cdalten@localhost oakland]$ gcc -Wall test.c -o test
[cdalten@localhost oakland]$ ./test
666[cdalten@localhost oakland]$
 
A

Andrew Poelstra

So if you have a x86 based processor, which you most likely do,
compile and run the following:
It will print out the value 666, and the size (in bytes) of a short
int,
on your x86 system. Enjoy:

#include <stdio.h>

int main() {
short int a;
unsigned char *b=(unsigned char *)&a;
*b=154;
*(b+1)=2;
printf("%d \n",a);
printf("%d bytes for short int \n",sizeof(short int));
system("pause");
}

On my system, it does indeed output 666, followed by a "command
not found" regarding your system() call. I'm not sure what this
code demonstrates, though, other than that one can take this:
puts("666")
And make it intrinsicly non-portable, rife with undefined
behavior, inefficient and unmaintainable to boot.

But hey, you're the expert.


(My compiler also has this to say:

usenet.c: In function ‘main’:
usenet.c:9: warning: format ‘%d’ expects type ‘int’, but argument
2 has type ‘long unsigned int’
usenet.c:10: warning: implicit declaration of function ‘system’
usenet.c:11: warning: control reaches end of non-void function

but it hasn't been dealing with C code for as long as you.)

(Also, FWIW, it's incorrect on the first warning - the value
yeilded by the sizeof operator is technically a size_t. I'm
guessing since all the world's a x86, it doesn't matter.)
 
K

Keith Thompson

Andrew Poelstra said:
printf("%d bytes for short int \n",sizeof(short int));
[...]
(My compiler also has this to say:

usenet.c: In function ‘main’:
usenet.c:9: warning: format ‘%d’ expects type ‘int’, but argument
2 has type ‘long unsigned int’ [...]

(Also, FWIW, it's incorrect on the first warning - the value
yeilded by the sizeof operator is technically a size_t. I'm
guessing since all the world's a x86, it doesn't matter.)

But size_t is merely a typedef for some predefined unsigned integer
type, apparently unsigned long on your system. A typedef doesn't
create a new type, merely an alias for an existing type. So on your
system, sizeof(short int) really is of type long unsigned int.

But it would be nice if the compiler were clever enough to refer to
the size_t typedef instead.
 
K

Keith Thompson

Richard Heathfield said:
Keith Thompson said:

I disagree. Chuck was actually correct, and you have it backwards. It is
sizeof(short) that tells you how many bytes a short occupies (but doesn't
tell you about padding bits), whereas the information in <limits.h> can
tell you how many bytes (and fractions of a byte) a short int actually
uses. You can work it out by stepping outside the C system for a moment
(so that you can do unbounded arithmetic!) and calculating 2 * (1 +
SHRT_MAX), taking the logarithm of the result (base 2), and dividing
/that/ result by CHAR_BIT - also in <limits.h>.

Then the only disagreement/confusion is over the meaning of "uses".
An object of type short, as we all know, *occupies* exactly
sizeof(short) bytes; you can argue (and I won't disagree) that it only
*uses* the sign and value bits. (Though it might *use* the padding
bits for some purpose other than representing the value, for example
as check bits.)

If Chuck intended to make that distinction, I'll gladly concede that
he was correct, though I don't know why he'd say bytes in that context
rather than bits. But he was responding to Amkcoder's claim that a
short int *is* exactly two bytes. A more pertinent response to that
claim is that a short int *is* exactly sizeof(short) bytes.

(I doubt that Amkcoder knows about padding bits anyway.)
 
F

Flash Gordon

Mark L Pappin wrote, On 24/09/08 01:52:

In an ideal world with perfectly rational students perhaps one could
begin by stating "What I am about to tell you is not completely
correct, but is a necessary simplification to bootstrap this model of
reality into your brain. Later, as your understanding grows, you will
need to throw out some of these simplifications to allow you to see
better models." We don't have such a world, unfortunately.

Some of the very good teachers I had did basically tell us that. Well,
actually it was the physics and chemistry teachers told us that the
models were simplifications and if we were doing both we would be taught
different models for different purposes in the two courses and further
models in later courses if we continued with science. It did not seem to
cause problems.
 
N

Nick Keighley

sombody has messed up the attributions. There may have been
Top Posting. I've just gathered up the attributions I've
found in this post and dumped them here.

I think you're wrong. People *can* use pointers effectivly
without swallowing the standard. They might do a better
job if they fully understood the underlying type system
but not doing so does *not* preclude them from using C
effectivly.

A tutorial author though should at least be aware or the
correct terminology even if for pedalogical purposes
he drifts away from it a little.

Given that p is char [4][2], you should immediately be able to tell
which type *p is, p[0][0], &p[0].
(answer: char [2], char, char (*)[2])
I wouldn't frighten off the OP with this stuff. I don't understand half of
it either.

I don't think he frightens easily!

:)

cobblers



Why don't you explain why I am wrong then, MR.PROGRAMMER,
and just to tell you my understanding of datatypes is backed
by the intel x86 manuals applications programming section,
chapter on data types.

It might be an idea to read C documentaion when writing
a C tutorial.

So you call Intel liars,

no he didn't. Don't be silly.

You call universities who use my same definition of pointers liars,

ditto. Which universites? Where? Do you have a link to this
usage?

And then you say I have but a smattering of datatypes
when you don't even know what your saying...

your -> you're

why do you think he doesn't know what he's saying?
Is he delirious? Drugged?

Go on and explain,
or you are no programmer.
silly

Now the topic of this post is about good tutorials,
and they are, so follow the link at the top.

are you the author of the tutorial?
Bad C tutorials unfortunatly far outnumber
good ones.


--
Nick Keighley


"Perilous to us all are the devices of
an art deeper than we possess ourselves."
Gandalf The Grey (discussing Windows Vista)
 
S

soscpd

Hello Richard, James, List

If you're looking for a *short* definition, "pointer" is perfect. If you're
looking for a technical definition, the best place to look is the
Standard, but unfortunately it defines "pointer" in terms of behaviour,

So far, I can't agree with you more.

"One great advantage of stored-program digital computers is that they can
store both code and data in their memory. To a first approximation, a
pointer value is a value that represents the place in memory where either
code (a function) or data (an object) is stored. We'll cover the two
exceptions - indeterminate pointers and null pointers - later on. Pointer
values can be stored in objects that have the appropriate pointer type for
the relevant object or function."

Yeah, right. It is correct. But try that in a classroom. The ones who
will not sleep, will leave the room. But ok... I'll give you a shot.
By friday I can test it with a friend (teacher... :).

My point is: There must be a way to define pointers as simple as they
are - they are pointers. They point to something. Then, the behavior
it's up to the contents. Leave pointers alone and put the effort in
teaching the contents. Doing that you will not scare students with -
Hey.. that's true, but not always - or - Pointers is a hard subject.
It is not if teached without the "stuff", I think.

++++++++

I'm not quite sure what you mean by those questions. A function
pointer does not "return" anything. It points at the entry point for a

Well... James... here is the part who, sometimes, make-me delete all
c.l.c inputs on my mail box before read. I love C. It is my favorite
language, and I am always looking for his edges. Still can't find (and
probably will not), but the trip is enough fun.

But every time we are discussing something on c.l.c, we must follow
the standards, thinking, speaking and so on. Well... was my mistake do
not follow that simple rules. By return, I mean: If you use it, in
some place where you expect the variable value, you will get the value
(please... no to initialization, error and stuff. Consider the utopia
with me, right now. I'm not a C teacher and my goal is not follow the
standards as standards... they are more general guidelines to me),
like:

int *p = malloc(sizeof(int));
p=2;

So... p is a pointer to a memory location of int size?

After all... the machine job is to go to that location and "return"
the value, if I ask for it.

That's was my return definition in there.
function, which does not qualify as an "object" as far as the C
standard is concerned. It can be used to call the function that it
points at. That is the reason why we use function pointers. The

Right. By me... that still means you are returning something. I can't
find a function who do not return (by me, a null void return is,
still, a return).
It has a value, which is the location of the function it points at. It
doesn't "return" that value.

Ok... ok...
The standard doesn't define "pointer" but it does define a "pointer
type":

Yeah, right...

Can we keep Richard's "...defines "pointer" in terms of behaviour..."
and keep that way?
It is commonplace to use the term pointer to mean either a "pointer
object" or a "pointer value", both usages are common in the standard

I can't find any difference between function pointer and variable
pointer (I mean... pointer object and value, sorry). Both point to
some memory location where is some "stuff" you like to use. What is
it, and how you will use it doesn't matter to the pointer. That is why
I am usual to do not mix both subjects (bottle and contents - ok...
here is not exactly bottle. Its more like the place where the bottle
is... endless). I just find that way the best one to know how to
handle pointers.
in C terms, a variable is a named object.

Mm... agreed, I think.


Regards
Rafael
 
N

Nick Keighley

Amkcoder said:
Amkcoder said:
On Sep 23, 9:03 am, (e-mail address removed) wrote:
Amkcoder wrote:
The definition you so waywardly complain about is repeated as a common
definition:
"A pointer is a variable that points at, or refers to, another
variable."
So, if  we have
char  greeting[] = "Hello, World!";
int seven = 7;
Then according to your definition, neither greeting+6 nor &seven are
pointers, because they are expressions, not variables. According to
your definition,  neither (void*)0 nor malloc(256) is a pointer, both
because they aren't variables and because they don't point at
variables.
I consider this to be a serious defect in your definition of a
pointer.
Like I said, good tutorials...
Please only sincere students or real programmers comment,
I'm a real programmer. At least, they pay me to write computer
programs. And I know, as you apparently do not, that pointers don't
need to be variables, and they don't need to point at variables.
Sorry,
but a short int is exactly two bytes,
No, a short int is at least 16 bits, and at least one byte, in width, but
there is no upper limit.
and in order to use them they
must be treated as a word.
No, they must be treated as short ints (modulo object representation
techniques which don't seem to be relevant here).
You think I don't know that you can refer a pointer to allocated
memory,

you can read his mind?
What absolute nonsense. The behaviour on a conforming system must be a
truth or it would not be conforming.

I was trying to cut down on my responses to Richard <null> but then
he
posts stuff like this...

The behaviour of a conforming program must produce output
consistent with the standard. But it does not (cannot)
illustrate all possible behaviours allowable by the standard.

A short does not have to be 16-bits. If it were, say, 32-bits
and a byte was 8 bits then the above snippet of code would
exhibit Undefined Behaviour.

This constant desire to confuse people with a "pointer is not an
address" is simply ridiculous. It is an "address". You address an object
or memory or whatever through it. One representation of that address is
as a value which can be displayed as a hexadecimal memory "address".

this was wrong the first time you said it. It is still wrong.

<snip std_richard_rant>
 
N

Nick Keighley


don't post sigs. The bit after "-- "

On x86 architecture based systems and compatibles,
it is confirmed that a word is two contiguous bytes,
each of which have their own address,
and the lower of the addresses is the address of the word.
This makes a 16-bit value.

this has nothing to do with C. C does not have "words".
Nowhere is is set in stone that a short must be an x86 word.
On some compilers a short might be 32 bits. Even on an
x86.

As can be seen in this archecture it requires a double word (32-bit
binary value)
to represent every address,
for it can address up to 2^32-1 bytes,
and as can be seen a double word contains 32-bits having
a maximum value of 2^32-1 when unsigned
, for on these systems each address refers to a byte.

there are 64-bit x86s

To program on the x86 architecture it is requisite knowledge.
no


This is the most common of architectures, so to be a real programmer,
capable working in the real world on most systems,
you'll need this manual for the 80386,

no. I have programmed x86s and I don't have an x86 hardware manual.

<snip>

You definitly should learn more C before you write any more
tutorials.
 
N

Nick Keighley

Amkcoder said:
On Sep 23, 10:17 am, Richard Heathfield <[email protected]> wrote:
[x86] is the most common of architectures, so to be a real programmer,

Don't count on it. For every x86 machine, there's multiple embedded
processors on the very same board with it, in addition to all of the
embedded processors in all of the other devices in the world. I'm not
sure that there's any one embedded processor that is more common than
the entire x86 family of processors, but collectively I'm quite sure
that embedded processors vastly outnumber x86 processors, and most of
those embedded processors have environments significantly different
from the one you describe.

the ARM is a contender. From its wiki entry:
"Today, the ARM family accounts for approximately 75% of all embedded
32-bit RISC CPUs,[1] making it one of the most widely used 32-bit
architectures."

<snip>
 
J

James Kuyper

soscpd wrote:
....
Well... James... here is the part who, sometimes, make-me delete all
c.l.c inputs on my mail box before read. I love C. It is my favorite
language, and I am always looking for his edges. Still can't find (and
probably will not), but the trip is enough fun.

But every time we are discussing something on c.l.c, we must follow
the standards, thinking, speaking and so on. Well... was my mistake do
not follow that simple rules. ...

Technical jargon serves many purposes, including the ignoble purpose of
separating the in-group and the out-group. However, it's main purpose is
to clearly communicate complex concepts (to members of the in-group).
Jargon wasn't just invented for fun; it was invented because ordinary
English doesn't express the ideas with sufficient precision. (See below
for examples.
I can't find any difference between function pointer and variable
pointer

A function pointer points at a function; the function can be called
using that pointer by using the syntax pfunc(), or (*pfunc)(). An object
pointer points at an object; the value represented by that object can be
either accessed or written by using the syntax *pobj. If you don't see a
difference, how do you decide which syntax to use?
... (I mean... pointer object and value, sorry). Both point to
some memory location where is some "stuff" you like to use.

I suspect that you actually understand the difference those words
describe; I just think you're unclear about the fact that those words
describe that difference.

The difference is that a pointer object is a piece of memory that
contains the representation of a pointer value. A pointer value can also
occur in a C program without being stored in any object, for example, in
the expression p+3, where p is the name of a pointer variable. The
pointer value p+3 isn't necessarily stored in any object, as that term
is defined by the C standard, it typically resides in a register.

Due to optimization, that pointer value might never be stored anywhere -
p+3 might be combined with some other operation, as in (p+3)->count.
That C code might be translated into machine code which retrieves the
byte address stored in p, and then adds to it, in a single instruction,
the combined values of 3*sizeof *p and the offset of the 'count' member
within the struct pointed at by p.

The distinction between a pointer object and a pointer value is sort of
like the difference between a newspaper article describing a murder, and
the murder described by that article. If you have trouble distinguishing
between those two things, I'd recommend avoiding reading the newspaper
:). Similarly, if you can't distinguish between a pointer object and a
pointer value, you should avoid pointers (which would make using C a bit
difficult :).
 
V

vippstar

I think you're wrong. People *can* use pointers effectivly
without swallowing the standard. They might do a better
job if they fully understood the underlying type system
but not doing so does *not* preclude them from using C
effectivly.

Since you repeated the typo twice, I'd wanted to mention it's
'effectiv*e*ly'.
I think you're wrong, but before we further argue I think it's best to
agree about the meaning of "effective use of pointers", as it's pretty
vague.

The reason I mentioned the type system, is that in another article,
someone asked how to learn pointers.
I replied with something close to "learn the type system, then read
the pointer semantics".
You certainly need to know the type system; if you do, you'll always
know what &p is, **p, the difference between &*p and *&p.
If you know the pointer semantics, you'll always know what operations
can be performed with the pointer.
 
R

Richard

Message-ID: <[email protected]>
Bartc [on another article] said:
I neither know nor care whether a pointer is a value, variable, type or
object. But that hasn't stopped me using them quite effectively.
I doubt you've used pointers effectively.

I think you're wrong. People *can* use pointers effectivly
without swallowing the standard. They might do a better
job if they fully understood the underlying type system
but not doing so does *not* preclude them from using C
effectivly.

Since you repeated the typo twice, I'd wanted to mention it's
'effectiv*e*ly'.
I think you're wrong, but before we further argue I think it's best to

No surprise there.

But you are wrong. "effective and efficient" use does not need the
knowledge of the standard since a huge % of code is never ported to
other platforms. I dont "support" writing "non standard code"
necessarily but to deny that a practical knowledge of pointers in terms
of memory addresses similar to CPU registers can produce good, stable
efficient code is purely ridiculous.
agree about the meaning of "effective use of pointers", as it's pretty
vague.

The reason I mentioned the type system, is that in another article,
someone asked how to learn pointers.
I replied with something close to "learn the type system, then read
the pointer semantics".
You certainly need to know the type system; if you do, you'll always
know what &p is, **p, the difference between &*p and *&p.

Neither of which have anything to do with the type system of course. e.g
I know what those things are and there's not a type in sight.
If you know the pointer semantics, you'll always know what operations
can be performed with the pointer.

Now I get it. You're just waffling for waffle's sake.
 
C

CBFalconer

soscpd said:
.... snip ...

I can't find any difference between function pointer and variable
pointer (I mean... pointer object and value, sorry). Both point to
some memory location where is some "stuff" you like to use. What
is it, and how you will use it doesn't matter to the pointer. That
is why I am usual to do not mix both subjects (bottle and contents
- ok... here is not exactly bottle. Its more like the place where
the bottle is... endless). I just find that way the best one to
know how to handle pointers.

Well, here is one difference. An object pointer (dereferencable)
needs to point to memory, since that is where the value of the
object is stored. However a function pointer needs to load AND
EXECUTE code. That may well be stored in a shared library, and the
reference is to a location in a file. This is one reason function
pointers and object pointers are not interchangeable; the function
pointer may need much more data.
 
R

Richard

Tristan Miller said:
Greetings.



Oh, really? Perhaps you could explain to us, then, how and where the
system allocates space for the following pointer declaration?

extern int *p;

That is declaring that the variable is external. It is not "declaring a
variable" in my view. I'm sure that thats probably over simplified and
breaks something in the standard but there you go.
Regards,
Tristan

--
 
K

Keith Thompson

soscpd said:
But every time we are discussing something on c.l.c, we must follow
the standards, thinking, speaking and so on. Well... was my mistake do
not follow that simple rules. By return, I mean: If you use it, in
some place where you expect the variable value, you will get the value
(please... no to initialization, error and stuff. Consider the utopia
with me, right now. I'm not a C teacher and my goal is not follow the
standards as standards... they are more general guidelines to me),
like:

int *p = malloc(sizeof(int));
p=2;

I assume you meant "*p = 2;".
So... p is a pointer to a memory location of int size?
Right.

After all... the machine job is to go to that location and "return"
the value, if I ask for it.

That's was my return definition in there.

I'm having trouble understanding what you mean. By "my return
definition", I *think* you mean your definition of the word "return",
and I think you're trying to argue that the pointer p can "return" the
value 2. Is that correct?

I suggest that greater precision both in your C and in your English
would serve you well.

Personally, when talking about C, I use the word "return" only to
refer to a value returned by a function (using the "return" keyword),
where as an expression *yields* a value. But ok, if you want to say
that an expression returns a value, that's not too horribly bad. But
in your example, exactly what returns what? Are you saying that the
pointer object p "returns" the value 2? If so, how would you say what
I express as "the expression ``p'' yields a pointer value of type
int*"?
 
K

Keith Thompson

Nick Keighley said:
this was wrong the first time you said it. It is still wrong.
[...]

Um, how is it wrong?

A pointer is an address; the way the standard defines the terms,
they're nearly synonymous (though I suspect Richard is using the term
"address" in some more hardware-specific way). And it's always
possible to represent a pointer value / address in hexadecimal; even
if "%p" doesn't do this, you can interpret its representation as an
array of unsigned char.

An address is not a number (though it's often implemented that way),
but Richard didn't make that particular claim here.
 
J

jameskuyper

Richard said:
That is declaring that the variable is external. It is not "declaring a
variable" in my view. I'm sure that thats probably over simplified and
breaks something in the standard but there you go.

It doesn't break something, it just doesn't use the jargon correctly.
The standard doesn't use the term "variable". However, that
declaration unambiguously declares the identifier 'p', which is the
name of an object, in exactly the same sense that

int f(int);

declares the identifier 'f', which is the name of a function. if you
accept the definition I'm familiar with (variable = "named object"),
then this means that the declaration declares a variable named 'p'.

What neither statement does is define the thing that the identifier
identifies. If Amkcoder had said "Every time you define a pointer
variable, space is allocated to store its value", he would have been
reasonably accurate There's a big difference between declaring an
identifier and defining the thing that the identifier identifies.
 
R

Richard

It doesn't break something, it just doesn't use the jargon correctly.
The standard doesn't use the term "variable". However, that
declaration unambiguously declares the identifier 'p', which is the
name of an object, in exactly the same sense that

int f(int);

declares the identifier 'f', which is the name of a function. if you
accept the definition I'm familiar with (variable = "named object"),
then this means that the declaration declares a variable named 'p'.

What neither statement does is define the thing that the identifier
identifies. If Amkcoder had said "Every time you define a pointer
variable, space is allocated to store its value", he would have been
reasonably accurate There's a big difference between declaring an
identifier and defining the thing that the identifier identifies.

I know. But one does not need to be a genius to know what he meant. or
one to understand what I said.
 
K

Keith Thompson

pete said:
To "retrieve the address it holds",
neither an ampersand nor an asterisk is used.

The asterisk is used to reference the value of the object
that the pointer points to.
[...]

Or to refer to the object itself; unary * yields an lvalue.
 

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

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,051
Latest member
CarleyMcCr

Latest Threads

Top