Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #98017 > unrolled thread
| Started by | Alla _ <modelling.data@gmail.com> |
|---|---|
| First post | 2016-12-05 07:45 -0800 |
| Last post | 2016-12-05 12:50 -0500 |
| Articles | 20 on this page of 23 — 5 participants |
Back to article view | Back to comp.lang.c
Understanding the program that has pointers to two_dimensional arrays Alla _ <modelling.data@gmail.com> - 2016-12-05 07:45 -0800
Re: Understanding the program that has pointers to two_dimensional arrays Richard Heathfield <rjh@cpax.org.uk> - 2016-12-05 17:03 +0000
Re: Understanding the program that has pointers to two_dimensional arrays Alla _ <modelling.data@gmail.com> - 2016-12-05 09:43 -0800
Re: Understanding the program that has pointers to two_dimensional arrays Richard Heathfield <rjh@cpax.org.uk> - 2016-12-05 18:16 +0000
Re: Understanding the program that has pointers to two_dimensional arrays Alla _ <modelling.data@gmail.com> - 2016-12-05 22:46 -0800
Re: Understanding the program that has pointers to two_dimensional arrays Richard Heathfield <rjh@cpax.org.uk> - 2016-12-06 10:23 +0000
Re: Understanding the program that has pointers to two_dimensional arrays Alla _ <modelling.data@gmail.com> - 2016-12-06 02:53 -0800
Re: Understanding the program that has pointers to two_dimensional arrays Richard Heathfield <rjh@cpax.org.uk> - 2016-12-06 10:58 +0000
Re: Understanding the program that has pointers to two_dimensional arrays Alla _ <modelling.data@gmail.com> - 2016-12-06 03:42 -0800
Re: Understanding the program that has pointers to two_dimensional arrays Alla _ <modelling.data@gmail.com> - 2016-12-06 06:31 -0800
Re: Understanding the program that has pointers to two_dimensional arrays Richard Heathfield <rjh@cpax.org.uk> - 2016-12-06 14:49 +0000
Re: Understanding the program that has pointers to two_dimensional arrays Alla _ <modelling.data@gmail.com> - 2016-12-06 08:22 -0800
Re: Understanding the program that has pointers to two_dimensional arrays Richard Heathfield <rjh@cpax.org.uk> - 2016-12-06 16:48 +0000
Re: Understanding the program that has pointers to two_dimensional arrays Alla _ <modelling.data@gmail.com> - 2016-12-06 09:15 -0800
Re: Understanding the program that has pointers to two_dimensional arrays Keith Thompson <kst-u@mib.org> - 2016-12-06 08:20 -0800
Re: Understanding the program that has pointers to two_dimensional arrays Alla _ <modelling.data@gmail.com> - 2016-12-05 22:53 -0800
Re: Understanding the program that has pointers to two_dimensional arrays Keith Thompson <kst-u@mib.org> - 2016-12-05 09:26 -0800
Re: Understanding the program that has pointers to two_dimensional arrays Alla _ <modelling.data@gmail.com> - 2016-12-05 09:47 -0800
Re: Understanding the program that has pointers to two_dimensional arrays Keith Thompson <kst-u@mib.org> - 2016-12-05 12:10 -0800
Re: Understanding the program that has pointers to two_dimensional arrays Alla _ <modelling.data@gmail.com> - 2016-12-05 10:00 -0800
Re: Understanding the program that has pointers to two_dimensional arrays Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-12-05 19:11 +0000
Re: Understanding the program that has pointers to two_dimensional arrays Keith Thompson <kst-u@mib.org> - 2016-12-05 12:21 -0800
Re: Understanding the program that has pointers to two_dimensional arrays "James R. Kuyper" <jameskuyper@verizon.net> - 2016-12-05 12:50 -0500
Page 1 of 2 [1] 2 Next page →
| From | Alla _ <modelling.data@gmail.com> |
|---|---|
| Date | 2016-12-05 07:45 -0800 |
| Subject | Understanding the program that has pointers to two_dimensional arrays |
| Message-ID | <481da833-61f6-4f1c-973b-1b129118c682@googlegroups.com> |
Hello!
Please, take a look at my reading of the program (in comments to each statement)
that uses pointers to two-dimensional arrays. Is my understanding correct, i.e. do
correctly interpret the given code? And, please, help me to understand one part closer
to the end of the program.
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
// define the number of rows and columns
int nrows = 5;
int ncols = 10;
int row;
// initialise a pointer, which points to a pointer, which, in turn, points to type int,
// i.e. stores the address of an integer value
int **rowptr;
/*** define rowptr pointer by assigning to it the value of the address of the array,
allocated by the call to malloc for nrows (5 in this case) pointers to type int;
therefore the value of the rowptr after the call to malloc will be the address,
at which the first element in the array of pointers to integer type could be stored;
of course, none of these pointers yet point anywhere
***/
rowptr = malloc(nrows * sizeof(int *));
/** check of the memory has been allocated; if not, print the info message,
and exit **/
if (rowptr == NULL)
{
puts("\nFailure to allocate room for row pointers.\n");
exit(0);
}
// Print the title
printf("\n\n\nIndex Pointer(hex) Pointer(dec) Diff.(dec)");
/** Allocate memory for an array of ncols integers for every row, and store the value of the
allocated address of the first element of each array at the pointer rowptr[row],
such that rowptr[row] now points to corresponding address of the first element
in the array of ncols integers **/
for (row = 0; row < nrows; row++)
{
rowptr[row] = malloc(ncols * sizeof(int));
/** check of the memory has been allocated; if not, print the info message,
and exit **/
if (rowptr[row] == NULL)
{
printf("\nFailure to allocate for row[%d]\n",row);
exit(0);
}
/** Here is the difficult part: print the number of the current row "row",
print the hexadecimal address of the pointer that now has the value
of the address of the first element of the array of integers;
and the third element should the same address of the pointer
but its decimal value;
When I tried to compile this, I have received an error message,
which I solved by casting (void *) to the first call to rowptr[row]
(see my new printf below the original one), which is specified
by %p; but I can't solve the second error message (see below)
and I don't understand why the author has not mentioned anything
about it:
error: format specifies type 'int' but the argument has
type 'int *' [-Werror,-Wformat]
printf("\n%d %p %d", row, rowptr[row], rowptr[row]);
~~ ^~~~~~~~~~~
**/
/** original printf function:
printf("\n%d %p %d", row, rowptr[row], rowptr[row]); **/
// partially corrected printf
printf("\n%d %p %d", row, (void *)rowptr[row], rowptr[row]);
/** print the difference between the value of addresses of each row **/
if (row > 0)
printf(" %d",(int)(rowptr[row] - rowptr[row-1]));
}
return 0;
}
Thank you very much!
[toc] | [next] | [standalone]
| From | Richard Heathfield <rjh@cpax.org.uk> |
|---|---|
| Date | 2016-12-05 17:03 +0000 |
| Message-ID | <o246iv$8m7$1@dont-email.me> |
| In reply to | #98017 |
On 05/12/16 15:45, Alla _ wrote:
>
> Hello!
>
> Please, take a look at my reading of the program (in comments to each statement)
> that uses pointers to two-dimensional arrays.
No, it doesn't. Not at any point. What it does use is a pointer to
pointer to int, which you point at the beginning of storage suitable for
storing several int * objects. And those int * are used for pointing at
the beginning of storage that is suitable for storing several int objects.
> Is my understanding correct, i.e. do
> correctly interpret the given code? And, please, help me to understand one part closer
> to the end of the program.
>
>
> #include <stdio.h>
> #include <stdlib.h>
> int main(void)
> {
> // define the number of rows and columns
> int nrows = 5;
> int ncols = 10;
> int row;
>
> // initialise a pointer, which points to a pointer, which, in turn, points to type int,
> // i.e. stores the address of an integer value
> int **rowptr;
Yes, rowptr is suitable for pointing to objects of type int *, which are
in turn suitable to pointing to objects of type int.
> /*** define rowptr pointer
No, it's already defined. What you're about to do is assign to it.
> by assigning to it the value of the address of the array,
> allocated by the call to malloc for nrows (5 in this case) pointers to type int;
That's one way to say it, yes. You are asking for enough storage to
store 5 objects of type int *.
> therefore the value of the rowptr after the call to malloc will be the address,
> at which the first element in the array of pointers to integer type could be stored;
> of course, none of these pointers yet point anywhere
> ***/
Correct.
>
> rowptr = malloc(nrows * sizeof(int *));
Better: rowptr = malloc(nrows * sizeof *rowptr);
which will still be correct even if you later change the type of rowptr.
>
> /** check of the memory has been allocated; if not, print the info message,
> and exit **/
> if (rowptr == NULL)
> {
> puts("\nFailure to allocate room for row pointers.\n");
> exit(0);
> }
Yes. Not /quite/ how I would do it, but you are correctly checking that
the storage allocation request succeeded. If it didn't, you have to take
evasive action. Terminating the program, as you are doing, is generally
acceptable in student code.
> // Print the title
> printf("\n\n\nIndex Pointer(hex) Pointer(dec) Diff.(dec)");
>
> /** Allocate memory for an array of ncols integers for every row, and store the value of the
> allocated address of the first element of each array at the pointer rowptr[row],
> such that rowptr[row] now points to corresponding address of the first element
> in the array of ncols integers **/
Yes.
>
> for (row = 0; row < nrows; row++)
> {
> rowptr[row] = malloc(ncols * sizeof(int));
Better: rowptr[row] = malloc(ncols * sizeof *rowptr[row]);
>
> /** check of the memory has been allocated; if not, print the info message,
> and exit **/
> if (rowptr[row] == NULL)
> {
> printf("\nFailure to allocate for row[%d]\n",row);
> exit(0);
> }
Yes, that's fine.
> /** Here is the difficult part: print the number of the current row "row",
> print the hexadecimal address of the pointer that now has the value
> of the address of the first element of the array of integers;
> and the third element should the same address of the pointer
> but its decimal value;
>
> When I tried to compile this, I have received an error message,
> which I solved by casting (void *)
If the compiler is complaining that int * doesn't match void * in a call
to printf, then the cast is (saints preserve us) actually correct! This
is one of the very, very, very few times that a cast is not a completely
hopeless idea.
> to the first call to rowptr[row]
> (see my new printf below the original one), which is specified
> by %p; but I can't solve the second error message (see below)
> and I don't understand why the author has not mentioned anything
> about it:
> error: format specifies type 'int' but the argument has
> type 'int *' [-Werror,-Wformat]
> printf("\n%d %p %d", row, rowptr[row], rowptr[row]);
> ~~ ^~~~~~~~~~~
>
> **/
>
> /** original printf function:
> printf("\n%d %p %d", row, rowptr[row], rowptr[row]); **/
What is this horrible thing you are doing? \n is a line end character,
not a line beginning character! Ouch eek ow ow bad! (It's not against
the rules or anything. It just shows a complete disregard for the
semantics of \n.)
>
> // partially corrected printf
> printf("\n%d %p %d", row, (void *)rowptr[row], rowptr[row]);
You have been asked to do something too difficult. It's not impossible,
of course, but it's difficult.
Printing the address with %p is correct. But /how/ it is printed is
entirely up to the implementation. For example, on one early system it
might print something like "DS:04E0", which is part-hexadecimal and
part-abbreviation.
If you want to print it in hexadecimal (and then decimal), you're going
to need to get to the object representation of the pointer value. And
/that/ is a major distraction from learning about pointers to pointers.
>
> /** print the difference between the value of addresses of each row **/
>
> if (row > 0)
> printf(" %d",(int)(rowptr[row] - rowptr[row-1]));
And that's just broken. rowptr[row] and rowptr[row - 1] point to
different areas of memory. The subtraction invokes undefined behaviour.
What book is this, and why haven't you burned it yet? What happened to
your reading of K&R?
--
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within
[toc] | [prev] | [next] | [standalone]
| From | Alla _ <modelling.data@gmail.com> |
|---|---|
| Date | 2016-12-05 09:43 -0800 |
| Message-ID | <a9a728fd-cc8e-4b08-aabd-6877015ef5f8@googlegroups.com> |
| In reply to | #98024 |
On Monday, December 5, 2016 at 8:03:57 PM UTC+3, Richard Heathfield wrote:
> On 05/12/16 15:45, Alla _ wrote:
> >
> > Hello!
> >
> > Please, take a look at my reading of the program (in comments to each statement)
> > that uses pointers to two-dimensional arrays.
>
> No, it doesn't. Not at any point. What it does use is a pointer to
> pointer to int, which you point at the beginning of storage suitable for
> storing several int * objects. And those int * are used for pointing at
> the beginning of storage that is suitable for storing several int objects.
>
> > Is my understanding correct, i.e. do
> > correctly interpret the given code? And, please, help me to understand one part closer
> > to the end of the program.
> >
> >
> > #include <stdio.h>
> > #include <stdlib.h>
> > int main(void)
> > {
> > // define the number of rows and columns
> > int nrows = 5;
> > int ncols = 10;
> > int row;
> >
> > // initialise a pointer, which points to a pointer, which, in turn, points to type int,
> > // i.e. stores the address of an integer value
> > int **rowptr;
>
> Yes, rowptr is suitable for pointing to objects of type int *, which are
> in turn suitable to pointing to objects of type int.
>
> > /*** define rowptr pointer
>
> No, it's already defined. What you're about to do is assign to it.
>
> > by assigning to it the value of the address of the array,
> > allocated by the call to malloc for nrows (5 in this case) pointers to type int;
>
> That's one way to say it, yes. You are asking for enough storage to
> store 5 objects of type int *.
>
> > therefore the value of the rowptr after the call to malloc will be the address,
> > at which the first element in the array of pointers to integer type could be stored;
> > of course, none of these pointers yet point anywhere
> > ***/
>
> Correct.
>
> >
> > rowptr = malloc(nrows * sizeof(int *));
>
> Better: rowptr = malloc(nrows * sizeof *rowptr);
>
> which will still be correct even if you later change the type of rowptr.
>
> >
> > /** check of the memory has been allocated; if not, print the info message,
> > and exit **/
> > if (rowptr == NULL)
> > {
> > puts("\nFailure to allocate room for row pointers.\n");
> > exit(0);
> > }
>
> Yes. Not /quite/ how I would do it, but you are correctly checking that
> the storage allocation request succeeded. If it didn't, you have to take
> evasive action. Terminating the program, as you are doing, is generally
> acceptable in student code.
>
> > // Print the title
> > printf("\n\n\nIndex Pointer(hex) Pointer(dec) Diff.(dec)");
> >
> > /** Allocate memory for an array of ncols integers for every row, and store the value of the
> > allocated address of the first element of each array at the pointer rowptr[row],
> > such that rowptr[row] now points to corresponding address of the first element
> > in the array of ncols integers **/
>
> Yes.
>
> >
> > for (row = 0; row < nrows; row++)
> > {
> > rowptr[row] = malloc(ncols * sizeof(int));
>
> Better: rowptr[row] = malloc(ncols * sizeof *rowptr[row]);
>
> >
> > /** check of the memory has been allocated; if not, print the info message,
> > and exit **/
> > if (rowptr[row] == NULL)
> > {
> > printf("\nFailure to allocate for row[%d]\n",row);
> > exit(0);
> > }
>
> Yes, that's fine.
>
> > /** Here is the difficult part: print the number of the current row "row",
> > print the hexadecimal address of the pointer that now has the value
> > of the address of the first element of the array of integers;
> > and the third element should the same address of the pointer
> > but its decimal value;
> >
> > When I tried to compile this, I have received an error message,
> > which I solved by casting (void *)
>
> If the compiler is complaining that int * doesn't match void * in a call
> to printf, then the cast is (saints preserve us) actually correct! This
> is one of the very, very, very few times that a cast is not a completely
> hopeless idea.
>
> > to the first call to rowptr[row]
> > (see my new printf below the original one), which is specified
> > by %p; but I can't solve the second error message (see below)
> > and I don't understand why the author has not mentioned anything
> > about it:
> > error: format specifies type 'int' but the argument has
> > type 'int *' [-Werror,-Wformat]
> > printf("\n%d %p %d", row, rowptr[row], rowptr[row]);
> > ~~ ^~~~~~~~~~~
> >
> > **/
> >
> > /** original printf function:
> > printf("\n%d %p %d", row, rowptr[row], rowptr[row]); **/
>
> What is this horrible thing you are doing? \n is a line end character,
> not a line beginning character! Ouch eek ow ow bad! (It's not against
> the rules or anything. It just shows a complete disregard for the
> semantics of \n.)
>
> >
> > // partially corrected printf
> > printf("\n%d %p %d", row, (void *)rowptr[row], rowptr[row]);
>
> You have been asked to do something too difficult. It's not impossible,
> of course, but it's difficult.
>
> Printing the address with %p is correct. But /how/ it is printed is
> entirely up to the implementation. For example, on one early system it
> might print something like "DS:04E0", which is part-hexadecimal and
> part-abbreviation.
>
> If you want to print it in hexadecimal (and then decimal), you're going
> to need to get to the object representation of the pointer value. And
> /that/ is a major distraction from learning about pointers to pointers.
>
> >
> > /** print the difference between the value of addresses of each row **/
> >
> > if (row > 0)
> > printf(" %d",(int)(rowptr[row] - rowptr[row-1]));
>
> And that's just broken. rowptr[row] and rowptr[row - 1] point to
> different areas of memory. The subtraction invokes undefined behaviour.
> What book is this, and why haven't you burned it yet? What happened to
> your reading of K&R?
Thank you very very much! Nothing has happened to my reading K&R;
I had a disastrous time in terms of learning C because I couldn't allocate
( :D ) time for it due to certain obligations; given my love to C, it was very
difficult not to continue with a proper learning process. Now, to refresh what
I have already learned, I have found this thing, which, although not good, has
helped me, and it is based on K&R. I did notice those non-elegant semantics,
and have corrected them within my code, as well as deleting all global variables
the author is using. Also it raises interesting issues, part of which are covered
in the this code.
I also have to write a student's program within 2 weeks. So, I have to work
on this program, K&R and one more book on C, which is based on K&R, but
is more detailed and might be of a great help:
C: How to Program by Deitel and Deitel
I hope it will help me to understand the material better, and hopefully to do
all K&R exercises.
[toc] | [prev] | [next] | [standalone]
| From | Richard Heathfield <rjh@cpax.org.uk> |
|---|---|
| Date | 2016-12-05 18:16 +0000 |
| Message-ID | <o24ar4$pir$1@dont-email.me> |
| In reply to | #98030 |
On 05/12/16 17:43, Alla _ wrote: <snip> > I also have to write a student's program within 2 weeks. If you spent less time on these C courses, you might have time to learn C properly. > So, I have to work > on this program, K&R and one more book on C, which is based on K&R, but > is more detailed and might be of a great help: > C: How to Program by Deitel and Deitel > I hope it will help me to understand the material better, and hopefully to do > all K&R exercises. Deitel and Deitel is a reasonable book. Or at least I thought it was. Are you telling me the example code came from that book? If so, Deitel and Deitel have gone catastrophically downhill. -- Richard Heathfield Email: rjh at cpax dot org dot uk "Usenet is a strange place" - dmr 29 July 1999 Sig line 4 vacant - apply within
[toc] | [prev] | [next] | [standalone]
| From | Alla _ <modelling.data@gmail.com> |
|---|---|
| Date | 2016-12-05 22:46 -0800 |
| Message-ID | <e4ceb105-96f5-428b-8fd6-28fc20b28eab@googlegroups.com> |
| In reply to | #98034 |
On Monday, December 5, 2016 at 9:16:27 PM UTC+3, Richard Heathfield wrote: > On 05/12/16 17:43, Alla _ wrote: > > <snip> > > > I also have to write a student's program within 2 weeks. > > If you spent less time on these C courses, you might have time to learn > C properly. > > > So, I have to work > > on this program, K&R and one more book on C, which is based on K&R, but > > is more detailed and might be of a great help: > > C: How to Program by Deitel and Deitel > > I hope it will help me to understand the material better, and hopefully to do > > all K&R exercises. > > Deitel and Deitel is a reasonable book. Or at least I thought it was. > Are you telling me the example code came from that book? If so, Deitel > and Deitel have gone catastrophically downhill. > No no no, this example is not from that book, I have not yet started it. This example is from a tiny (53 pages) book on pointers, dating from 1997 or so.
[toc] | [prev] | [next] | [standalone]
| From | Richard Heathfield <rjh@cpax.org.uk> |
|---|---|
| Date | 2016-12-06 10:23 +0000 |
| Message-ID | <o263g7$v6m$1@dont-email.me> |
| In reply to | #98126 |
On 06/12/16 06:46, Alla _ wrote: > On Monday, December 5, 2016 at 9:16:27 PM UTC+3, Richard Heathfield wrote: >> On 05/12/16 17:43, Alla _ wrote: >> >> <snip> >> >>> I also have to write a student's program within 2 weeks. >> >> If you spent less time on these C courses, you might have time to learn >> C properly. >> >>> So, I have to work >>> on this program, K&R and one more book on C, which is based on K&R, but >>> is more detailed and might be of a great help: >>> C: How to Program by Deitel and Deitel >>> I hope it will help me to understand the material better, and hopefully to do >>> all K&R exercises. >> >> Deitel and Deitel is a reasonable book. Or at least I thought it was. >> Are you telling me the example code came from that book? If so, Deitel >> and Deitel have gone catastrophically downhill. >> > No no no, this example is not from that book, I have not yet started it. This example is from > a tiny (53 pages) book on pointers, dating from 1997 or so. That, at least, is a relief. Now that you know the book is seriously flawed, do you plan to continue using it? -- Richard Heathfield Email: rjh at cpax dot org dot uk "Usenet is a strange place" - dmr 29 July 1999 Sig line 4 vacant - apply within
[toc] | [prev] | [next] | [standalone]
| From | Alla _ <modelling.data@gmail.com> |
|---|---|
| Date | 2016-12-06 02:53 -0800 |
| Message-ID | <6b66b016-96d7-4c7e-856f-2942ca012384@googlegroups.com> |
| In reply to | #98135 |
On Tuesday, December 6, 2016 at 1:23:28 PM UTC+3, Richard Heathfield wrote: > On 06/12/16 06:46, Alla _ wrote: > > On Monday, December 5, 2016 at 9:16:27 PM UTC+3, Richard Heathfield wrote: > >> On 05/12/16 17:43, Alla _ wrote: > >> > >> <snip> > >> > >>> I also have to write a student's program within 2 weeks. > >> > >> If you spent less time on these C courses, you might have time to learn > >> C properly. > >> > >>> So, I have to work > >>> on this program, K&R and one more book on C, which is based on K&R, but > >>> is more detailed and might be of a great help: > >>> C: How to Program by Deitel and Deitel > >>> I hope it will help me to understand the material better, and hopefully to do > >>> all K&R exercises. > >> > >> Deitel and Deitel is a reasonable book. Or at least I thought it was. > >> Are you telling me the example code came from that book? If so, Deitel > >> and Deitel have gone catastrophically downhill. > >> > > No no no, this example is not from that book, I have not yet started it. This example is from > > a tiny (53 pages) book on pointers, dating from 1997 or so. > > That, at least, is a relief. Now that you know the book is seriously > flawed, do you plan to continue using it? > I am done with that book, as I have said yesterday - it served its purpose, and that's it; I don't need it anymore ) I have K&R and Deitel books.
[toc] | [prev] | [next] | [standalone]
| From | Richard Heathfield <rjh@cpax.org.uk> |
|---|---|
| Date | 2016-12-06 10:58 +0000 |
| Message-ID | <o265hg$3i7$4@dont-email.me> |
| In reply to | #98136 |
On 06/12/16 10:53, Alla _ wrote: > On Tuesday, December 6, 2016 at 1:23:28 PM UTC+3, Richard Heathfield wrote: >> On 06/12/16 06:46, Alla _ wrote: >>> On Monday, December 5, 2016 at 9:16:27 PM UTC+3, Richard Heathfield wrote: >>>> Deitel and Deitel is a reasonable book. Or at least I thought it was. >>>> Are you telling me the example code came from that book? If so, Deitel >>>> and Deitel have gone catastrophically downhill. >>>> >>> No no no, this example is not from that book, I have not yet started it. This example is from >>> a tiny (53 pages) book on pointers, dating from 1997 or so. >> >> That, at least, is a relief. Now that you know the book is seriously >> flawed, do you plan to continue using it? >> > I am done with that book, as I have said yesterday - it served its purpose, and that's it; > I don't need it anymore ) You didn't need it before, either. You need to get out of your head the idea that "this book is about C, therefore this book is good". Most books about C are written by people who don't know C terribly well. > I have K&R and Deitel books. For learning C, those two are sufficient. Please don't confuse yourself by getting any more, not until you've learned the language well enough not to be confused by wrong information. -- Richard Heathfield Email: rjh at cpax dot org dot uk "Usenet is a strange place" - dmr 29 July 1999 Sig line 4 vacant - apply within
[toc] | [prev] | [next] | [standalone]
| From | Alla _ <modelling.data@gmail.com> |
|---|---|
| Date | 2016-12-06 03:42 -0800 |
| Message-ID | <2a862878-be53-43ba-848a-f59943da580d@googlegroups.com> |
| In reply to | #98137 |
On Tuesday, December 6, 2016 at 1:58:15 PM UTC+3, Richard Heathfield wrote: > On 06/12/16 10:53, Alla _ wrote: > > On Tuesday, December 6, 2016 at 1:23:28 PM UTC+3, Richard Heathfield wrote: > >> On 06/12/16 06:46, Alla _ wrote: > >>> On Monday, December 5, 2016 at 9:16:27 PM UTC+3, Richard Heathfield wrote: > >>>> Deitel and Deitel is a reasonable book. Or at least I thought it was. > >>>> Are you telling me the example code came from that book? If so, Deitel > >>>> and Deitel have gone catastrophically downhill. > >>>> > >>> No no no, this example is not from that book, I have not yet started it. This example is from > >>> a tiny (53 pages) book on pointers, dating from 1997 or so. > >> > >> That, at least, is a relief. Now that you know the book is seriously > >> flawed, do you plan to continue using it? > >> > > I am done with that book, as I have said yesterday - it served its purpose, and that's it; > > I don't need it anymore ) > > You didn't need it before, either. > > You need to get out of your head the idea that "this book is about C, > therefore this book is good". Most books about C are written by people > who don't know C terribly well. > > > I have K&R and Deitel books. > > For learning C, those two are sufficient. Please don't confuse yourself > by getting any more, not until you've learned the language well enough > not to be confused by wrong information. > Thank you! Yes, I definitely won't look for any other books or materials.
[toc] | [prev] | [next] | [standalone]
| From | Alla _ <modelling.data@gmail.com> |
|---|---|
| Date | 2016-12-06 06:31 -0800 |
| Message-ID | <dabb5dff-d0d8-446a-b37c-60613fd9a8d3@googlegroups.com> |
| In reply to | #98137 |
On Tuesday, December 6, 2016 at 1:58:15 PM UTC+3, Richard Heathfield wrote: > On 06/12/16 10:53, Alla _ wrote: > > On Tuesday, December 6, 2016 at 1:23:28 PM UTC+3, Richard Heathfield wrote: > >> On 06/12/16 06:46, Alla _ wrote: > >>> On Monday, December 5, 2016 at 9:16:27 PM UTC+3, Richard Heathfield wrote: > >>>> Deitel and Deitel is a reasonable book. Or at least I thought it was. > >>>> Are you telling me the example code came from that book? If so, Deitel > >>>> and Deitel have gone catastrophically downhill. > >>>> > >>> No no no, this example is not from that book, I have not yet started it. This example is from > >>> a tiny (53 pages) book on pointers, dating from 1997 or so. > >> > >> That, at least, is a relief. Now that you know the book is seriously > >> flawed, do you plan to continue using it? > >> > > I am done with that book, as I have said yesterday - it served its purpose, and that's it; > > I don't need it anymore ) > > You didn't need it before, either. > > You need to get out of your head the idea that "this book is about C, > therefore this book is good". Most books about C are written by people > who don't know C terribly well. > > > I have K&R and Deitel books. > > For learning C, those two are sufficient. Please don't confuse yourself > by getting any more, not until you've learned the language well enough > not to be confused by wrong information. > I have decided to add for the sake of complete honesty: although, yes, I won't look for any more books for now, I have quite a few of them already, including the MIT one on algorithms, and much more ))) But! I will not even try to open them for now, that's for sure. At least I know my further steps, and it's always good to look and plan beyond current possibilities )
[toc] | [prev] | [next] | [standalone]
| From | Richard Heathfield <rjh@cpax.org.uk> |
|---|---|
| Date | 2016-12-06 14:49 +0000 |
| Message-ID | <o26j3q$mac$1@dont-email.me> |
| In reply to | #98165 |
On 06/12/16 14:31, Alla _ wrote:
> On Tuesday, December 6, 2016 at 1:58:15 PM UTC+3, Richard Heathfield wrote:
>> On 06/12/16 10:53, Alla _ wrote:
>>> On Tuesday, December 6, 2016 at 1:23:28 PM UTC+3, Richard Heathfield wrote:
>>>> On 06/12/16 06:46, Alla _ wrote:
>>>>> On Monday, December 5, 2016 at 9:16:27 PM UTC+3, Richard Heathfield wrote:
>>>>>> Deitel and Deitel is a reasonable book. Or at least I thought it was.
>>>>>> Are you telling me the example code came from that book? If so, Deitel
>>>>>> and Deitel have gone catastrophically downhill.
>>>>>>
>>>>> No no no, this example is not from that book, I have not yet started it. This example is from
>>>>> a tiny (53 pages) book on pointers, dating from 1997 or so.
>>>>
>>>> That, at least, is a relief. Now that you know the book is seriously
>>>> flawed, do you plan to continue using it?
>>>>
>>> I am done with that book, as I have said yesterday - it served its purpose, and that's it;
>>> I don't need it anymore )
>>
>> You didn't need it before, either.
>>
>> You need to get out of your head the idea that "this book is about C,
>> therefore this book is good". Most books about C are written by people
>> who don't know C terribly well.
>>
>>> I have K&R and Deitel books.
>>
>> For learning C, those two are sufficient. Please don't confuse yourself
>> by getting any more, not until you've learned the language well enough
>> not to be confused by wrong information.
>>
> I have decided to add for the sake of complete honesty: although, yes, I
> won't look for any more books for now, I have quite a few of them already,
> including the MIT one on algorithms, and much more ))) But! I will not
> even try to open them for now, that's for sure. At least I know my further
> steps, and it's always good to look and plan beyond current possibilities )
Books about algorithms are fine. I was only talking about books on C.
Sometimes, of course, C is used in books on algorithms. The trick is to
learn the algorithms from the algorithm experts, and C from the C
experts. K&R are of course C experts, and it isn't too much of a stretch
to say that Deitel and Deitel are, too. Also acceptable are Harbison &
Steele, and (so I am told) K N King ("C Programming: A Modern
Approach"). Oh, and let's not forget Steve Summit (C FAQs).
Don't make the mistake of thinking that experts on other subjects are
necessarily experts on C. Charles Petzold, for example, has a
tremendously in-depth knowledge of the Windows programming API, but his
C is absolutely gerharsterly.[1] The trick is to be able to extract the
good teaching and leave the bad C behind.
[1] Out of curiosity, I looked up this word in a Web search just now. To
my surprise, I only got seven hits. To my even greater surprise, *all
seven* of them were Web copies of articles I had posted to Usenet.
Oh well. I guess this makes it eight.
--
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within
[toc] | [prev] | [next] | [standalone]
| From | Alla _ <modelling.data@gmail.com> |
|---|---|
| Date | 2016-12-06 08:22 -0800 |
| Message-ID | <0ef69e52-232b-4b69-b38d-11d51530069f@googlegroups.com> |
| In reply to | #98166 |
On Tuesday, December 6, 2016 at 5:49:58 PM UTC+3, Richard Heathfield wrote:
> On 06/12/16 14:31, Alla _ wrote:
> > On Tuesday, December 6, 2016 at 1:58:15 PM UTC+3, Richard Heathfield wrote:
> >> On 06/12/16 10:53, Alla _ wrote:
> >>> On Tuesday, December 6, 2016 at 1:23:28 PM UTC+3, Richard Heathfield wrote:
> >>>> On 06/12/16 06:46, Alla _ wrote:
> >>>>> On Monday, December 5, 2016 at 9:16:27 PM UTC+3, Richard Heathfield wrote:
> >>>>>> Deitel and Deitel is a reasonable book. Or at least I thought it was.
> >>>>>> Are you telling me the example code came from that book? If so, Deitel
> >>>>>> and Deitel have gone catastrophically downhill.
> >>>>>>
> >>>>> No no no, this example is not from that book, I have not yet started it. This example is from
> >>>>> a tiny (53 pages) book on pointers, dating from 1997 or so.
> >>>>
> >>>> That, at least, is a relief. Now that you know the book is seriously
> >>>> flawed, do you plan to continue using it?
> >>>>
> >>> I am done with that book, as I have said yesterday - it served its purpose, and that's it;
> >>> I don't need it anymore )
> >>
> >> You didn't need it before, either.
> >>
> >> You need to get out of your head the idea that "this book is about C,
> >> therefore this book is good". Most books about C are written by people
> >> who don't know C terribly well.
> >>
> >>> I have K&R and Deitel books.
> >>
> >> For learning C, those two are sufficient. Please don't confuse yourself
> >> by getting any more, not until you've learned the language well enough
> >> not to be confused by wrong information.
> >>
> > I have decided to add for the sake of complete honesty: although, yes, I
> > won't look for any more books for now, I have quite a few of them already,
> > including the MIT one on algorithms, and much more ))) But! I will not
> > even try to open them for now, that's for sure. At least I know my further
> > steps, and it's always good to look and plan beyond current possibilities )
>
> Books about algorithms are fine. I was only talking about books on C.
> Sometimes, of course, C is used in books on algorithms. The trick is to
> learn the algorithms from the algorithm experts, and C from the C
> experts. K&R are of course C experts, and it isn't too much of a stretch
> to say that Deitel and Deitel are, too. Also acceptable are Harbison &
> Steele, and (so I am told) K N King ("C Programming: A Modern
> Approach"). Oh, and let's not forget Steve Summit (C FAQs).
>
> Don't make the mistake of thinking that experts on other subjects are
> necessarily experts on C. Charles Petzold, for example, has a
> tremendously in-depth knowledge of the Windows programming API, but his
> C is absolutely gerharsterly.[1] The trick is to be able to extract the
> good teaching and leave the bad C behind.
>
>
Of course, I understand all that. It doesn't apply only to C and/or programming )
> [1] Out of curiosity, I looked up this word in a Web search just now. To
> my surprise, I only got seven hits. To my even greater surprise, *all
> seven* of them were Web copies of articles I had posted to Usenet.
>
> Oh well. I guess this makes it eight.
>
Does it mean that this word is your invention? If so, what does it mean?
I have checked dictionaries, and have also checked German-English one
(because it does have some sort of a germanic sound),
just in case I could find meanings of some parts of this word to deduce
the overall meaning. Failed )
[toc] | [prev] | [next] | [standalone]
| From | Richard Heathfield <rjh@cpax.org.uk> |
|---|---|
| Date | 2016-12-06 16:48 +0000 |
| Message-ID | <o26q2c$hbe$1@dont-email.me> |
| In reply to | #98174 |
On 06/12/16 16:22, Alla _ wrote: > On Tuesday, December 6, 2016 at 5:49:58 PM UTC+3, Richard Heathfield wrote: <snip> >> Don't make the mistake of thinking that experts on other subjects are >> necessarily experts on C. Charles Petzold, for example, has a >> tremendously in-depth knowledge of the Windows programming API, but his >> C is absolutely gerharsterly.[1] The trick is to be able to extract the >> good teaching and leave the bad C behind. >> >> > Of course, I understand all that. It doesn't apply only to C and/or programming ) > >> [1] Out of curiosity, I looked up this word in a Web search just now. To >> my surprise, I only got seven hits. To my even greater surprise, *all >> seven* of them were Web copies of articles I had posted to Usenet. >> >> Oh well. I guess this makes it eight. >> > Does it mean that this word is your invention? No. That's the strange thing. As far as I can tell, it was Terry Pratchett who first used that spelling, in "Moving Pictures" (context: "gerharsterly things from the Dungeon Dimensions", or something along those lines). But this doesn't seem to have been quoted anywhere on the Web, and neither does anyone else appear to have adopted it. > If so, what does it mean? It's a corruption of "ghastly", which you will find in any reasonable dictionary. -- Richard Heathfield Email: rjh at cpax dot org dot uk "Usenet is a strange place" - dmr 29 July 1999 Sig line 4 vacant - apply within
[toc] | [prev] | [next] | [standalone]
| From | Alla _ <modelling.data@gmail.com> |
|---|---|
| Date | 2016-12-06 09:15 -0800 |
| Message-ID | <a8d2a606-3e80-4b10-93a0-82088904e536@googlegroups.com> |
| In reply to | #98177 |
On Tuesday, December 6, 2016 at 7:48:35 PM UTC+3, Richard Heathfield wrote: > On 06/12/16 16:22, Alla _ wrote: > > On Tuesday, December 6, 2016 at 5:49:58 PM UTC+3, Richard Heathfield wrote: > > <snip> > > >> Don't make the mistake of thinking that experts on other subjects are > >> necessarily experts on C. Charles Petzold, for example, has a > >> tremendously in-depth knowledge of the Windows programming API, but his > >> C is absolutely gerharsterly.[1] The trick is to be able to extract the > >> good teaching and leave the bad C behind. > >> > >> > > Of course, I understand all that. It doesn't apply only to C and/or programming ) > > > >> [1] Out of curiosity, I looked up this word in a Web search just now. To > >> my surprise, I only got seven hits. To my even greater surprise, *all > >> seven* of them were Web copies of articles I had posted to Usenet. > >> > >> Oh well. I guess this makes it eight. > >> > > Does it mean that this word is your invention? > > No. That's the strange thing. As far as I can tell, it was Terry > Pratchett who first used that spelling, in "Moving Pictures" (context: > "gerharsterly things from the Dungeon Dimensions", or something along > those lines). But this doesn't seem to have been quoted anywhere on the > Web, and neither does anyone else appear to have adopted it. > > > If so, what does it mean? > > It's a corruption of "ghastly", which you will find in any reasonable > dictionary. > Good that at least this one I managed to understand in a snap )
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2016-12-06 08:20 -0800 |
| Message-ID | <ln37i13u7v.fsf@kst-u.example.com> |
| In reply to | #98126 |
Alla _ <modelling.data@gmail.com> writes:
[...]
>> Deitel and Deitel is a reasonable book. Or at least I thought it was.
>> Are you telling me the example code came from that book? If so, Deitel
>> and Deitel have gone catastrophically downhill.
>>
> No no no, this example is not from that book, I have not yet started
> it. This example is from a tiny (53 pages) book on pointers, dating
> from 1997 or so.
Is there some reason you're unwilling to identify the book? I'd like to
know what it is so I can take a look and possibly warn people away from
it.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Alla _ <modelling.data@gmail.com> |
|---|---|
| Date | 2016-12-05 22:53 -0800 |
| Message-ID | <3127b0eb-c0c1-4e70-b5a3-b891b41318e8@googlegroups.com> |
| In reply to | #98034 |
On Monday, December 5, 2016 at 9:16:27 PM UTC+3, Richard Heathfield wrote: > On 05/12/16 17:43, Alla _ wrote: > > <snip> > > > I also have to write a student's program within 2 weeks. > > If you spent less time on these C courses, you might have time to learn > C properly. Yes, I agree, that is why I have to write the program in two weeks and get over with it, so to be able to learn C. Now I do have a sense of few basic languages, but none compare to C (though given the huge few months hiatus in programming, I am not sure I remember those properly :) ). I do think that C is the best language, although php and java are more suitable for higher level programming, and for all web programming; still I believe that none can compare to C - it's interesting, elegant, not so easy, which makes it even more attractive. I have no idea why people shun learning it, and learn only higher level languages. > > > So, I have to work > > on this program, K&R and one more book on C, which is based on K&R, but > > is more detailed and might be of a great help: > > C: How to Program by Deitel and Deitel > > I hope it will help me to understand the material better, and hopefully to do > > all K&R exercises. > > Deitel and Deitel is a reasonable book. Or at least I thought it was. > Are you telling me the example code came from that book? If so, Deitel > and Deitel have gone catastrophically downhill. > > -- > Richard Heathfield > Email: rjh at cpax dot org dot uk > "Usenet is a strange place" - dmr 29 July 1999 > Sig line 4 vacant - apply within
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2016-12-05 09:26 -0800 |
| Message-ID | <lnvauy478f.fsf@kst-u.example.com> |
| In reply to | #98017 |
Alla _ <modelling.data@gmail.com> writes:
> Please, take a look at my reading of the program (in comments to each
> statement) that uses pointers to two-dimensional arrays. Is my
> understanding correct, i.e. do correctly interpret the given code?
> And, please, help me to understand one part closer to the end of the
> program.
I presume this is code you got from someone else, not something you
wrote.
The indentation is inconsistent and IMHO excessive. The comments are
far more verbose than you'd want in real-world code, but the program is
obviously intended for teaching, not production.
There is no pointer to a two-dimensional array anywhere in the code.
Such a pointer might be defined like this:
int (*p)[10][20]
The program creates a data structure that acts like a two-dimensional
array, but isn't one (and the way the program does it is likely to be
more useful and flexible than an actual 2D array). It creates an array
of int* pointers, each of which points to an array of ints, with
everything allocated using malloc(), with an int** pointing to the
initial element of the array of pointers. It's similar to the layout
used by argv.
> #include <stdio.h>
> #include <stdlib.h>
> int main(void)
> {
> // define the number of rows and columns
> int nrows = 5;
> int ncols = 10;
> int row;
>
> // initialise a pointer, which points to a pointer, which, in turn, points to type int,
> // i.e. stores the address of an integer value
> int **rowptr;
The comment is incorrect. This declares and defines a pointer object,
but it doesn't *initialize* anything. Also, "the address of an integer
value" doesn't make sense; values don't have addresses. A pointer
points to an object, not to a value.
> /*** define rowptr pointer by assigning to it the value of the address of the array,
> allocated by the call to malloc for nrows (5 in this case) pointers to type int;
> therefore the value of the rowptr after the call to malloc will be the address,
> at which the first element in the array of pointers to integer type could be stored;
> of course, none of these pointers yet point anywhere
> ***/
rowptr holds the address of *the initial element of* the array, not the
address of the array itself. The two refer to the same location in
memory, but with different types. It's common to refer to a pointer to
(equivalently, the address of) the initial element of an array as a
pointer to the array itself, but it's incorrect.
> rowptr = malloc(nrows * sizeof(int *));
This is ok, but it would be better written using the usual idiom:
rowptr = malloc(nrows * sizeof *rowptr);
You can add parentheses around *rowptr if you think that makes it
clearer (personally, I don't).
> /** check of the memory has been allocated; if not, print the info message,
> and exit **/
> if (rowptr == NULL)
> {
> puts("\nFailure to allocate room for row pointers.\n");
> exit(0);
> }
Error messages should be printed to stderr, and program failure should
be indicated by returning a non-zero status, preferably EXIT_FAILURE.
if (rowptr == NULL) {
fputs("Failure to allocate room for row pointers.\n", stderr);
exit(EXIT_FAILURE);
}
Exiting on a malloc failure is a bit drastic, but it's ok for a small
demo program like this.
> // Print the title
> printf("\n\n\nIndex Pointer(hex) Pointer(dec) Diff.(dec)");
The author of this program certainly likes newlines, but omits them at
the ends of lines. I see this kind of thing in program written for
Windows. Perhaps there's some reason to print three blank lines before
the title. Normally every line of output should end in a newline.
> /** Allocate memory for an array of ncols integers for every row, and store the value of the
> allocated address of the first element of each array at the pointer rowptr[row],
> such that rowptr[row] now points to corresponding address of the first element
> in the array of ncols integers **/
That description seems to be accurate, apart from a bit of confusion
about a pointer "pointing to an address" vs. "*containing* an address"
and "pointing to an object".
> for (row = 0; row < nrows; row++)
> {
> rowptr[row] = malloc(ncols * sizeof(int));
Again, I'd write this as:
rowptr[row] = malloc(ncols * sizeof *rowptr[row]);
> /** check of the memory has been allocated; if not, print the info message,
> and exit **/
> if (rowptr[row] == NULL)
> {
> printf("\nFailure to allocate for row[%d]\n",row);
> exit(0);
> }
And again, the error message should be printed to stderr, and exit(0)
should be exit(EXIT_FAILURE).
> /** Here is the difficult part: print the number of the current row "row",
> print the hexadecimal address of the pointer that now has the value
> of the address of the first element of the array of integers;
> and the third element should the same address of the pointer
> but its decimal value;
>
> When I tried to compile this, I have received an error message,
> which I solved by casting (void *) to the first call to rowptr[row]
> (see my new printf below the original one), which is specified
> by %p; but I can't solve the second error message (see below)
> and I don't understand why the author has not mentioned anything
> about it:
> error: format specifies type 'int' but the argument has
> type 'int *' [-Werror,-Wformat]
> printf("\n%d %p %d", row, rowptr[row], rowptr[row]);
> ~~ ^~~~~~~~~~~
>
> **/
>
> /** original printf function:
> printf("\n%d %p %d", row, rowptr[row], rowptr[row]); **/
This is attempting to print pointer values as integers. The original
author seems to be unaware that this has undefined behavior, and
particularly on a system where int and pointers have different sizes it
can fail badly.
row is of type int, so of course %d is the correct format.
The code uses %p to print the value of rowptr[row], which is of type
int*. That's almost correct, but %p requires an argument of type void*,
not int*. The two types have the same representation on *most* systems,
so that's likely to "work", but there are no guarantees. You need to
cast the value to void* (as you've done below). Note that the author
assumes that %p prints pointer values in hexadecimal; that's common, but
not specified by the standard.
Using "%d" to print the value of rowptr[row] again is likely to "work"
on *some* systems, but can fail badly. (On my system, where int is 32
bits and pointers are 64 bits, it appears to discard the high-order bits
of the pointer value.) It can be corrected; see below.
> // partially corrected printf
> printf("\n%d %p %d", row, (void *)rowptr[row], rowptr[row]);
You've correctly fixed the first attempt to print the value of
rowptr[row]. The final %d is intended to print the pointer value in
decimal -- something that might not even make sense.
I'd convert the pointer value to uintptr_t and print it:
printf("%d %p %llu\n",
row,
(void*)rowptr[row],
(unsigned long long)(uintptr_t)rowptr[row]);
Note that this requires adding "#include <stdint.h>" at the top.
I convert the pointer value to uintptr_t because that conversion is well
defined *if* the implementation defines uintptr_t. I then convert it to
unsigned long long so I can print it with "%llu". I could *probably*
get away with converting directly to unsigned long long, but I'm being
paranoid. (If I were being *really* paranoid, I'd cast rowptr[row] to
void* before casting it to uintptr_t. I might also use uintmax_t rather
than unsigned long long, just in case uintptr_t is an extended integer
type wider than unsigned long long -- which is very unlikely.)
I could have used the PRIuPTR macro defined in <inttypes.h> to print the
uintptr_t value directly, but I can never remember how all those macros
are spelled, so I just convert to a known type instead.
There's no guarantee that the result of the conversion is meaningful,
but on most systems it will be. (Personally I'd just stick with "%p"
and count on the system to show me something meaningful.)
> /** print the difference between the value of addresses of each row **/
>
> if (row > 0)
> printf(" %d",(int)(rowptr[row] - rowptr[row-1]));
Now this is a bit messed up. The author gets points for using pointer
arithmetic and converting the result to int, but the result is not
particularly meaningful. The pointers being subtracted are of type
int*, so the difference is in units of sizeof(int) not in bytes. The
decimal values are likely to be byte addresses, so the displayed
differences aren't going to correspond to them. That might be
interesting, but there are no comments indicating that the author is
aware of this important distinction.
Furthermore, the two pointers point to distinct objects, allocated by
separate calls to malloc(), so subtracting them has undefined behavior.
Since malloc() allocates strictly allocated memory, the difference is
likely to be a whole number of units of sizeof (int*) bytes, and the
output might give some insight into how the system's malloc() behaves,
but there's no indication that the author really knows what's going on.
Perhaps there's more context at the place where you got this program?
On my system, the pointers differ by 48 bytes, which is probably
an indication of how much overhead when malloc allocates 8 bytes
(sizeof (int*)).
> }
> return 0;
> }
Here's my version of the program, without the comments:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
int main(void) {
const int nrows = 5;
const int ncols = 10;
int **rowptr = malloc(nrows * sizeof *rowptr);
if (rowptr == NULL) {
fputs("Failure to allocate room for row pointers.\n", stderr);
exit(EXIT_FAILURE);
}
printf("Index Pointer(hex) Pointer(dec) Diff.(dec)\n");
for (int row = 0; row < nrows; row++) {
rowptr[row] = malloc(ncols * sizeof *rowptr[row]);
if (rowptr[row] == NULL) {
fprintf(stderr, "Failure to allocate for row %d\n", row);
exit(EXIT_FAILURE);
}
printf("%d %p %llu",
row, (void *) rowptr[row], (unsigned long
long)(uintptr_t)rowptr[row]);
if (row > 0) {
printf(" %d", (int)((char*)rowptr[row] -
(char*)rowptr[row-1]));
}
putchar('\n');
}
return 0;
}
The output on my system is:
Index Pointer(hex) Pointer(dec) Diff.(dec)
0 0x55c044d51450 94284276896848
1 0x55c044d51480 94284276896896 48
2 0x55c044d514b0 94284276896944 48
3 0x55c044d514e0 94284276896992 48
4 0x55c044d51510 94284276897040 48
The output when I compile in 32-bit mode (gcc -m32) is:
Index Pointer(hex) Pointer(dec) Diff.(dec)
0 0x57726428 1467114536
1 0x57726458 1467114584 48
2 0x57726488 1467114632 48
3 0x577264b8 1467114680 48
4 0x577264e8 1467114728 48
(Aligning the columns would be an interesting exercise.)
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Alla _ <modelling.data@gmail.com> |
|---|---|
| Date | 2016-12-05 09:47 -0800 |
| Message-ID | <128218c6-6fa1-49e3-8224-93d5810d060c@googlegroups.com> |
| In reply to | #98025 |
On Monday, December 5, 2016 at 8:26:46 PM UTC+3, Keith Thompson wrote: > Alla _ <modelling.data@gmail.com> writes: > > Please, take a look at my reading of the program (in comments to each > > statement) that uses pointers to two-dimensional arrays. Is my > > understanding correct, i.e. do correctly interpret the given code? > > And, please, help me to understand one part closer to the end of the > > program. > > I presume this is code you got from someone else, not something you > wrote. > > The indentation is inconsistent and IMHO excessive. The comments are > far more verbose than you'd want in real-world code, but the program is > obviously intended for teaching, not production. > I am sniping the rest of your message - I have just started reading it, but have decided to comment on these two paragraphs first: yes, of course, I have not written this code; this is the code I have picked up from a book on pointers. But all these bizarre looking and excessive comments are mine, and they are not intended to be usual comments to a program but a mere description of the way I read the code :) <snip>
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2016-12-05 12:10 -0800 |
| Message-ID | <lnk2be3znn.fsf@kst-u.example.com> |
| In reply to | #98031 |
Alla _ <modelling.data@gmail.com> writes:
> On Monday, December 5, 2016 at 8:26:46 PM UTC+3, Keith Thompson wrote:
>> Alla _ <modelling.data@gmail.com> writes:
>> > Please, take a look at my reading of the program (in comments to each
>> > statement) that uses pointers to two-dimensional arrays. Is my
>> > understanding correct, i.e. do correctly interpret the given code?
>> > And, please, help me to understand one part closer to the end of the
>> > program.
>>
>> I presume this is code you got from someone else, not something you
>> wrote.
>>
>> The indentation is inconsistent and IMHO excessive. The comments are
>> far more verbose than you'd want in real-world code, but the program is
>> obviously intended for teaching, not production.
>>
> I am sniping the rest of your message - I have just started reading it,
> but have decided to comment on these two paragraphs first:
> yes, of course, I have not written this code; this is the code I have
> picked up from a book on pointers. But all these bizarre looking and
> excessive comments are mine, and they are not intended to be
> usual comments to a program but a mere description of the way
> I read the code :)
> <snip>
What book?
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Alla _ <modelling.data@gmail.com> |
|---|---|
| Date | 2016-12-05 10:00 -0800 |
| Message-ID | <abc7808c-b5e5-49b4-b6e6-5c67f82eca21@googlegroups.com> |
| In reply to | #98025 |
On Monday, December 5, 2016 at 8:26:46 PM UTC+3, Keith Thompson wrote:
> Alla _ <modelling.data@gmail.com> writes:
> > Please, take a look at my reading of the program (in comments to each
> > statement) that uses pointers to two-dimensional arrays. Is my
> > understanding correct, i.e. do correctly interpret the given code?
> > And, please, help me to understand one part closer to the end of the
> > program.
>
> I presume this is code you got from someone else, not something you
> wrote.
>
> The indentation is inconsistent and IMHO excessive. The comments are
> far more verbose than you'd want in real-world code, but the program is
> obviously intended for teaching, not production.
>
> There is no pointer to a two-dimensional array anywhere in the code.
> Such a pointer might be defined like this:
> int (*p)[10][20]
>
> The program creates a data structure that acts like a two-dimensional
> array, but isn't one (and the way the program does it is likely to be
> more useful and flexible than an actual 2D array). It creates an array
> of int* pointers, each of which points to an array of ints, with
> everything allocated using malloc(), with an int** pointing to the
> initial element of the array of pointers. It's similar to the layout
> used by argv.
>
> > #include <stdio.h>
> > #include <stdlib.h>
> > int main(void)
> > {
> > // define the number of rows and columns
> > int nrows = 5;
> > int ncols = 10;
> > int row;
> >
> > // initialise a pointer, which points to a pointer, which, in turn, points to type int,
> > // i.e. stores the address of an integer value
> > int **rowptr;
>
> The comment is incorrect. This declares and defines a pointer object,
> but it doesn't *initialize* anything. Also, "the address of an integer
> value" doesn't make sense; values don't have addresses. A pointer
> points to an object, not to a value.
>
> > /*** define rowptr pointer by assigning to it the value of the address of the array,
> > allocated by the call to malloc for nrows (5 in this case) pointers to type int;
> > therefore the value of the rowptr after the call to malloc will be the address,
> > at which the first element in the array of pointers to integer type could be stored;
> > of course, none of these pointers yet point anywhere
> > ***/
>
> rowptr holds the address of *the initial element of* the array, not the
> address of the array itself. The two refer to the same location in
> memory, but with different types. It's common to refer to a pointer to
> (equivalently, the address of) the initial element of an array as a
> pointer to the array itself, but it's incorrect.
>
> > rowptr = malloc(nrows * sizeof(int *));
>
> This is ok, but it would be better written using the usual idiom:
>
> rowptr = malloc(nrows * sizeof *rowptr);
>
> You can add parentheses around *rowptr if you think that makes it
> clearer (personally, I don't).
>
> > /** check of the memory has been allocated; if not, print the info message,
> > and exit **/
> > if (rowptr == NULL)
> > {
> > puts("\nFailure to allocate room for row pointers.\n");
> > exit(0);
> > }
>
> Error messages should be printed to stderr, and program failure should
> be indicated by returning a non-zero status, preferably EXIT_FAILURE.
>
> if (rowptr == NULL) {
> fputs("Failure to allocate room for row pointers.\n", stderr);
> exit(EXIT_FAILURE);
> }
>
> Exiting on a malloc failure is a bit drastic, but it's ok for a small
> demo program like this.
>
> > // Print the title
> > printf("\n\n\nIndex Pointer(hex) Pointer(dec) Diff.(dec)");
>
> The author of this program certainly likes newlines, but omits them at
> the ends of lines. I see this kind of thing in program written for
> Windows. Perhaps there's some reason to print three blank lines before
> the title. Normally every line of output should end in a newline.
>
> > /** Allocate memory for an array of ncols integers for every row, and store the value of the
> > allocated address of the first element of each array at the pointer rowptr[row],
> > such that rowptr[row] now points to corresponding address of the first element
> > in the array of ncols integers **/
>
> That description seems to be accurate, apart from a bit of confusion
> about a pointer "pointing to an address" vs. "*containing* an address"
> and "pointing to an object".
>
> > for (row = 0; row < nrows; row++)
> > {
> > rowptr[row] = malloc(ncols * sizeof(int));
>
> Again, I'd write this as:
>
> rowptr[row] = malloc(ncols * sizeof *rowptr[row]);
>
> > /** check of the memory has been allocated; if not, print the info message,
> > and exit **/
> > if (rowptr[row] == NULL)
> > {
> > printf("\nFailure to allocate for row[%d]\n",row);
> > exit(0);
> > }
>
> And again, the error message should be printed to stderr, and exit(0)
> should be exit(EXIT_FAILURE).
>
> > /** Here is the difficult part: print the number of the current row "row",
> > print the hexadecimal address of the pointer that now has the value
> > of the address of the first element of the array of integers;
> > and the third element should the same address of the pointer
> > but its decimal value;
> >
> > When I tried to compile this, I have received an error message,
> > which I solved by casting (void *) to the first call to rowptr[row]
> > (see my new printf below the original one), which is specified
> > by %p; but I can't solve the second error message (see below)
> > and I don't understand why the author has not mentioned anything
> > about it:
> > error: format specifies type 'int' but the argument has
> > type 'int *' [-Werror,-Wformat]
> > printf("\n%d %p %d", row, rowptr[row], rowptr[row]);
> > ~~ ^~~~~~~~~~~
> >
> > **/
> >
> > /** original printf function:
> > printf("\n%d %p %d", row, rowptr[row], rowptr[row]); **/
>
> This is attempting to print pointer values as integers. The original
> author seems to be unaware that this has undefined behavior, and
> particularly on a system where int and pointers have different sizes it
> can fail badly.
>
> row is of type int, so of course %d is the correct format.
>
> The code uses %p to print the value of rowptr[row], which is of type
> int*. That's almost correct, but %p requires an argument of type void*,
> not int*. The two types have the same representation on *most* systems,
> so that's likely to "work", but there are no guarantees. You need to
> cast the value to void* (as you've done below). Note that the author
> assumes that %p prints pointer values in hexadecimal; that's common, but
> not specified by the standard.
>
> Using "%d" to print the value of rowptr[row] again is likely to "work"
> on *some* systems, but can fail badly. (On my system, where int is 32
> bits and pointers are 64 bits, it appears to discard the high-order bits
> of the pointer value.) It can be corrected; see below.
>
> > // partially corrected printf
> > printf("\n%d %p %d", row, (void *)rowptr[row], rowptr[row]);
>
> You've correctly fixed the first attempt to print the value of
> rowptr[row]. The final %d is intended to print the pointer value in
> decimal -- something that might not even make sense.
>
> I'd convert the pointer value to uintptr_t and print it:
>
> printf("%d %p %llu\n",
> row,
> (void*)rowptr[row],
> (unsigned long long)(uintptr_t)rowptr[row]);
>
> Note that this requires adding "#include <stdint.h>" at the top.
>
> I convert the pointer value to uintptr_t because that conversion is well
> defined *if* the implementation defines uintptr_t. I then convert it to
> unsigned long long so I can print it with "%llu". I could *probably*
> get away with converting directly to unsigned long long, but I'm being
> paranoid. (If I were being *really* paranoid, I'd cast rowptr[row] to
> void* before casting it to uintptr_t. I might also use uintmax_t rather
> than unsigned long long, just in case uintptr_t is an extended integer
> type wider than unsigned long long -- which is very unlikely.)
>
> I could have used the PRIuPTR macro defined in <inttypes.h> to print the
> uintptr_t value directly, but I can never remember how all those macros
> are spelled, so I just convert to a known type instead.
>
> There's no guarantee that the result of the conversion is meaningful,
> but on most systems it will be. (Personally I'd just stick with "%p"
> and count on the system to show me something meaningful.)
>
> > /** print the difference between the value of addresses of each row **/
> >
> > if (row > 0)
> > printf(" %d",(int)(rowptr[row] - rowptr[row-1]));
>
> Now this is a bit messed up. The author gets points for using pointer
> arithmetic and converting the result to int, but the result is not
> particularly meaningful. The pointers being subtracted are of type
> int*, so the difference is in units of sizeof(int) not in bytes. The
> decimal values are likely to be byte addresses, so the displayed
> differences aren't going to correspond to them. That might be
> interesting, but there are no comments indicating that the author is
> aware of this important distinction.
>
> Furthermore, the two pointers point to distinct objects, allocated by
> separate calls to malloc(), so subtracting them has undefined behavior.
> Since malloc() allocates strictly allocated memory, the difference is
> likely to be a whole number of units of sizeof (int*) bytes, and the
> output might give some insight into how the system's malloc() behaves,
> but there's no indication that the author really knows what's going on.
> Perhaps there's more context at the place where you got this program?
>
> On my system, the pointers differ by 48 bytes, which is probably
> an indication of how much overhead when malloc allocates 8 bytes
> (sizeof (int*)).
>
> > }
> > return 0;
> > }
>
> Here's my version of the program, without the comments:
>
> #include <stdio.h>
> #include <stdlib.h>
> #include <stdint.h>
> int main(void) {
> const int nrows = 5;
> const int ncols = 10;
> int **rowptr = malloc(nrows * sizeof *rowptr);
> if (rowptr == NULL) {
> fputs("Failure to allocate room for row pointers.\n", stderr);
> exit(EXIT_FAILURE);
> }
>
> printf("Index Pointer(hex) Pointer(dec) Diff.(dec)\n");
>
> for (int row = 0; row < nrows; row++) {
> rowptr[row] = malloc(ncols * sizeof *rowptr[row]);
> if (rowptr[row] == NULL) {
> fprintf(stderr, "Failure to allocate for row %d\n", row);
> exit(EXIT_FAILURE);
> }
> printf("%d %p %llu",
> row, (void *) rowptr[row], (unsigned long
> long)(uintptr_t)rowptr[row]);
> if (row > 0) {
> printf(" %d", (int)((char*)rowptr[row] -
> (char*)rowptr[row-1]));
> }
> putchar('\n');
> }
> return 0;
> }
>
> The output on my system is:
>
> Index Pointer(hex) Pointer(dec) Diff.(dec)
> 0 0x55c044d51450 94284276896848
> 1 0x55c044d51480 94284276896896 48
> 2 0x55c044d514b0 94284276896944 48
> 3 0x55c044d514e0 94284276896992 48
> 4 0x55c044d51510 94284276897040 48
>
> The output when I compile in 32-bit mode (gcc -m32) is:
>
> Index Pointer(hex) Pointer(dec) Diff.(dec)
> 0 0x57726428 1467114536
> 1 0x57726458 1467114584 48
> 2 0x57726488 1467114632 48
> 3 0x577264b8 1467114680 48
> 4 0x577264e8 1467114728 48
>
> (Aligning the columns would be an interesting exercise.)
>
> --
> Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
> Working, but not speaking, for JetHead Development, Inc.
> "We must do something. This is something. Therefore, we must do this."
> -- Antony Jay and Jonathan Lynn, "Yes Minister"
Thank you very much! I have learned a lot again thanks to your explanations
and explanations Richard has written above. Thank you!
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | comp.lang.c
csiph-web