What's the difference between passing an argument inside a function as a parameter and declaring the argument as a variable inside the function declaration block in function definition?
Example: Make use of my comments to get the gist of the question.
#include<iostream>
int max=0;
int t=0;
class stack
{
int s[10];
public:
void push(int);
void pop();
};
void stack::push(int y) //argument passed inside function parameter
{
if(t<=max);
{
s[t]=y;
t=t+1;
}
else
cout<<"Stack overflow";
}
void stack::pop()
{
int item; //variable declared inside function definition
if(t>=0)
{
t=t-1;
item=s[t+1];
}
}
One difference is that parameters are initialized by the caller but local variables have to be initialized by the function.
int somefunc(int arg)
{
int local = 0;
…
return local + arg;
}
When the function is called:
int x = somefunc(23);
the variable arg in the function is initialized with the value 23 by the calling code. However, the local variable local has to be explicitly initialized (in this case with the = 0; if it was a class type, by an appropriate constructor). Local variables of built-in types such as int that are not explicitly initialized get a quasi-random value.
One difference is in how arrays are interpreted:
// returns nonzero iff array1 equals {1, 2, 3}
int func(int array1[], size_t size1)
{
int array2[] = {1, 2, 3};
return size1 == sizeof(array2) && memcmp(array1, array2, size1) == 0;
}
While array2 is an array of 3 integers, array1 is an array of unknown size, which is why we usually pass a second parameter for the size. This is because of arrays "decay to pointers" when passed into functions like this. You can read about it here: What is array decaying?
There are fancier techniques for dealing with this in C++ using value templates for the array size, but the above is true of C and most C++ code in the wild too.
Other than arrays, C types used in function parameters behave pretty much the same as C types used in local variables.
The arguments is passed by calling that function. so caller decides what should be passed.
functions decides what should it accept.
for example:
main()
{
int i=0;
int k=i;
for (int j=i; j `enter code here`< n; j++)
{
}
}
is same as
main()
{
int i=0,k;
for (int j=k=i; j < n; j++)
{
}
}
but this
main()
{
int i=0,k;
for (int j=i; j < n; j++)
{
k=i;
}
}
is totally different.
Related
using namespace std;
void leftRotate(int arr[]){
unsigned int n = sizeof(arr)/sizeof(arr[0]);
for(int i = 0; i < n; i++){
cout<<"Value: " << arr[i] << endl;
}
}
//function declaration
void leftRotate(int arr[]);
int main(){
std::list<int> l = {1,2,3,4,5};
leftRotate(l);
return 0;
}
Your problem is connected with the declaration of your void leftRotate, as its input is an array of integers, while you declare l as the std::list<int>. You would have to change one of these (function or data) in order to make your program work, which means you must use only one type at a time. The possibilities are:
void leftRotate(int arr[]) {...}
int main()
{
int l[] = {1, 2, 3, 4, 5};
leftRotate(l);
}
or
void leftRotate(std::list<int> &s) {...}
int main()
{
std::list<int> l = {1,2,3,4,5};
leftRotate(l);
}
std::list<int> is not equivalent to array int arr[],hence, you don't have leftRotate function that accepts std::list<int> the compiler throws this error.
In order to solve this , depending on what your project needs, you either have to change:
the declaration of l to int int l[5] = { 1, 2, 3, 4,5};
Or the leftRotate definition and declaration to void leftRotate(std::list<int> arr).
Note: As mentioned in the comments. Unlike many other languages, In C and C++ you need to be explicit on how to pass parameters to functions, either by copying the data structure and everything in it to a new instance (passing by value) or by passing a pointer or reference to the original instance (passing by reference).
In your case the later option is more sensible, however the code you have and what being suggested is implementing the first option.
For more introductory information https://www.geeksforgeeks.org/parameter-passing-techniques-in-c-cpp/
Error: braces around scalar initializer for type int*
I'm trying to pass an array to the function but I keep getting this error in the initialization step.
How can I fix this?
#include <iostream>
using namespace std;
void func (int *p[4]);
int main()
{
int *p[4]={ {1,4,5},{3,5,6},{6,6,2},{6,5,3}}; //The error appears here
func(p);
return 0;
}
void func (int *p[4])
{
for(int i=0;i<4;i++)
{
for(int j=0;j<1;j++)
{ cout<<p[i][j]; }
}
cout<<" \t";
}
Problem is what is p.
Whit this definition:
int *p[4];
this is 4 element array of pointers to int.
I guessing you wanted this:
int (*p)[3];
pointer to 3 element array of ints.
Also to use initialization you need an array.
Here is working example.
The variable p is an array of pointers. { 1, 4, 5 } is not a pointer.
You need to make p an array of arrays:
int p[4][3] = { ... };
Because of that change, you have to change the func function argument as well, as p will now decay to a pointer to an array, of type int (*)[3] (that is, the argument for func should be int (*p)[3]).
This would work, however you are going to lose array information because they will decay into pointers:
int arr1[] = { 1,4,5 };
int arr2[] = { 3,5,6 };
int arr3[] = { 6,6,2 };
int arr4[] = { 6,5,3 };
int *p[4] = { arr1, arr2, arr3, arr4 };
I am looking for some advice on how to organise my C++ code.
I have an int array, side, that I would like to be static in the sense that its value is kept constant between calls. This is because my function foo(), will modify the array side recursively and so I don't want copies to be made of side. Furthermore, the size of side can only be determined at compile time from the size of a vector that is passed into the function bar().
I have thought of the following structure to layout such a problem.
I keep a global int pointer, side, which I can then use to point to the address of my int array and then use the pointer *side within foo to do my modifications.
Please can you give me advise on the layout and organisation of this code? I am quite new to C++ so would appreciate any advice on the below structure.
#include <iostream>
#include <vector>
using namespace std;
int *side;
class A {
public:
int foo(bool);
int bar(vector<int>);
void set_n(int n){ class_n = n;};
private:
int class_n;
};
int A::foo(bool fl)
{
int n = class_n;
for(int i = 0; i < n; i++) {
// modify side[] and then recursively call foo
}
return 0;
}
int A::bar(vector<int> t)
{
int size = t.size();
set_n(size);
int a = foo(true);
int *side_local = new int[size];
for(int i = 0; i < size; i++) {
side_local[i] = 0;
}
side = side_local;
return 0;
}
int main()
{
A a;
vector<int> t = {1, 2, 3};
a.bar(t);
return 0;
}
A recursive call can pass a pointer to itself:
void foo(int *pList)
{
foo(pList); // recursive
}
the same list is then being worked on.
That being said, since foo is inside a class you wouldn't need a global either, but a member variable.
class A
{
int *pMemberList;
...
void foo();
}
now foo can see pMemberList all the time.
BUT ... passing it is probably a better option as in the future your class might house 2 lists that you want to do foo on.
For some reason the following code gives a compiler error in DevC++: [Error] cannot declare member function 'static double* Sort::bubbleSort(double*, int)' to have static linkage [-fpermissive]
BubbleSort.cpp:
#include <iostream>
#include "Sort.h"
int main(int argc, char** argv) {
double list[] = {4.0, 4.5, 3.2, 10.3, 2.1, 1.6, 8.3, 3.4, 2.1, 20.1};
int size = 10;
double* sortedList = Sort::bubbleSort(list, size);
return 0;
}
Sort.h:
class Sort
{
public:
static double* bubbleSort (double list[], int size);
}
;
Sort.cpp:
#include "Sort.h"
#include <algorithm> // std::swap
static double* Sort::bubbleSort (double list[], int size)
{
bool changed = true;
do
{
changed = false;
for (int j = 0; j < size - 1; j++)
{
if (list[j] > list[j +1])
{
std::swap(list[j], list[j + 1]);
changed = true;
}
}
}
while (changed);
return list; // return pointer to list array
}
Essentially, I'm trying to call the bubbleSort function without creating a Sort object. The code works fine if I create an object first.
What could be causing the error?
Thanks for any suggestions.
The static modifier goes in Sort.h, but not in Sort.cpp.
That's because it means two different things in the two contexts.
When used inside a class declaration, static indicates that the method it refers to is a class method (that you should use without a object reference), rather than a instance method (that you need a object reference to invoke).
When used inside the implementation file (i.e. outside of a class declaration), it indicates that the method it refers to should have static linkage, which means it should not be made visible from outside the object file that contains it. From an object oriented point of view, these functions are private to the file that contains them. It's pretty obvious that this cannot work if other files (which are using your class) should access the method.
Remove the static keyword in the .cpp file. Also, you do not need to return the pointer list since only the contents of the array change change, not the array itself. You can keep using the pointer that you put into the function. sortedList will point to the same memory location as list at the end of your main function.
If all that is in your Sort class is this one static member, there is absolutely no need for a class.
double* bubbleSort (double list[], int size)
{
bool changed = true;
do
{
changed = false;
for (int j = 0; j < size - 1; j++)
{
if (list[j] > list[j +1])
{
std::swap(list[j], list[j + 1]);
changed = true;
}
}
}
while (changed);
return list; // return pointer to list array
}
Additionally, there is no need to return the pointer to the list because you are modifying the list as you sort it (double list[] is the same as double* list, and since you are changing the values in your routine, the pointer to the first element will still be the same, but the values in the array will be swapped around).
void bubbleSort (double list[], int size)
{
bool changed = true;
do
{
changed = false;
for (int j = 0; j < size - 1; j++)
{
if (list[j] > list[j +1])
{
std::swap(list[j], list[j + 1]);
changed = true;
}
}
}
while (changed);
}
You should make the function free-standing and if you need a class method, make it call the free-standing function with the correct parameters.
I'm trying to use pointers of arrays to use as arguments for a function which generates an array.
void generateArray(int *a[], int *si){
srand(time(0));
for (int j=0;j<*si;j++)
*a[j]=(0+rand()%9);
} //end generateArray;
int main() {
const int size=5;
int a[size];
generateArray(&a, &size);
return 0;
} //end main
But when I compile this this message appears:
cannot convert `int (*)[5]' to `int**' for argument `1' to `void generateArray(int**, int*)'
You're over-complicating it - it just needs to be:
void generateArray(int *a, int si)
{
for (int j = 0; j < si; j++)
a[j] = rand() % 9;
}
int main()
{
const int size=5;
int a[size];
generateArray(a, size);
return 0;
}
When you pass an array as a parameter to a function it decays to a pointer to the first element of the array. So there is normally never a need to pass a pointer to an array.
int *a[], when used as a function parameter (but not in normal declarations), is a pointer to a pointer, not a pointer to an array (in normal declarations, it is an array of pointers). A pointer to an array looks like this:
int (*aptr)[N]
Where N is a particular positive integer (not a variable).
If you make your function a template, you can do it and you don't even need to pass the size of the array (because it is automatically deduced):
template<size_t SZ>
void generateArray(int (*aptr)[SZ])
{
for (size_t i=0; i<SZ; ++i)
(*aptr)[i] = rand() % 9;
}
int main()
{
int a[5];
generateArray(&a);
}
You could also take a reference:
template<size_t SZ>
void generateArray(int (&arr)[SZ])
{
for (size_t i=0; i<SZ; ++i)
arr[i] = rand() % 9;
}
int main()
{
int a[5];
generateArray(a);
}
You do not need to take a pointer to the array in order to pass it to an array-generating function, because arrays already decay to pointers when you pass them to functions. Simply make the parameter int a[], and use it as a regular array inside the function, the changes will be made to the array that you have passed in.
void generateArray(int a[], int si) {
srand(time(0));
for (int j=0;j<*si;j++)
a[j]=(0+rand()%9);
}
int main(){
const int size=5;
int a[size];
generateArray(a, size);
return 0;
}
As a side note, you do not need to pass the size by pointer, because you are not changing it inside the function. Moreover, it is not a good idea to pass a pointer to constant to a parameter that expects a pointer to non-constant.
I'm guessing this will help.
When passed as functions arguments, arrays act the same way as pointers. So you don't need to reference them. Simply type:
int x[]
or
int x[a]
. Both ways will work. I guess its the same thing Konrad Rudolf was saying, figured as much.
This is another method . Passing array as a pointer to the function
void generateArray(int *array, int size) {
srand(time(0));
for (int j=0;j<size;j++)
array[j]=(0+rand()%9);
}
int main(){
const int size=5;
int a[size];
generateArray(a, size);
return 0;
}