Home > database >  How can I modify values of an array passed to a function?
How can I modify values of an array passed to a function?

Time:07-26

I'm a C beginner and I'm stuck on my course assignment because I can't wrap my head around how to modify values of an array passed to a function. Honestly, we haven't reached the topic about arrays yet in class, but I recall some basic functionalities related to them and I wanted to solve the exercise using arrays because it's surely a smarter way to do it then the easy version of the assignment without them (that I've already solved). I've looked online for some references but clearly I'm missing something important.

The assignment states:

In this exercise you’ll investigate a simple scheme for encrypting and decrypting data. A company that wants to send data over the Internet has asked you to write a program that will encrypt the data so that it may be transmitted more securely. All the data is transmitted as four-digit integers. Your application should read a four-digit integer entered by the user and encrypt it as follows:

  • Replace each digit with the result of adding 7 to the digit and getting the remainder after dividing the new value by 10.
  • Then swap the first digit with the third, and swap the second digit with the fourth.
  • Then print the encrypted integer.

And my attempt is this:

main.cpp

#include "encrypt.h"
#include <iostream>

const size_t size{4};


int main () {
    int arrEncrypt[size] = {1, 2, 3, 4};

    swap(arrEncrypt[size]);
    encrypt(arrEncrypt[size]);
    printArr(arrEncrypt[size]);
}

encrypt.h

#ifndef ENCRYPT_H
#define ENCRYPT_H


void encrypt(int a[]);
void swap(int a[]);
void printArr(int a[]);


#endif

encrypt.cpp

#include <iostream>
#include "encrypt.h"

const size_t num{4};


// Replace each digit with the result of adding 7 to the digit and getting the remainder after dividing the new value by 10. 
void encrypt(int arr[::num]) {

    for (int k = 0; k < ::num; k  ) {
        arr[k] = (arr[k]   7) % 10;
    }

}

// Then swap the first digit with the third, and swap the second digit with the fourth.
void swap(int arr[::num]) {

    int box[1] = {0};
    for (int k = 0; k < (::num / 2); k  ) {
        box[1] = arr[k];
        arr[k] = arr[k 2];     
        arr[k 2] = box[1];  
    }

    box[1] = arr[0];
    arr[0] = arr[2];
    arr[2] = box[1];

    box[1] = arr[1];
    arr[1] = arr[3];
    arr[3] = box[1]; 

}

// Then print the encrypted integer. 
void printArr(int arr[::num]) {
    
    for (int k = 0; k < ::num; k  ) {
        std::cout << arr[k] << " ";
    }

}

The swap function has some problems in the algorithm probably because I tried printing the for loop output and I get just one random value, while the bit manually written is working fine. I don't know why.

This program clearly doesn't work because every time I pass the array to a function it is always the one declared in main and not an array modified by the functions. I tried pointing to the array passed to the functions but I think I messed it up because I got a bunch of errors - moreover, I've read that taking the address of a built-in array to pass it to a function is not needed and I can simply pass the built-in array’s name because the called function can modify all the elements of an array in the caller, unless the function precedes the corresponding built-in array parameter with const to indicate that the elements should not be modified. But I don't get why in my program it doesn't work.

Thanks in advance for anyone who would take their time to help me out, I really appreciate it.

CodePudding user response:

An array can't be passed to a function by value, only by reference or pointer. In your case, a parameter like int a[] is really just syntax sugar for a pointer int *a. But you are not actually calling the functions with a pointer, you are indexing into arrEncrypt and passing an individual int instead (using an index that is out of range!).

Get rid of the array indexing at the call sites. An array decays into a pointer to its 1st element when it is referred to by just its name.

Also, such parameters don't carry size information, so you have to pass the array size explicitly in a separate parameter.

Try this instead:

#include "encrypt.h"

const size_t size{4};

int main () {
    int arrEncrypt[size] = {1, 2, 3, 4};

    swap(arrEncrypt, size);
    encrypt(arrEncrypt, size);
    printArr(arrEncrypt, size);
}

encrypt.h

#ifndef ENCRYPT_H
#define ENCRYPT_H

void encrypt(int a[], int size);
void swap(int a[], int size);
void printArr(int a[], int size);

#endif

encrypt.cpp

#include <iostream>
#include <stdexcept>
#include "encrypt.h"

// Replace each digit with the result of adding 7 to the digit and getting the remainder after dividing the new value by 10. 
void encrypt(int arr[], int size) {
    if (!arr || size < 0) throw invalid_argument("");
    for (int k = 0; k < size; k  ) {
        arr[k] = (arr[k]   7) % 10;
    }
}

// Then swap the first digit with the third, and swap the second digit with the fourth.
void swap(int arr[], int size) {
    if (!arr || size < 4) throw invalid_argument("");
    int box;

    for (int k = 0; k < (size / 2); k  ) {
        box = arr[k];
        arr[k] = arr[k 2];     
        arr[k 2] = box;
    }

    box = arr[0];
    arr[0] = arr[2];
    arr[2] = box;

    box = arr[1];
    arr[1] = arr[3];
    arr[3] = box;
}

// Then print the encrypted integer. 
void printArr(int arr[], int size) {    
    if (!arr) throw invalid_argument("");
    for (int k = 0; k < size; k  ) {
        std::cout << arr[k] << " ";
    }
}

That being said, consider using std::vector instead, eg:

#include "encrypt.h"

int main () {
    std::vector<int> arrEncrypt = {1, 2, 3, 4};

    swap(arrEncrypt);
    encrypt(arrEncrypt);
    printArr(arrEncrypt);
}

encrypt.h

#ifndef ENCRYPT_H
#define ENCRYPT_H

#include <vector>

void encrypt(std::vector<int> &a);
void swap(std::vector<int> &a);
void printArr(const std::vector<int> &a);


#endif

encrypt.cpp

#include <iostream>
#include <utility>
#include <stdexcept>
#include "encrypt.h"

// Replace each digit with the result of adding 7 to the digit and getting the remainder after dividing the new value by 10. 
void encrypt(std::vector<int> &arr) {
    for (size_t k = 0; k < arr.size(); k  ) {
        arr[k] = (arr[k]   7) % 10;
    }
}

// Then swap the first digit with the third, and swap the second digit with the fourth.
void swap(std::vector<int> &arr) {
    if (arr.size() < 4) throw invalid_argument("");
    for (size_t k = 0; k < (a.size() / 2); k  ) {
        std::swap(arr[k], arr[k 2]);
    }
    std::swap(arr[0], arr[2]);
    std::swap(arr[1], arr[3]);
}

// Then print the encrypted integer. 
void printArr(const std::vector<int> &arr) {    
    for (size_t k = 0; k < arr.size(); k  ) {
        std::cout << arr[k] << " ";
    }
}

Or std::array, eg:

#include "encrypt.h"

int main () {
    std::array<int, size> arrEncrypt = {1, 2, 3, 4};

    swap(arrEncrypt);
    encrypt(arrEncrypt);
    printArr(arrEncrypt);
}

encrypt.h

#ifndef ENCRYPT_H
#define ENCRYPT_H

#include <array>
#include <iostream>
#include <utility>

// Replace each digit with the result of adding 7 to the digit and getting the remainder after dividing the new value by 10. 
template<typename T, size_t N>
void encrypt(std::array<T, N> &arr) {
    for (size_t k = 0; k < N; k  ) {
        arr[k] = (arr[k]   7) % 10;
    }
}

// Then swap the first digit with the third, and swap the second digit with the fourth.
template<typename T, size_t N>
void swap(std::array<T, N> &arr) {
    if (N < 4) throw invalid_argument("");
    for (size_t k = 0; k < (N / 2); k  ) {
        std::swap(arr[k], arr[k 2]);
    }
    std::swap(arr[0], arr[2]);
    std::swap(arr[1], arr[3]);
}

// Then print the encrypted integer. 
template<typename T, size_t N>
void printArr(const std::array<T, N> &arr) {
    for (size_t k = 0; k < N; k  ) {
        std::cout << arr[k] << " ";
    }
}

#endif

CodePudding user response:

  • The arguments arrEncrypt[size] in the function main() is bad because
    • It is out-of-range because the array arrEncrypt has only size elements and its valid indice are 0 to size-1.
    • The functions are expecting pointers, but an integer is passed.
  • The element box[1] used in the function swap() is out-of-range because the array box has only one element. Since it looks you are using only the element box[1] from the array box, you should stop using array here and instead of that you should use simple variable box.

In the function main(), you should pass the array (or a pointer to the first element of the array converted from the array) to the function:

int main () {
    int arrEncrypt[size] = {1, 2, 3, 4};

    swap(arrEncrypt);
    encrypt(arrEncrypt);
    printArr(arrEncrypt);
}

In the function swap(), you should stop using out-of-range "element":

void swap(int arr[::num]) {

    int box = 0;
    for (int k = 0; k < (::num / 2); k  ) {
        box = arr[k];
        arr[k] = arr[k 2];     
        arr[k 2] = box;  
    }

    box = arr[0];
    arr[0] = arr[2];
    arr[2] = box;

    box = arr[1];
    arr[1] = arr[3];
    arr[3] = box; 

}
  • Related