Working with arrays of pointers and pointers of pointers

  • (2 Pages)
  • +
  • 1
  • 2

25 Replies - 1136 Views - Last Post: 21 March 2011 - 01:42 PM Rate Topic: -----

#1 DemonTaoist  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 21
  • Joined: 14-March 11

Working with arrays of pointers and pointers of pointers

Posted 19 March 2011 - 11:51 AM

This is my first attempt. I think my logic on the function is sound (if not, please tell me otherwise), but I'm just not familiar with the intricacies of pointers for declaring, passing, referencing, dereffing, etc, etc....

Except for the declaration of minS, maxS, the main function appears exactly as required for the assignment.


Any help appreciated!


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

void first_last( char *s[], int n, char **first, char **last ){ //find first and last word alphabetically
**first = 123; // z + 1, assuring first comparison will always result in assignment of new value
**last = 96; // a - 1
for( n = 0; n < 8; n++){
   if (*s[n] > **last) // and if first char is great than
        *s[n] = **last;}
    if (*s[n] < **first) // if first char of string is less than char first points to,
        *s[n] = **first;



return;}


int main ( ) {
char *array [ ] = { "hello" , "world " , "today" , "is" , " a " , "very" , "nice", "day" } ;


int size = 8 ;
char **minS;
char **maxS;

first_last( array , size , &minS, &maxS ) ;

printf ( "The first word is %s and the last is %s \n " , minS , maxS ) ;
return(0);
}



Is This A Good Question/Topic? 0
  • +

Replies To: Working with arrays of pointers and pointers of pointers

#2 JackOfAllTrades  Icon User is offline

  • Saucy!
  • member icon

Reputation: 6111
  • View blog
  • Posts: 23,672
  • Joined: 23-August 08

Re: Working with arrays of pointers and pointers of pointers

Posted 19 March 2011 - 12:40 PM

Your warnings:
pp.c: In function ‘main’:
pp.c:26: warning: passing argument 3 of ‘first_last’ from incompatible pointer type
pp.c:26: warning: passing argument 4 of ‘first_last’ from incompatible pointer type
pp.c:28: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘char **’
pp.c:28: warning: format ‘%s’ expects type ‘char *’, but argument 3 has type ‘char **’



You are using pointers without providing any memory for them to point to; instant seg fault.

minS and maxS should NOT be declared as char **. They are character strings, and you will pass the address of these pointers (which need to to have memory allocated to them) to your function.

That's a few pointers in the right direction.

EDIT: Oops, I was wrong there; you're looking to return pointers to the element in the passed-in array. My bad.

Your function code is...wrong. You are modifying the passed-in array, not changing the passed in pointers for starters.

Write down for us what you think the algorithm for this operation should be.

This post has been edited by JackOfAllTrades: 19 March 2011 - 12:50 PM

Was This Post Helpful? 1
  • +
  • -

#3 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5943
  • View blog
  • Posts: 12,871
  • Joined: 16-October 07

Re: Working with arrays of pointers and pointers of pointers

Posted 19 March 2011 - 03:51 PM

// assuming this is the prototype you want
void first_last( char *s[], int n, char **first, char **last ){
	// do your pointers actually reference storage?  no
	// are you comparing chars? no
	// **first = 123;
	// **last = 96; // a - 1
	// you've passed the size as n
	// where does the magic 8 come from?
	// perhaps you want:
	int i;
	for(i = 0; i < n; i++){
		// this is simply wrong,
		// lookup strcmp
		if (*s[n] > **last) // and if first char is great than
//...

// wrong
// you want pointers, not pointer pointers
// char **minS;
// char **maxS;
char *minS, *maxS;

first_last( array , size , &minS, &maxS ) ;




Probably shouldn't give this away, but your first three lines should probably be:
void first_last( char *s[], int n, char **first, char **last ){
	int i;
	
	*first = *last = s[0];
	for(i = 1; i < n; i++){


Was This Post Helpful? 1
  • +
  • -

#4 DemonTaoist  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 21
  • Joined: 14-March 11

Re: Working with arrays of pointers and pointers of pointers

Posted 19 March 2011 - 09:56 PM

Quote

void first_last( char *s[], int n, char **first, char **last ){
	int i;
	
	*first = *last = s[0];
	for(i = 1; i < n; i++){



Thanks for the comments. I thought if I declared pointers that pointed to nothing in particular, they would point to a random address until directed elsewhere.

I don't understand a lot of what's going on with this assignment. Clearly. I had some thing switched around, and I would never have thought after passing **first, **last to change them *first *last, but that sort of makes sense.

I don't get how, in invoking the function, passing the addresses of minS and maxS turns into pointers to pointers. I thought I would have to declare them as pointers to pointers since they are (I thought, supposed to) point to characters in an array of pointers.

Um... here's another try? So confused...

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

void first_last( char *s[], int n, char **first, char **last ){ //find first and last word alphabetically

int z;

*first = *last = s[0]; // point both to first character of first string

for( z = 0; z < n ; z++){
   if (*s[z + 1] > *first)//z+1 since both are initially pointing to same value
        *first = *s[z+1];
    if (*s[z+1] < *last)
        *last = *s[z+1];}



return;}


int main ( ) {
char *array [ ] = { "hello" , "world " , "today" , "is" , " a " , "very" , "nice", "day" } ;


int size = 8 ;
char *minS;
char *maxS;

first_last( array , size , &minS, &maxS ) ;

printf ( "The first word is %s and the last is %s \n " , minS , maxS ) ;
return(0);
}


Was This Post Helpful? 0
  • +
  • -

#5 r.stiltskin  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1833
  • View blog
  • Posts: 4,927
  • Joined: 27-December 05

Re: Working with arrays of pointers and pointers of pointers

Posted 19 March 2011 - 10:51 PM

Yes it is confusing.

Since first is a char**, it is the address of a char*. So *first is the value of the char*, i.e., *first is the address of the first character, and **first is the value of the first character.

Similarly, s[z] is a char* (address of a char), and s[z][0] is the value of the first character of each word.

You don't want to use z+1 in the loop because if z goes to n-1, z+1 goes beyond the end of the array, so instead initialize z to 1.

Here, I cleaned it up for you & it "works" -- but only because every word begins with a different letter. Your function only compares the first letters of the words. You can't compare entire strings using > < and ==. To do that, use the strcmp function.

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

void first_last( char *s[], int n, char **first, char **last ) { //find first and last word alphabetically

    int z;

    *first = *last = s[0]; // point both to first character of first string
    for ( z = 1; z < n ; z++) { // start at the second string in the array
		printf("%s\n", s[z]);
        if (s[z][0] < **first)// comparing value of first letter of each string
            *first = s[z]; // assign address of first letter
        if (s[z][0] > **last)
            *last = s[z];
    }



    return;
}


int main ( ) {
    char *array [ ] = { "hello" , "world " , "today" , "is" , " a " , "very" , "nice", "day" } ;


    int size = 8 ;
    char *minS;
    char *maxS;

    first_last( array , size , &minS, &maxS ) ;

    printf ( "The first word is %s and the last is %s \n " , minS , maxS ) ;
    return(0);
}



Was This Post Helpful? 1
  • +
  • -

#6 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5943
  • View blog
  • Posts: 12,871
  • Joined: 16-October 07

Re: Working with arrays of pointers and pointers of pointers

Posted 20 March 2011 - 03:46 AM

View PostDemonTaoist, on 19 March 2011 - 11:56 PM, said:

I thought if I declared pointers that pointed to nothing in particular, they would point to a random address until directed elsewhere.


Yes, that is correct. The problem is, if you try to use those pointers to store data, like **first='A', then you've sent data where it has no where to go.

Pointer pointers are absolutely confusing. However, there's no rule that says you have to keep them that way in you code. Declare saner values and work from there.



// this only a test
void first_last( char *s[], int n, char **first, char **last ){
	int z;
	
	*first = *last = s[0]; // point both to first character of first string

	// note, start with one, we've already seeded with s[0] above
	// that z + 1 thing is going to blow you up
	for( z = 1; z < n ; z++) {
		// let's stop here and consider what you're looking at
		// if (*s[z] > *first)
		
		// *first points to an array of characters
		// test it:
		printf("*first = %s\n", *first);
		
		// *s[z] points to... what?
		// it actually points to a character
		printf("*s[z] = %c\n", *s[z]);



Confused? Let's make is easier to see. Just because you're dealing with pointer pointers, doesn't mean you always have to look at them that way:
void first_last( char *s[], int n, char **first, char **last ){
	int z;
	*first = *last = s[0];
	for( z = 1; z < n ; z++) {
		char *word1, *word2; // define simply pointers to strings of characters
		
		word1 = s[z];
		word2 = *first;
		
		printf("word1 = %s\nword2 = %s\n", word1, word2);



That's a little easier to follow, I think. The problem is, if (word2 < word1) does not compare strings, it compares pointer addresses. Saying if (*word2 < *word1) also doesn't compare strings, it compares the first character in each string. Once again, this is why I mentioned the strcmp function. This compares strings: if (strcmp(word2,word1)<0)

You now have all the elements spelled out. You just need to put them together. Good luck.

This post has been edited by baavgai: 20 March 2011 - 03:51 AM

Was This Post Helpful? 1
  • +
  • -

#7 Bench  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 857
  • View blog
  • Posts: 2,343
  • Joined: 20-August 07

Re: Working with arrays of pointers and pointers of pointers

Posted 20 March 2011 - 04:02 AM

View PostDemonTaoist, on 20 March 2011 - 04:56 AM, said:

Thanks for the comments. I thought if I declared pointers that pointed to nothing in particular, they would point to a random address until directed elsewhere.

Yes, their stored value will be whatever was left over in memory from the last time it was used. which is exactly the same thing which happens when you declare any other kind of variable like an int, a double or a char.


There is absolutely no difference whatsoever between the way "pointer variables" and other types of variables work; the only difference is the way that the C++ language lets you use their stored data.

e.g. Telling C++ that a variable is an int means that you can only use that data as if it were an integer (you can only do integer operations on it). Similarly, telling C++ that a variable is double means that you can only do operations on it which make sense for double-precision floating-point data.
Finally, if you tell C++ that a variable is a pointer, then C++ will only let you do things which make sense in a pointer context.


Just to illustrate - some things you can do with different "kinds of" data (data types)
  • int - store integral data, Integer arithmetic, conversion to floating-point, array index representation
  • double - store floating point data, Floating point arithmetic
  • pointer - store address data, "de-reference" (i.e. indirection to a memory location).

(Remember that the * is a part of the data type in a declaration - i.e. it tells the compiler that the "kind of" data stored by the memory block with the given identifier/name/variable is "pointer data" or "address data")


However, if you bypassed C++'s type system, there's nothing which absolutely prohibits you from doing things with data types which C++ wouldn't normally let you. E.g. you can use casting in order to "de-reference" an int or a double (Note that doing something like this is a very very bad idea)

However, if you wanted to know what the byte of data at memory location 1234 looked like, there's nothing stopping you doing it by "abusing" the language:
int n = 1234;
int m = *(char*)n;
printf("%d", m); 



To summarise - "data types" are just in interface which C++ pulls over your eyes to give you nice abstractions and ways of working, but under the hood, data is always just data. "data types" are something which your compiler imposes on you to make your life easier.
Was This Post Helpful? 1
  • +
  • -

#8 DemonTaoist  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 21
  • Joined: 14-March 11

Re: Working with arrays of pointers and pointers of pointers

Posted 20 March 2011 - 04:12 PM

So... testing values with print is definitely something I need to do much more often. This code apparently works how it's supposed to (comparing single characters is what I wanted). Seeing (and understanding, more or less) the end result, I can see why I was so confused. I think finally watching Inception last night definitely helped.

Thanks a bunch for all your help!


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

void first_last( char *s[], int n, char **first, char **last ){ //find first and last word alphabetically

int z;

*first = *last = s[0]; // point both to first character of first string

for( z = 1; z < n ; z++){
   if (*s[z] < **first) //compares first character of string to character **ptr's point to.
        *first = s[z];
    if (*s[z] > **last)
        *last = s[z];}



return;}


int main ( ) {
char *array [ ] = { "hello" , "world " , "today" , "is" , " a " , "very" , "nice", "day" } ;


int size = 8 ;
char *minS;
char *maxS;

first_last( array , size , &minS, &maxS ) ;

printf ( "The first word is %s and the last is %s \n " , minS , maxS ) ;
return(0);
}



Was This Post Helpful? 0
  • +
  • -

#9 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5943
  • View blog
  • Posts: 12,871
  • Joined: 16-October 07

Re: Working with arrays of pointers and pointers of pointers

Posted 20 March 2011 - 04:32 PM

View PostDemonTaoist, on 20 March 2011 - 06:12 PM, said:

comparing single characters is what I wanted


Really? Well then, glad you found your answer. That return is redundant, btw.

For a real string compare, it would look like this:
void first_last( char *s[], int n, char **first, char **last ){
	int i;
	*first = *last = s[0];
	for(i=1; i<n; i++) {
		if (strcmp(s[i],*first)<0) { *first = s[i]; }
		if (strcmp(s[i],*last)>0) { *last = s[i]; }
	}
}


Was This Post Helpful? 2
  • +
  • -

#10 DemonTaoist  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 21
  • Joined: 14-March 11

Re: Working with arrays of pointers and pointers of pointers

Posted 20 March 2011 - 06:45 PM

View Postbaavgai, on 20 March 2011 - 04:32 PM, said:

View PostDemonTaoist, on 20 March 2011 - 06:12 PM, said:

comparing single characters is what I wanted


Really? Well then, glad you found your answer. That return is redundant, btw.

For a real string compare, it would look like this:
void first_last( char *s[], int n, char **first, char **last ){
	int i;
	*first = *last = s[0];
	for(i=1; i<n; i++) {
		if (strcmp(s[i],*first)<0) { *first = s[i]; }
		if (strcmp(s[i],*last)>0) { *last = s[i]; }
	}
}



All we know about strcmp is that it's peculiar for returning 0 when strings are equal. I just realized yesterday (after reviewing the syllabus) that we are technically not allowed to seek help from any sources (not from friends, classmates, internet). We can only use powerpoints slides and the text. Which, based on our assignments so far, means we're basically supposed to invent C for ourselves.

That said, I'm sure we are totally expected to use strcmp.

Anyway, ignoring the silly course requirements, I'm stuck on another pointers problem.
This is for a remove character function. The trick with this is it has to print from the main function. Right now I'm just trying to get the trimmed string to print inside the function

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

 void removeCharacter(char s[50], char c, char tr[50], int num){


int x;

for(x=0; s[x] != '\0'; x++){
    if (s[x] != c && s[x] + 32 != c && s[x] - 32 != c){
    tr[x-num]= s[x];}
    else
    num++;
    }
tr[x-num] = '\0'; // (x+1)-num?

printf("%s", tr);

return;}


    int main(){


    char word[50];
    char h;
    char trim[50];
    int numb;
   // char *ptr = &trim;



{
    char word[50] = ("MisSiSsippi");
    h = 's';
    removeCharacter(word, h, trim, numb);
   /* printf("%s", *ptr);*/
}

return(0);
    }




Was This Post Helpful? 0
  • +
  • -

#11 r.stiltskin  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1833
  • View blog
  • Posts: 4,927
  • Joined: 27-December 05

Re: Working with arrays of pointers and pointers of pointers

Posted 20 March 2011 - 07:01 PM

I don't understand what your numb or num is supposed to represent. Aren't you simply trying to copy to tr every char in s that doesn't match c, ignoring case?

So ask yourself, how can you navigate through tr, beginning at index 0, without skipping any elements? (And why would you need any number sent from main to accomplish that?)
Was This Post Helpful? 0
  • +
  • -

#12 r.stiltskin  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1833
  • View blog
  • Posts: 4,927
  • Joined: 27-December 05

Re: Working with arrays of pointers and pointers of pointers

Posted 20 March 2011 - 07:07 PM

Oh, and by the way, you don't have to invent C yourself. You can find a wealth of information in the C library reference pages at cplusplus.com.

And here are couple of other sources:
C Tutorial
C Programming Notes

And I'm sure if you search a bit you'll find others.
Was This Post Helpful? 0
  • +
  • -

#13 DemonTaoist  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 21
  • Joined: 14-March 11

Re: Working with arrays of pointers and pointers of pointers

Posted 20 March 2011 - 07:24 PM

View Postr.stiltskin, on 20 March 2011 - 07:01 PM, said:

I don't understand what your numb or num is supposed to represent. Aren't you simply trying to copy to tr every char in s that doesn't match c, ignoring case?


num represents the number of occurrences of the character I want to remove. numb represents an integer that was required to be passed by the assignment.

Quote

So ask yourself, how can you navigate through tr, beginning at index 0, without skipping any elements? (And why would you need any number sent from main to accomplish that?)


Maybe an address so I can dereference it in the main? Or something? I don't know.

Quote

Homeworks Policy
All Homeworks and exams must be done individually. You may not consult with other classmates about the assignments.
You may not use any source besides the book and the class material to do your homeworks. That includes the web. Pieces of code copied from the web or other classmates will automatically turn your whole homework grade to zero and you may be reported to the dean for academic dishonesty (see following section).


I think I should report this, the book, the 'class material" and the homework sets to whoever's in charge of the undergrad CS curriculum....
Was This Post Helpful? 0
  • +
  • -

#14 r.stiltskin  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1833
  • View blog
  • Posts: 4,927
  • Joined: 27-December 05

Re: Working with arrays of pointers and pointers of pointers

Posted 20 March 2011 - 07:33 PM

View PostDemonTaoist, on 20 March 2011 - 09:19 PM, said:

num represents the number of occurrences of the character I want to remove. numb represents an integer that was required to be passed by the assignment.

Oh, OK. It's kind of ambiguous though. So if you pass, say, 'c' 2, then the function is supposed to delete the first 2 occurrences of 'c' or 'C' from the source string?

If so, that's a bit tricky. Then I guess you have to figure out how to use that variable num in a conditional statement to determine when to stop deleting. You'll have to figure that one out -- it's not really a C language question but rather a logical thinking question.

The other issue -- navigating through the destination string -- involves creating another index variable dedicated to that string. You can't use the same index (x) that you're using for the source string, since the destination will contain fewer elements, right?

I don't disagree with the policy as regards copying code from the web or elsewhere. But I think that limiting sources to "the book and the class material" is profoundly stupid. Other books are taboo?

This post has been edited by r.stiltskin: 20 March 2011 - 07:40 PM

Was This Post Helpful? 0
  • +
  • -

#15 DemonTaoist  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 21
  • Joined: 14-March 11

Re: Working with arrays of pointers and pointers of pointers

Posted 20 March 2011 - 08:16 PM

View Postr.stiltskin, on 20 March 2011 - 07:33 PM, said:

Oh, OK. It's kind of ambiguous though. So if you pass, say, 'c' 2, then the function is supposed to delete the first 2 occurrences of 'c' or 'C' from the source string?


No, it's simpler. forgive me mods

Quote

Pointers. Write a function named removeCharacter() that
4.1. Takes 4 inputs: an integer num, a string tr, a string s and a character c, but does not return anything.
4.2. Finds the number of all the occurrences of c in s (both capital and lower case) and saves it in num
4.3. Copies the trimmed string in tr
4.4. Write in the same file a main() function containing a series of tests to showcase the correct behavior of removeCharacter(). Note: you can print only from the main function


This is a repeat of another assignment we had, except this time we have to use pointers to make it print from the main function.

Quote

The other issue -- navigating through the destination string -- involves creating another index variable dedicated to that string. You can't use the same index (x) that you're using for the source string, since the destination will contain fewer elements, right?


won't the destination index always equal the current index minus the number of occurrences? Hence the x-num. I thought that was the point of counting the occurrences.

Quote

I don't disagree with the policy as regards copying code from the web or elsewhere. But I think that limiting sources to "the book and the class material" is profoundly stupid. Other books are taboo?

Especially considering how basic the book and powerpoint slides are. We aren't even supposed to consult each other? Really? Anyway the prof knows we talk to each other and I told him I had to go to the web to figure out nested for loops for another assignment. He was a jerk about it (I didn't think hard enough to just figure out nested loops out of the thin air), but I didn't get a zero or reported lol.
Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2