I have written this piece of code:
#include <iostream>
using namespace std;
double function(int i)
{
static int Array[5] = {0};
for(int j = i ; j <= i ; j++)
{
Array[j+1] = Array[j]+1;
}
return Array[i+1];
}
int main()
{
for(int i = 0 ; i <= 4 ; i++)
{
cout << function(i) << endl;
}
return 0;
}
Which outputs 1,2,3,4,5
I am wondering why elements of Array at each call of function(i) doesn't become zero despite this piece of code :
static int Array[5] = {0};
The array is static, which means it gets initialized just once (the first time function is called). It keeps its existing items thereafter. If you remove the static keyword you will get 1, 1, 1, 1, 1 instead.
By the way, the for loop inside function is redundant (it's guaranteed to only execute exactly once).
When you use static keyword for declaring a variable inside a function. Then:
The variable is created when the function is called first time.
Thereafter the variable remains alive throughout the lifetime of the program &
The value of the variable persists between function calls.
What you observe is this property of the keyword static at work.
The Array is statics. static variables only initialize once. Therefor, Array becomes zero only on the first call.
if you remove the static keyword it will become zero on every call.
by the way the following code is very strange:
for(int j = i; j <=i ; j++)
because it only runs for j=i. So you can change the whole function by the following:
double function(int i)
{
static int Array[5] = {0};
Array[i+1] = Array[i]+1;
return Array[i+1];
}
Related
I'm pretty new to coding and stumbled upon this issue when trying to code a program that prints the biggest number in an array.
Basically, if I don't include cout<<i;, the printf() will print the array location instead of the number 20. Any ideas why? (I'm guessing it is something stupid I overlooked, so sorry in advance).
#include <iostream>
using namespace std;
int maxinlst(int lst[], int size) {
int maxNum;
for (int i = 0; i < size; i++) {
cout << i;
if (lst[i] == lst[0])
int maxNum = lst[i];
else if (maxNum < lst[i]) {
maxNum = lst[i];
}
}
return maxNum;
}
int main() {
int lst[] = {-19, -3, 20, -1, 5, -25};
printf("%i", maxinlst(lst, 6));
}
You shadow maxInt by declaring another variable with the same name. See my comments here:
int maxinlst(int lst[], int size) {
// First declaration
int maxNum;
for (int i = 0; i < size; i++) {
cout << i;
if (lst[i] == lst[0])
// Second declaration
int maxNum = lst[i];
else if (maxNum < lst[i]) {
maxNum = lst[i];
}
}
return maxNum;
}
This is legal in C++, and in most languages with block scope. The second declaration creates a new variable, but it's never used because it goes out of scope immediately, so the whole assignment, along with the conditional, can be eliminated by the compiler. If you enable compiler warnings, you should get a warning about the second declaration because that variable is never used again:
test.cpp: In function ‘int maxinlst(int*, int)’:
test.cpp:8:17: error: unused variable ‘maxNum’ [-Werror=unused-variable]
int maxNum = lst[i];
^~~~~~
This also means that the value of the outer maxNum after the first iteration of the loop is indeterminate and reading it could be undefined behavior so the second loop iteration is either going to (a) use an indeterminate value since the outer maxNum was never assigned or (b) something else entirely because of UB.
If the second conditional is never true (assuming an indeterminate value and not UB) then the value returned by this function will also be indeterminate -- whatever unpredictable number maxNum happened to be.
The correction here would be to remove int in the second declaration.
You could also rewrite this to avoid the first in-loop conditional:
int maxinlst(int lst[], int size) {
// First declaration
int maxNum = lst[0];
for (int i = 1; i < size; i++) {
if (maxNum < lst[i]) {
maxNum = lst[i];
}
}
return maxNum;
}
As far as why cout << i changes the value you see, that's exactly the nature of using indeterminate values / undefined behavior. You can't reason about what's happening. Adding or removing other code could also change the value returned by the function. You may even see different values if you run the program multiple times without making any changes to it.
You actually have two variables called maxNum. Inside your if statement, int maxNum = lst[i] defines a new variable called maxNum which hides the outer maxNum variable. The inner, newly defined maxNum is destroyed as soon as the program exits the if statement.
What makes you think that the array location is being print?
maxNum is not set to a particular value when it is defined. Because of that it's just going to have whatever was stored in the memory before.
If that value in memory is large, then maxNum will be larger than all the values in your array, then maxNum will never change and it will keep the garbage value.
So, when you get to your printf statement, the garbage value will be output. I doubt that the location of the array is being output. I bet that it's just whatever garbage was in memory.
I am a C++ beginner and my task is as follows:
Define and initialise a single-dimensional integer array. Next, define a pointer that points to the first element in the array and passes the pointer to a function.
Using only pointer variables (and looping constructs), print only the array values that are exact multiples of 7 from start to finish to standard output. The only program output should be the numbers, one per line with no white space.
I have tried:
void print_sevens(int* nums, int length)
{
int array[5] = { 5,8,21,43,70 };
int* ptr = array;
int* num = array;
for (int i = 0; i < length; i++)
{
*num++;
if (num[i] % 7 == 0) {
cout << num[i] << endl;
}
}
}
int main()
{
int array[5] = { 5,8,21,43,70 };
int* ptr = array;
print_sevens(ptr, 5);
}
It compiles but does not output anything.
I am also confused about passing the pointer to a function. Should this be done in the main file or in the function file?
You are creating an additional array in the print_sevens function, which is unnecessary as you already passed the pointer to the first element of the array created in the main()(i.e. array).
Removing that unnecessary array and related codes from the function will make the program run perfectly. (See online)
void print_sevens(int* nums, int length)
{
for (int i = 0; i < length; i++)
{
if (nums[i] % 7 == 0)
std::cout << nums[i] << std::endl;
}
}
and in the main you only need to do the follows, as arrays decay to the pointer pointing to its first element.
int main()
{
int array[5]{ 5,8,21,43,70 };
print_sevens(array, 5);
}
Note that,
num++ increments the pointer, not the underline element it is
pointing to (due to the higher operator precedence of operator++ than operator*). If you meant to increment the element(pointee) you
should have (*num)++.
Secondly, do not practice with using namespace std;. Read more:
Why is "using namespace std;" considered bad practice?
You are modifying the contents of your array when you do *num++.
Is this function have any sense? if I didn't define the value of p_var1[] and p_size?
Just to know if it make sense, I have bigger code, but as a beginner, for me, if there is no values for these variables, that is weird.
First function:
int max1(int p_values[15][15])
{
int max_value;
for(int i=0; i < 15; i++)
{
int max_v = fnc(p_values[i], 15);
if( max_value < max_v)
{
max_value = max_v;
}
}
return max_value;
}
and second
//p_var1[] - is an array of values
//p_size - is the size of array
int fnc(int p_var1[], int p_size)
{
int max_value;
for (int i = 0; i < p_size; i++)
{
if (max_value > p_var1[i])
{
max_value = p_var[i];
}
}
return max_value;
}
This code isn't a full program, it's just a function definition. Here, a function called fnc is declared that can be called with parameters. Here's an example of a full program using it:
//p_var1[] - is an array of values
//p_size - is the size of array
int fnc(int p_var1[], int p_size)
{
int max_value;
for (int i = 0; i < p_size; i++)
{
if (max_value > p_var1[i])
{
max_value = p_var[i];
}
}
return max_value;
}
int main() {
int lst[5] = {10, 2, 6, 4, 8};
int max = fnc(lst, 5); // max = 10
return 0;
}
I guess you wrote fnc(p_values[i], 15) without knowing what it means? Not the best approach, but asking about it shows promise. When this expression is reached, the fnc identifier says that we're going to pause the execution of the current function (max1) and jump to execute the function fnc. Once that function finishes, the returned value will be the value of the expression and execution of max1 can resume. The stuff in the parentheses says that as we jump to fnc, assign p_var1 = p_values[i] and p_size = 15 (the first parameter is assigned the first argument, and the second parameter is assigned the second argument). If you're confused by the terms "parameter" and "argument", see What's the difference between an argument and a parameter?
So when you call fnc you do define the value of p_var1 and p_size (for that function call). (Wikipedia has an article with an example that covers this also, and you might find some useful information in the rest of that article.)
I am currently working on a project where we have to create an array of 1000 elements then pass it to another function to sort it. Everything I have seen online shows you how to pass it from main to another function, but not the other way around.
Please take a look at my code and help me pass Ar[1000] from Array() to ISort and ultimately main
#include <iostream>
#include <time.h>
using namespace std;
void Array()//function to make array
{
int Ar[1000];//creating array
int i = 0;//random variable to be element #
int counter = 0;// counter variable
int randnum;//variable to old random number
srand(time(NULL));//seeding rand with time
while (counter != 1000)
{
randnum = rand();
Ar[i] = randnum;
cout << Ar[i]<<endl;
counter++;
}
}
void ISort(int Ar[1000])//Iterative sort
{
int count = 0;//another counter variable
int count2 = 0;//counter variable # 3 because nested loops
int j=0;//Temp index # similar to i
int temp; //Temp variable to help switch elements
while (count != 1000)
{
if (Ar[count] < Ar[j])
{
temp = Ar[count];
Ar[count] = Ar[j];
Ar[j] = temp;
}
}
}
/*void RSort(int Ar)//Recursive sort
{
}
*/
int main()
{
Array();
ISort();
system("Pause");
return 0;
}
Ar in your Array function will be destroyed once this function finishes, you need to have a way to prevent this, one way is to pass an array by parameter instead of making it function local variable:
void Array(int* Ar, int count)//function to make array
{
I would also change Your current ISort definition to:
void ISort(int* Ar, int acount)//Iterative sort
where acount is number of elements in Ar. This is because it makes no difference whether you use void ISort(int Ar[1000]) or void ISort(int* Ar) (read here for more on this). If you want to preserve array type then you must pass it by reference using: void ISort(int (&Ar)[1000]).
Finally changes in main:
int Ar[1000];//creating array
Array(Ar, 1000);
ISort(Ar, 1000);
system("Pause");
return 0;
working code is here: http://coliru.stacked-crooked.com/a/678f581f802da85b
You also forgot to increment count inside your sorting loop.
Your array int Ar[1000] variable inside an Array() function is a local variable. Make it a global variable by moving it out of the function scope:
int Ar[1000]; //creating array
// your functions here
int main()
{
Array();
ISort(Ar);
return 0;
}
You should also modify the Array() function to accept array as parameter as pointed out in the comments below. Please note that I am omitting the array size part as it seems the number of the elements is set to 1000:
void Array(int Ar[]){
//...
};
in which case the above code would be:
int Ar[1000]; //creating array
// your functions here
int main()
{
Array(Ar);
ISort(Ar);
return 0;
}
Change the Array function declaration to:
int* Array() and make it return the array Ar. And in main get the returned value from Array function like this:
int* Ar = Array();
and pass it to the function ISort like this : ISort(Ar);.
Here is an example on SO passing an array to a function.
The easiest solution would be to change Array function a bit:
int* Array() { // change return type to be able to return array you create
int Ar[1000];
for (int i = 0; i < 1000; i++) { // much better to use for loop than while
Ar[i] = rand(); // no need to hold another variable for random number
cout << Ar[i] << endl;
}
return Ar; // return the Ar
}
int main() {
int* array = Array();
ISort(array);
}
Hope that helps. Also there are many other solutions to this but I don't know what exact restrictions your task has. If you have any questions feel free to ask.
EDIT: So I totally forgot about that C arrays are just a plain old pointers... Well then the solution would be like this:
void Array(Ar[1000]& array) { // pass array to the function with reference
for (int i = 0; i < 1000; i++) { // much better to use for loop than while
array[i] = rand(); // no need to hold another variable for random number
cout << array[i] << endl;
}
}
int main() {
int[1000] array = Array();
ISort(array);
}
Sorry for the error but using C style arrays really isn't common in C++ when you can use vectors and maps.
The output for this code is:
9
And I'm not sure what it changes in the function add1. And also what does this &n mean and what does it do when we assign the i to &n?
#include <iostream>
using namespace std;
int add1(int &n){
n++;
return n;
}
int main(){
int m = 0;
for (int i = 0; i < 5; i++){
m += add1(i);
}
cout << m ;
cout << "\n\n";
return 0;
}
When & is used in a parameter list, it will cause that parameter to be passed as a reference to the function.
What this means is that n in your function add1, will point to the same space in memory as i in your main function. Changes to n will also be reflected in i, as they will simply act as different names for the same thing.
Variable i is passed into add1 as a reference parameter, so every round i is increased by two:
1st round: i = 0, m = 1
2nd round: i = 2, m = 4
3rd round: i = 4, m = 9
If you have a function like this
int add1( int n )
^^^^^
{
n++;
return n;
}
and call it like
m += add1(i);
Then the function deals with a copy of the value of vatiable i.
You can imagine it the following way if to build it in the body of the loop
for ( int i = 0; i < 5; i++ )
{
// m += add1(i);
// function add1
int n = i;
n++;
m += n;
}
When a function is declared like this
int add1( int &n )
^^^^^
{
n++;
return n;
}
Then it means that the parameter is a reference to the corresponding original argument. You can consider it just as an alias for the argument.
In this case you can imagine it the following way if to build it in in the body of the loop
for ( int i = 0; i < 5; i++ )
{
// m += add1(i);
// function add1
i++;
m += i;
}
So the variable i is changed twice in the function add1 because it is directly used in the function by means of the reference n and in the control statement of the loop.
Here we are passing a parameter to the add1() function by using pass by reference. To pass a variable by reference, we simply declare the function parameters as references rather than as normal variables.
In above code,
int add1(int &n){ // n is a reference variable
n++;
return n;
}
When the function is called, n will become a reference to the argument. Since a reference to a variable is treated exactly the same as the variable itself, any changes made to the reference are passed through to the argument!