Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

Please explain the relationship between pointers and arrays. In this tutorial, they change int c by changing *r in the function. How is that possible?

Also, please review my code for reversing a string. The string variable belongs to the main() function, and I would like to pass a pointer to let the strreverse() function write to the string. Does my code work?

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

void strreverse(char *string)
{
 int i, len;
 char c;
 len=strlen(string);
 char string2[len+1];

 for(i=0; i<len; i++)
 {
  c=string[i];
  string2[len-i]=c;

 }
 string2[len+1]='\0';
 string=string2;
 //printf("%s\n", string); <-- this would work,but should be in main

}

int main(int argc, char *argv[])
{
  char str[256];
  printf("Type a String to reverse it.[max. 255 chars]\n");
  fgets(str, 255, stdin);
  strreverse(&str[0]);
  printf("%s", str);
  return EXIT_SUCCESS;
}
share|improve this question
    
You should be aware that your code requires C99, but that's fine for now. –  busy_wait Sep 10 '13 at 14:38
    
That was recommended in my books. Thanks for making my request readable! –  rrrrn Sep 10 '13 at 18:47
    
I never really understand the point of adding command line arguments when it is not used in the program. –  Olayinka Sep 10 '13 at 22:39
    
I don't think this question should have been put on hold. This site is for code reviews, and there are plenty of issues in this code for critique. (It fails the "you must post working code criterion", but a beginner who has made a good effort doesn't deserve to be turned away, I think.) –  200_success Sep 11 '13 at 22:36

1 Answer 1

up vote 2 down vote accepted

No, I've compiled your code with C90 and it doesn't reverse the given string.

  • int main(int argc, char *argv[]) If you're not compiling from the command line with arguments to be used by the program, then int main() suffices.
  • Passing argument by pointer is used when you want the value of the variable changed. Say I have a variable int var and a function change(.), I want change to alter the value of var. If I declare change as void change(int n) and I call change(var), function change will take a copy of var named var but it's only a copy, its address is different from the original var. Any change you make on copy var will not affect the original var. If i declare change as void change(int* n), then change will only accept int pointers, I have to pass the address, &var into change as change(&var). Now working on this address is exactly like working on the initial var.

To understand pointer-array relationship read wikipedia.

int array[5];      // Declares 5 contiguous integers 
int *ptr = array;  // Arrays can be used as pointers 
ptr[0] = 1;        // Pointers can be indexed with array syntax 
*(array + 1) = 2;  // Arrays can be dereferenced with pointer syntax 
*(1 + array) = 3;  // Pointer addition is commutative 
2[array] = 4;      // Subscript operator is commutative 

Array names can are not really pointers but can be used as pointers. Instead of strreverse(&str[0]), you can do strreverse(str). Same result.

You've passed argument as pointer but your code still fails, why?

  • One thing to know about fgets is that unless there is an [EOF][2] which you can only get from an input file or Ctrl+Z if you run from the command line, fgets exits when the length argument is reached or it encounters a newline. In summary, fgets reads the newline as a character when you press enter key, increasing your desired length by 1. So if I had entered "my string" + Enter, your variable str becomes "my string\n".
  • So you got the length of the string into len. The array string is zero-based, calling string[len] return the char after the desired last one. The last char is string[len - 1].

You should have done this;

char string2[len];

for(i=0; i<len; i++){
  c=string[i];      //variable c is unimportant
  string2[len-i-1] = string[i];  //observe the -1, when i = 0, string2[len - 1] = string[0]
}
string2[len] ='\0';

Now that you're done reversing, you need to understand the implication of your next move.

string = string2;

string is a pointer, but that doesn't make it any less of a variable, it's a pointer variable, it also has an address. And if I declare a pointer variable to its address, that pointer will also have an address. Going back to what I said earlier, when you call change(&var), a copy of the address of var is passed into the function, so when you change the value of this pointer, it no longer holds the address of var. You may think about dereferencing, like this

*string = *string2;

but this will only alter the first value of the array since *string is same as string[0]. The solution is to copy element by element.

for(i=0; i<=len; i++)
  string[i] = string2[i];

Now your string is reversed.

Read this wikipedia article to understand how an array can be reversed faster.

share|improve this answer
    
+1 thank you for this. I'm awful at pointers, even though I don't have to worry too much about the raw ones in C++. It never hurts to learn the fundamentals of C, either. :-) Your changes do work, by the way. –  Jamal Sep 11 '13 at 1:35
    
@Jamal I agree, pointers can be a pain in the ass but they force one to code carefully. –  Olayinka Sep 11 '13 at 1:46
    
Right. Still, for serious C++ applications, I'll just (learn) and stick with STL pointers. I believe one of my few SO questions shows my earliest attempt at using double pointers. –  Jamal Sep 11 '13 at 1:50
    
Thanks a lot, for a clear and encouraging answer. –  rrrrn Sep 11 '13 at 7:26

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.