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 functionmain()
is bad because- It is out-of-range because the array
arrEncrypt
has onlysize
elements and its valid indice are0
tosize-1
. - The functions are expecting pointers, but an integer is passed.
- It is out-of-range because the array
- The element
box[1]
used in the functionswap()
is out-of-range because the arraybox
has only one element. Since it looks you are using only the elementbox[1]
from the arraybox
, you should stop using array here and instead of that you should use simple variablebox
.
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;
}