I got not one but two good answers to my last question, which was how to make a function that would both create an array and fill it. I was surprised to find that the first one of them was so simple - I had been making it harder than it needed to be. But if both do the job, when is one better than the other? Anyone want to tackle that?

void  fillArray();
int main()
{  fillArray();
   return 0;  }  //End main fn
//*************************************************
//Function definition 
void fillArray()//No args or return values
{  const int SIZE = 3;
   int num[SIZE];//Create the array and size
   cout  << "Please enter three integers: ";
   for (int i = 0; i < SIZE; i ++)
      cin   >> num [i];

   cout  << "Here are your three integers: ";
   for (int i = 0; i < SIZE; i ++)
      cout   << num [i]  << " ";  } //End fillArray
//================================
//Another way to do the same thing; which is better, and in what situations?
#include <iostream>
using namespace std;

void  fillArray(int[], const int);
void  displayArray(int[], const int);

int main()
{  const int SIZE = 3;
   int num[SIZE];

   fillArray(num, SIZE);
   displayArray(num, SIZE);

   return 0; }
//****************** Fn definitions
void fillArray(int arr[], const int sz)
{    cout  << "Please enter three integers: ";
     for (int i=0; i < sz; i++)
        cin>>arr[i];   }  // End fillArray fn

void displayArray(int arr[], const int sz)
{   cout  << "Here are your three integers: ";
    for (int i=0; i < sz; i++)
      cout  << arr[i]   << " ";  } //End displayArray

Dani AI

Generated

Two patterns are shown by : a function that creates and uses an array entirely inside itself, and a pattern where the caller allocates the array and passes it to functions that fill and display it. is right that one pattern is more flexible — but the tradeoffs are worth spelling out so the right choice can be made for a given situation.

Creating the array inside the function keeps the task self-contained (useful for one-off operations), but the array is automatic storage and vanishes when the function returns. That means you cannot safely return a pointer/reference to it. Passing a caller-owned array into functions avoids that lifetime problem, but C-style arrays decay to pointers and lose size information, so the size must be carried separately, and safety relies on the caller providing the correct size.

A more robust modern-C++ approach is to use containers or views that carry size and lifetime semantics. For example, returning a std::vector<int> lets the caller own the data without manual memory management; std::array<T,N> works well for compile-time fixed sizes; std::span<T> (C++20) provides a safe non-owning view so functions can operate on any contiguous sequence without losing size information.

Example (modern pattern):

#include <vector>
#include <iostream>

std::vector<int> readValues(std::size_t n) {
    std::vector<int> v;
    v.reserve(n);
    for (std::size_t i = 0; i < n && std::cin; ++i) {
        int x;
        if (!(std::cin >> x)) break;
        v.push_back(x);
    }
    return v; // moved or elided efficiently
}

Practical tips: use std::size_t for sizes, mark read-only parameters const, avoid returning pointers to local arrays (UB), prefer standard containers for ownership and safety, and keep functions single-responsibility (read vs process vs print). If portability to older compilers matters, prefer std::vector or std::array over compiler-specific VLAs.

Recommended Answers

All 2 Replies

1) use Code tags.

2) The second one. Its more reusable.

Thanks - Sorry about forgetting the code tags; still new at this.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.