2

I am a beginner studying C++. Currently I am studying functions, C strings, and pass by reference.

The program below is meant to take a string from input, replace any spaces with hyphens, and any exclamation marks with question marks.

If the function below, StrSpaceToHyphen() is of return type void, wouldn't the function parameter need to be pass by reference in order for userStr in main() to be modified?

The program copied below works as intended. My question is meant to further my understanding of modifying c strings as I was expecting it to behave differently.

#include <iostream>
#include <cstring>
using namespace std;

// Function replaces spaces with hyphens
void StrSpaceToHyphen(char modString[]) {
   int i;      // Loop index
   
   for (i = 0; i < strlen(modString); ++i) {
      if (modString[i] == ' ') {
         modString[i] = '-';
      }
      if (modString[i] == '!') {
         modString[i] = '?';
      }
   }
}

int main() {
   const int INPUT_STR_SIZE = 50;  // Input C string size
   char userStr[INPUT_STR_SIZE];   // Input C string from user
   
   // Prompt user for input
   cout << "Enter string with spaces: " << endl;
   cin.getline(userStr, INPUT_STR_SIZE);
   
   // Call function to modify user defined C string
   StrSpaceToHyphen(userStr);
   
   cout << "String with hyphens: " << userStr << endl;
   
   return 0;
}

type here

I made the function parameter pass by reference and the program wouldn't compile.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
sam5855
  • 33
  • 4
  • 1
    Believe it or not, you *are* passing the parameter by reference because it's using a pointer. – Mark Ransom Nov 06 '22 at 16:23
  • `void StrSpaceToHyphen(char modString[])` is the exact same as `void StrSpaceToHyphen(char* modString)` - so your function already receives as pointer as argument – UnholySheep Nov 06 '22 at 16:23
  • 1
    uff. You're a beginner. In which context would you encounter C strings that get passed by reference? That's simply something that's pretty rare, and I'd argue, even something you'd avoid in C++ very much: the C string is not a ... easy structure to deal with safely, and `std::string` in C++ is very easy to deal with, soooo – Marcus Müller Nov 06 '22 at 16:23
  • 1
    See [here](https://stackoverflow.com/questions/1461432/what-is-array-to-pointer-decay) for more about array-to-pointer decay, which is what's occurring when you pass an argument to `StrSpaceToHyphen`. – Nathan Pierson Nov 06 '22 at 16:23
  • @MarcusMüller if you ever programmed in C, a pointer was the *only* way to pass by reference. So it's not uncommon to refer to it that way even in C++. – Mark Ransom Nov 06 '22 at 16:25
  • @MarkRansom but you're passing a pointer by value, not an object by reference, with all the lifetime consequences that has. C++ is not C, after all. – Marcus Müller Nov 06 '22 at 16:26
  • @MarkRansom Thank you Mark. Your comments helped everything make a little more sense to me! – sam5855 Nov 06 '22 at 16:36

1 Answers1

2

This declaration of the parameter

void StrSpaceToHyphen(char & modString[]) {

declares an array of references. You may not declare arrays of references.

As for your initial declaration

void StrSpaceToHyphen(char modString[]) {

then the compiler adjusts the parameter having the array type to pointer to the array element type like

void StrSpaceToHyphen(char *modString) {

As the address of the array is not changed within the function then there is no sense to declare the parameter as a reference to pointer like

void StrSpaceToHyphen(char * &modString) {

Having the pointer to the first element of the array and the pointer arithmetic you can change any element of the original array.

Pay attention to that the variable i and the call of strlen are redundant.

You could define the function the following way

char * StrSpaceToHyphen( char modString[] ) 
{
    for ( char *p = modString; *p; ++p ) 
    {
        if ( *p == ' ' ) 
        {
            *p = '-';
        }
        else if ( *p == '!' ) 
        {
            *p = '?';
        }
    }

    return modString;
}
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335