Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C Programming (http://www.velocityreviews.com/forums/f42-c-programming.html)
-   -   pointer to pointer (http://www.velocityreviews.com/forums/t740614-pointer-to-pointer.html)

arnuld 12-22-2010 03:43 AM

pointer to pointer
 
Its just a very simple and basic program to learn exactly what is
described in comments here. Can you provide a better (and short)
exercise ?


/* A program to learn how to use a pointer to a pointer. Here we take an
array of char pointers. A char* in the array, of course, points
* to some char. Array has only one element. We change the value of char
pointed by array's element using a function.
*
* VERSION 0.0
*/
#include <stdio.h>

void replace_char_value(char* [], char);

int main(void)
{
char* arrc[2] = {0};
char c = 'c';
arrc[0] = &c;

printf("*arrc: %p, **arrc: %c\n", (void*)*arrc, **arrc);
replace_char_value(arrc, 'w');
printf("*arrc: %p, **arrc: %c\n", (void*)*arrc, **arrc);

return 0;
}


void replace_char_value(char* arr[], const char t)
{
**arr = t;
}

==================== OUTPUT =======================
[arnuld@dune programs]$ gcc -ansi -pedantic -Wall -Wextra pointer-to-
pointer.c
[arnuld@dune programs]$ ./a.out
*arrc: 0xbfffe8ab, **arrc: c
*arrc: 0xbfffe8ab, **arrc: w
[arnuld@dune programs]$




--
http://www.lispmachine.wordpress.com

Ian Collins 12-22-2010 04:05 AM

Re: pointer to pointer
 
On 12/22/10 04:43 PM, arnuld wrote:
> Its just a very simple and basic program to learn exactly what is
> described in comments here. Can you provide a better (and short)
> exercise ?


Parse the arguments to a program. Don't forget argv is a pointer to
pointer!

Given ./a.out -a 10 -b 20

print out the values of a and b.

--
Ian Collins

Mark Wooding 12-22-2010 12:10 PM

Re: pointer to pointer
 
arnuld <sunrise@invalid.address> writes:

> Its just a very simple and basic program to learn exactly what is
> described in comments here. Can you provide a better (and short)
> exercise ?


Several linked-list idioms involve a pointer-to-a-pointer. The most
obvious ones are

* Removing an item from a singly-linked list.

* Inserting an item into a sorted singly-linked list.

* Building up a list in order, one at a time.

The last is especially simple, and will serve as an example of the
general technique. Suppose that you have a node structure like this

struct node {
struct node *next;
/* other members here */
};

You build a list in order by remembering where the trailing link is.
Initially, the trailing link is actually the list head pointer.

struct node *head, **tail = &head;
struct node *n;

To attach a new node n to the list, you do this:

*tail = n;
tail = &n->next;

and finally you terminate the list like this:

*tail = 0;

I encourage you to draw diagrams to see why this works.

Of course, you can abstract the core of the algorithm into a function.
If you do this in the obvious way, you will find that you need to pass
in the /address/ of the trailing-link pointer, which is a pointer to a
pointer to a pointer:

static link_to_end(struct node *n, struct node ***tail)
{
**tail = n;
*tail = &n->node;
}

This is the simplest natural example I know of for a `three-star'
pointer.

-- [mdw]

arnuld 12-23-2010 07:29 AM

Re: pointer to pointer
 
> On Wed, 22 Dec 2010 17:05:29 +1300, Ian Collins wrote:

> Parse the arguments to a program. Don't forget argv is a pointer to
> pointer!
>
> Given ./a.out -a 10 -b 20
>
> print out the values of a and b.



How about this. Two questions:

(1) How to write it better ?
(2) How to avoid OUTPUT-2 ?



/* A program given by Ian Collins on CLC. Parse input to C Program this
way:
* GIVEN: ./a.out a -10 b 2, print out values of a and b
*
* Assumptions: separator between 2 values is one space. User may enter
two elements together without any value but then program will
* take 2nd element as value of first element.
* VERSION 0.0
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void printElementAndValue(char** t);

int main(int argc, char* argv[])
{
/* char* pe; Pointer to element */
/* char* pv; Pointer to value */
char** t;

if(1 == argc)
{
printf("USE: ./a.out [ELEMENT1] [VALUE1] [ELEMENT2] [VALUE2] ....
\n");
exit(EXIT_FAILURE);
}
else if(0 == (argc % 2))
{
printf("Please enter proper input: [ELEMENT] [VALUE] \n");
exit(EXIT_FAILURE);
}

for(t = argv + 1; *t; ++t, ++t)
{
printElementAndValue(t);
}

return 0;
}


void printElementAndValue(char** t)
{
const char element_identifier = '-';
if(strchr(*t, element_identifier))
{
printf("%s = ", *t++);
printf("%s\n", *t);
}
else
{
printf("Improper input. Key identifier, '-', was not used ?\n");
}

}
==================== OUTPUT ==============================
[arnuld@dune programs]$ gcc -ansi -pedantic -Wall -Wextra PtoP_argv-
parse.c
[arnuld@dune programs]$ ./a.out -a 10 -b 3
-a = 10
-b = 3
[arnuld@dune programs]$



================= OUTPUT-2 ==========================
[arnuld@dune programs]$ ./a.out -a 10 -b *
-a = 10
-b = a.out
Improper input. Key identifier, '-', was not used ?
Improper input. Key identifier, '-', was not used ?
problem-scanf.c = PtoP_argv-parse.c
PtoP_argv-parse.c~ = scanf-problems.c
sequence-point.c = strcpy.c
Improper input. Key identifier, '-', was not used ?
[arnuld@dune programs]$




--
http://www.lispmachine.wordpress.com

Chad 12-25-2010 08:23 PM

Re: pointer to pointer
 
On Dec 21, 8:05*pm, Ian Collins <ian-n...@hotmail.com> wrote:
> On 12/22/10 04:43 PM, arnuld wrote:
>
> > Its just a very simple and basic program to learn exactly what is
> > described in comments here. Can you provide a better (and short)
> > exercise ?

>
> Parse the arguments to a program. *Don't forget argv is a pointer to
> pointer!
>
> Given ./a.out -a 10 -b 20
>
> print out the values of a and b.
>


I don't get the point of this exercise. Maybe I'm missing "it'.
Anyways, here is what I came up with..

#include <stdio.h>

int main(int argc, char **argv)
{
int i;
char dash, letter;

for (i = 1; i < argc; i++) {
dash = argv[i][0];
letter = argv[i][1];

if (dash == '-' && letter == 'a') {
printf("a = %s\n", argv[++i]);
}
if (dash == '-' && letter == 'b') {
printf("b = %s\n", argv[++i]);
}
}

return 0;
}

[cdalten@localhost oakland]$ gcc -Wall -Wextra -ansi -pedantic
parseab.c -o parseab
[cdalten@localhost oakland]$ ./parseab -a 10 -b 20
a = 10
b = 20
[cdalten@localhost oakland]$ ./parseab -a 10
a = 10
[cdalten@localhost oakland]$ ./parseab -b 40
b = 40
[cdalten@localhost oakland]$ ./parseab
[cdalten@localhost oakland]$ ./parseab b 40
[cdalten@localhost oakland]$ ./parseab a 40
[cdalten@localhost oakland]$ ./parseab a 40 b 40
[cdalten@localhost oakland]$ ./parseab -b 40 -a 100
b = 40
a = 100
[cdalten@localhost oakland]$



Chad 12-25-2010 09:57 PM

Re: pointer to pointer
 
On Dec 25, 12:23*pm, Chad <cdal...@gmail.com> wrote:
> On Dec 21, 8:05*pm, Ian Collins <ian-n...@hotmail.com> wrote:
>
> > On 12/22/10 04:43 PM, arnuld wrote:

>
> > > Its just a very simple and basic program to learn exactly what is
> > > described in comments here. Can you provide a better (and short)
> > > exercise ?

>
> > Parse the arguments to a program. *Don't forget argv is a pointer to
> > pointer!

>
> > Given ./a.out -a 10 -b 20

>
> > print out the values of a and b.

>
> I don't get the point of this exercise. Maybe I'm missing "it'.
> Anyways, here is what I came up with..
>


And here is my attempt at the pointer solution. It's kind of ugly, but
it appears to work correctly...

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
char *letter ="";
char *number ="";

while (--argc > 0) {
letter = *++argv;
number = *++argv;

if (letter != NULL && (strcmp(letter, "-a")) == 0 ) {
if(number != NULL && (strcmp(number, "-b")) == 0 ) {
number = *++argv;
if (number != NULL) {
printf("No number provided for a\n");
printf("b = %s\n", number);
exit(EXIT_SUCCESS);
} else {
printf("No number provided for a and b\n");
exit(EXIT_FAILURE);
}
}
printf("a = %s\n", number ? number : "No number provided for a
\n");
}
if (letter != NULL && (strcmp(letter, "-b")) == 0 ) {
if(number != NULL && (strcmp(number, "-a")) == 0 ) {
printf("No number provided for b and a\n");
exit(EXIT_FAILURE);
}
printf("b = %s\n", number ? number : "No number provided for b
\n");
}
}

exit(EXIT_SUCCESS);
}
[cdalten@localhost oakland]$ gcc -g -Wall -Wextra -ansi -pedantic
parseab2.c -o parseab2
[cdalten@localhost oakland]$ ./parseab2
[cdalten@localhost oakland]$ ./parseab2 -a
a = No number provided for a

[cdalten@localhost oakland]$ ./parseab2 -a -b
No number provided for a and b
[cdalten@localhost oakland]$ ./parseab2 -a -b 10
No number provided for a
b = 10
[cdalten@localhost oakland]$ ./parseab2 -a 10 -b
a = 10
b = No number provided for b

[cdalten@localhost oakland]$ ./parseab2 -a 10 -b 20
a = 10
b = 20
[cdalten@localhost oakland]$ ./parseab2 -b 10 -a
b = 10
a = No number provided for a

[cdalten@localhost oakland]$ ./parseab2 -b 10 -a 50 20
b = 10
a = 50
[cdalten@localhost oakland]$

Ike Naar 12-26-2010 12:44 PM

Re: pointer to pointer
 
On 2010-12-25, Chad <cdalten@gmail.com> wrote:
> #include <stdio.h>
> #include <string.h>
> #include <stdlib.h>
>
> int main(int argc, char **argv)
> {
> char *letter ="";
> char *number ="";
>
> while (--argc > 0) {
> letter = *++argv;
> number = *++argv;


You iterate argc-1 times through this loop, and in each iteration
argv is advanced at least two times. That means that for certain
argument lists you're accessing non-existing elements of argv.

Let's take, for example, the argument list ``the quick brown fox''.
argc=5, argv[0]=progname, argv[1]="the", argv[2]="quick",
argv[3]="brown", argv[4]="fox", argv[5]=NULL.

In the first iteration, you handle argv[1] ("the") and argv[2] ("quick").
In the second iteration, you handle argv[3] ("brown") and argv[4] ("fox").
In the third iteration, you handle argv[5] (NULL) and argv[6] (and
here the program goes off the rails).

arnuld 12-27-2010 11:20 AM

Re: pointer to pointer
 
> On Dec 26, 1:23*am, Chad <cdal...@gmail.com> wrote:


> I don't get the point of this exercise. Maybe I'm missing "it'.
> Anyways, here is what I came up with..
>
> #include <stdio.h>
>
> int main(int argc, char **argv)
> {
> * int i;
> * char dash, letter;
>
> * for (i = 1; i < argc; i++) {
> * * dash = argv[i][0];
> * * letter = argv[i][1];
>
> * * if (dash *== '-' && letter == 'a') {
> * * * printf("a = %s\n", argv[++i]);
> * * }
> * * if (dash *== '-' && letter == 'b') {
> * * * printf("b = %s\n", argv[++i]);
> * * }
> * }
>
> * return 0;
>
> }


> ...SNIP....



I think "Ian Collins" meant uknown number of arguments (rather than
two). Still even if he meant two arguments -a and -b, still your
program confuses a bit because at first it iterates for --argc times
but then at same time it it handles only two variables (which may or
may not not equal to --argc). I think if you want to deal with only 2
argiments then (i < 3) must be the conditional check.

Nice cleaner code with array indexing though :)


All times are GMT. The time now is 02:21 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.