![]() |
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 |
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 |
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] |
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 |
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]$ |
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]$ |
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). |
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 11:44 AM. |
Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.