When I write like this swap(a,b); it is ok.
When I write like this swap(&c[0],&d[0]); there is a error.
Somebody can tell me why?
#include<iostream>
#include<algorithm>
using namespace std;
int main(void){
int *a;
int *b;
int c[]={1,2};
int d[]={3,4};
a=&c[0];
b=&d[0];
swap(a,b);// it is ok
//swap(&c[0],&d[0]);// it is error why
cout<<a[0]<<" "<<b[0]<<endl;
cin.get();
}
user3365922 is correct on the syntax if you wish to swap the contents of c[0] and d[0].
Just to add on because you code sample is a bit weird.
std::swap(a,b) in your code isn't actually swapping the contents c[0] and d[0]. It's swapping the pointers a & b. I mention this because it looks like you replaced the std::swap(&c[0], &d[0]) with std::swap(a,b)--which isn't actually equivalent (this is an assumption, my bad if they weren't meant to be equivalent).
I'm not totally sure what your goal is, but std::swap(c[0], d[0]) will achieve swapping the first entry of c with the first entry of d (leaving the second entry as-is). If you actually wanted to swap the contents of arrays entirely in the example above, you could also do std::swap(c, d).
Replace swap(&c[0],&d[0]) with swap(c[0], d[0]).
&c[0] and &d[0] are rvalues (temporary objects of type int*), but you can swap lvalues only.
You're able to swap(a, b) because a and b are lvalues, a after swap will be pointing to d[0] and b to c[0], swap(a, b) wouldn't swap values in array, this is a difference in behaviour (thanks to M.M's comment with a notice).
swap function
template <class T> void swap ( T& a, T& b )
{
T c(a); a=b; b=c;
}
And a=&c[0]; b=&d[0]; after swap(a,b);
a will pointing to d[0]
b will pointing to c[0]
and here swap(&c[0],&d[0]); the prototype dose not match the current swap function.The required prototype is
swap(int*,int*)
so there is no matching function to call so the compiler throws error.
The arguments to std::swap() are two integer pointers, not two addresses of an array with an index.
For swapping normal singular int values you will have to use a pointer (call by reference), but for an array you could directly pass it (as base address of array is taken) for which you could have used c[0],d[0]. Using & to reference the array (i.e. using &c[0],&d[0]) with the function accepting a int * type would cause argument type mismatch, with your passed values being rvalues of type int *, which cannot be swapped. (whereas lvalues like c,d and c[index],d[index] can be swapped)
The error you recieved should be:
main.cpp:12:13: error: no matching function for call to ‘swap(int*, int*)’
swap(&c[0],&d[0]);
^
This pertains to invalid initialization of a non-const reference of type int*& from an rvalue of type int*, which is included in the error message.
If what you want to consider as the parameters are indeed addresses of the arrays, this would be your function:
void swap_array_elements(int a, int b, int arr[], int arr2[])
{
int temp = arr[a];
arr[a] = arr2[b];
arr2[b] = temp;
}
Note that the first two arguments used here are indices of the two arrays passed respectively as the third and fourth argument. This will swap in between any two elements you require among the two arrays.
Example:
#include <iostream>
void swap_array_elements(int a, int b, int arr[], int arr2[])
{
int temp = arr[a];
arr[a] = arr2[b];
arr2[b] = temp;
}
int main()
{ int array1[]={42,56}, array2[]={63,89};
swap_array_elements(0,1,array1,array2); // swapping element with index 0 in array1 (42) with element with index 1 in array2 (89)
std::cout<<array1[0]<<" "<<array2[1]; // 89 42
return 0;
}
Related
I am currently struggling with Pointers in C++, especially with the input of following function:
/*
... there is an immutable array a of unsigned integers that we are not allowed to change
In order to sort this array, a second array b containing pointers to the individual
elements in a is created. We then sort the poiners in b based on the values of the pointed-to elements in a.
(d) implement the quicksort function which sorts an array of pointers as outlined above.
Note that the parameters to this function are two pointers, one to the first element in b and
one to the first element past the end of b.
*/
// Sort the range of pointers [begin; end)
void quicksort(const unsigned** begin, const unsigned** end)
{
//TODO
}
However, the Function is given const values, so is there any way to change the position of the input pointers?
A common Quicksort algorithm relies on the swap function, I tried calling
void swap (const unsigned** a, const unsigned** b){
const unsigned** temp = **a;
**a = **b;
**b = temp;
}
with
swap(begin, (end-1));
in the Quicksort Function. But that does not not work as the value for **a cannot be changed (Here, with the value **b), due to it being const.
So how would I even be able to sort the input pointers if I cannot change their order?
First of all, I know this stuff is really tricky when starting out with c/c++ and I had my fair share of confusion when I did. Therefore I will try to explain it the best way I can:
What you are trying to do in your swap function is changing the actual value of the integers behind the pointers by dereferencing two times and reassigning. You got an array of pointers which is basically a pointer to the first pointer and if you dereference that two times you end up at the actual integers, however you don't want that because this integer is constant.
Instead you want to end up at the pointers to the actual integers and swap those around. You can achieve that by dereferencing only once. If you try to reasign the pointer to change what it's pointing to, you can change the order of the array of pointers without ever touching the actual integers.
your swap function should look like this:
void swap(const unsigned int** a,const unsigned int** b) {
const unsigned int* temp = *a;
*a = *b;
*b = temp;
}
and the code where you call it could look something like this:
const unsigned int sort_without_touching[] = { 1 , 2 };
const unsigned int* ptr_array[] = {&sort_without_touching[0],
&sort_without_touching[1]};
//1 2
std::cout << *ptr_array[0] << " " << *ptr_array[1] << std::endl;
swap((ptr_array+ 0), (ptr_array+ 1));
//2 1
std::cout << *ptr_array[0] << " " << *ptr_array[1] << std::endl;
I am trying to write a function that prints out the elements in an array. However when I work with the arrays that are passed, I don't know how to iterate over the array.
void
print_array(int* b)
{
int sizeof_b = sizeof(b) / sizeof(b[0]);
int i;
for (i = 0; i < sizeof_b; i++)
{
printf("%d", b[i]);
}
}
What is the best way to do iterate over the passed array?
You need to also pass the size of the array to the function.
When you pass in the array to your function, you are really passing in the address of the first element in that array. So the pointer is only pointing to the first element once inside your function.
Since memory in the array is continuous though, you can still use pointer arithmetic such as (b+1) to point to the second element or equivalently b[1]
void print_array(int* b, int num_elements)
{
for (int i = 0; i < num_elements; i++)
{
printf("%d", b[i]);
}
}
This trick only works with arrays not pointers:
sizeof(b) / sizeof(b[0])
... and arrays are not the same as pointers.
Why don't you use function templates for this (C++)?
template<class T, int N> void f(T (&r)[N]){
}
int main(){
int buf[10];
f(buf);
}
EDIT 2:
The qn now appears to have C tag and the C++ tag is removed.
For C, you have to pass the length (number of elements)of the array.
For C++, you can pass the length, BUT, if you have access to C++0x, BETTER is to use std::array. See here and here. It carries the length, and provides check for out-of-bound if you access elements using the at() member function.
In C99, you can require that an array an array has at least n elements thusly:
void print_array(int b[static n]);
6.7.5.3.7: A declaration of a parameter as ‘‘array of type’’ shall be adjusted to ‘‘qualified pointer to
type’’, where the type qualifiers (if any) are those specified within the [ and ] of the
array type derivation. If the keyword static also appears within the [ and ] of the
array type derivation, then for each call to the function, the value of the corresponding
actual argument shall provide access to the first element of an array with at least as many
elements as specified by the size expression.
In GCC you can pass the size of an array implicitly like this:
void print_array(int n, int b[n]);
You could try this...
#include <cstdio>
void
print_array(int b[], size_t N)
{
for (int i = 0; i < N; ++i)
printf("%d ", b[i]);
printf("\n");
}
template <size_t N>
inline void
print_array(int (&b)[N])
{
// could have loop here, but inline forwarding to
// single function eliminates code bloat...
print_array(b, N);
}
int main()
{
int a[] = { 1, 2 };
int b[] = { };
int c[] = { 1, 2, 3, 4, 5 };
print_array(a);
// print_array(b);
print_array(c);
}
...interestingly b doesn't work...
array_size.cc: In function `int main()':
array_size.cc:19: error: no matching function for call to `print_array(int[0u])'
JoshD points out in comments below the issue re 0 sized arrays (a GCC extension), and the size inference above.
In c++ you can also use a some type of list class implemented as an array with a size method or as a struct with a size member(in c or c++).
Use variable to pass the size of array.
int sizeof_b = sizeof(b) / sizeof(b[0]); does nothing but getting the pre-declared array size, which is known, and you could have passed it as an argument; for instance, void print_array(int*b, int size). size could be the user-defined size too.
int sizeof_b = sizeof(b) / sizeof(b[0]); will cause redundant iteration when the number of elements is less than the pre-declared array-size.
The question has already some good answers, for example the second one. However there is a lack of explanation so I would like to extend the sample and explain it:
Using template and template parameters and in this case None-Type Template parameters makes it possible to get the size of a fixed array with any type.
Assume you have such a function template:
template<typename T, int S>
int getSizeOfArray(T (&arr)[S]) {
return S;
}
The template is clearly for any type(here T) and a fixed integer(S).
The function as you see takes a reference to an array of S objects of type T, as you know in C++ you cannot pass arrays to functions by value but by reference so the function has to take a reference.
Now if u use it like this:
int i_arr[] = { 3, 8, 90, -1 };
std::cout << "number f elements in Array: " << getSizeOfArray(i_arr) << std::endl;
The compiler will implicitly instantiate the template function and detect the arguments, so the S here is 4 which is returned and printed to output.
I was playing through c++ and trying to understand vector and its signature .
In below method printPrimes I need to use pointer with address of why ?
Is vector<int> &primes not enough as from main method printPrimes is already sending address .
void printPrimes(long long l, long long r, vector<int>* &primes) {
// some code
}
vector<int>* sieve() {
vector<int> *prime = new vector<int>();
return prime;
}
int main() {
vector<int> *primes = sieve();
printPrimes(l, r, primes);
return 0;
}
I need to use pointer with address of
Here, & does not mean "address of"; it means the type "reference to".
It's clearer if you write it not like this:
vector<int>* &primes
but like this:
vector<int>*& primes
Though the choice of whitespace is artificial, that better documents that this & is "part of the type".
Have some types:
std::vector<T> = A vector of Ts
std::vector<T>& = A reference to a vector of Ts
std::vector<T>* = A pointer to a vector of Ts
std::vector<T>*& = A reference to a pointer to a vector of Ts
std::vector<T>*** = A pointer to a pointer to a pointer to a vector of Ts
std::vector<T>**& = A reference to a pointer to a pointer to a vector of Ts
…and so forth.
As for why you need a vector<int>*& for printPrimes to do its job, we could not tell you without actually being able to see it. I will say that it seems unlikely it needs a pointer at all, and that if it wants to modify that pointer it's going to cause problems with the new and delete in the calling scope.
In fact, all that dynamic allocation is completely pointless and only complicates things.
The following was likely intended instead:
void printPrimes(long long l, long long r, vector<int>& primes) {
// some code
}
vector<int> sieve() {
vector<int> prime;
return prime;
}
int main() {
vector<int> primes = sieve();
printPrimes(l, r, primes);
}
vector<int>* &primes parameter has to be read this way:
Reference to a pointer of vector of int
and not
Address of a pointer of vector of int (which, you are right, would be useless)
Passing by reference allows to directly manipulate any instance outside of scope (like with pointers, but a safer way since a reference cannot be nullptr, and its existence is auto-managed (no need to delete)).
In c++ & in function parameter used to pass parameter by reference. vector<int>* &primes declares primes to be a reference to a pointer to vector<int>.
If printPrimes means to print only the vector passed to the function then the signature
void printPrimes(long long l, long long r, vector<int> &primes);
can also do the job.
Reference to a pointer is needed when the pointer passed to the function is need to be modified and it's effect is expected to seen in the caller function.
void foo(int*& p){
p = new int[10];
// rest of the code
}
if a function bar is calling foo like
void bar(/* some parameters */){
// ...
int *p;
foo(p);
// rest of the code
}
foo is modifying the pointer itself and this modification will be seen to bar also and memory allocated to p can be accessed from bar.
I want to use for example this array of pointers to functions, without using STL.
That array is an array of pointers that I call functions OptionA, OptionB and so on.
int(*Functions[4])();
Functions[0] = OpionA;
Functions[1] = OptionB;
Functions[2] = OptionC;
Functions[0] = Exit;
Now if I write inside the function where I have my array
Functions[0];
I want to have called function 'OptionA' where it has been defined before for example like this:
int OptionA()
{
cout << "OPTION A";
_getch();
return 0;
}
Is it possible to do this without STL?
If not, I would like to know how to do it with STL.
You can create and pass arrays of function pointers like any other types. It's easiest if you have a type alias (my example leverages using, but typedef will also work).
#include <iostream>
using Function = int (*)(int, int);
int add(int a, int b) {
return a + b;
}
int sub(int a, int b) {
return a - b;
}
void do_stuff(int a, int b, Function * fns, int cnt) {
for(auto i = 0; i < cnt; ++i) {
std::cout << "Result " << i << " = " << fns[i](a, b) << '\n';
}
}
int main() {
Function fns[2] = { add, sub };
do_stuff(10, 7, fns, 2);
return 0;
}
Output:
Result 0 = 17
Result 1 = 3
I think that what you are looking for is
How to initialize a vector of pointers
Once your vector is initialize you can send it to a function like a normal data type.
Example:
std::vector<int*> array_of_pointers{ new int(0), new int(1), new int(17) };
function(array_of_pointers);
In the declaration of the function
void function(std::vector<int*> array_of_pointers);
I hope this answer your question.
In C and C++, arrays are second-class. They cannot be passed by value by themselves, only if somehow wrapped.
As a first step, the questions you have to decide are:
Does your array have a fixed length?
And do you have to pass it by value or can you pass it by reference?
If you have to pass it by value, is that a choice you want the caller to make, or the callee to impose? In the first case, pass it by reference.
If you pass the array by reference, nothing can beat using a gsl::span, unless you pass multiple sequences all having intrinsically the same length, in which case passing pointers and a single length-argument is more efficient and maybe comfortable.
If you pass an array of variable length by value, try to use a std::vector. That's also the go-to type to pass a by-ref argument as if by-value.
Otherwise (array of fixed length, by value), nothing beats std::array.
If p is a pointer to a function, which receives no parameters, you should call it by this syntax:
p();
So, if array is an array of pointers to functions, you should call one of them using the same syntax idea:
array[0]();
Here the parentheses are important; they say "call this function, and pass no parameters to it". If you have no parentheses
array[0];
this means "select this function from the array, but do nothing with it".
It's a useless expression, like if you have an integer x, then x * 5 means "multiply x by 5 and do nothing with the result" (useless), while x *= 5 means "multiply x by 5 and replace x with the result".
Here is my problem:
I have a struct:
struct point
{
int x;
int y;
};
and then I have an array:
for (int i = 0;i < n;i++)
{
arr[i].x=rand() % n + 1;
}
I defined the quicksort function as follows:
void quicksort(int *a, int left, int right);
and I want to sort the point by X coordinate, so I call the quicksort:
quicksort(arr.x, 0, n-1);
And this is the error message:
error: request for member 'x' in 'arr', which is of non-class type 'point [(((unsigned int)(((int)n) + -0x000000001)) + 1)]'
Sorry if the question is too stupid or badly formulated, the truth is I'm a newbie and I'm really willing to learn as much as possible and I'd be very thankful for your help!
If you always want to sort by x, then you can hard-code it into the sort function, and just pass a pointer to the array to sort:
void quicksort(point * arr, int left, int right) {
// test points with
// if (arr[i].x < arr[j].x) {/* i sorts before j */}
}
quicksort(arr, 0, n-1);
To specify a class member to sort by, you need a pointer-to-member, not a pointer; something like:
void quicksort(point * arr, int point::*member, int left, int right){
// test points with
// if (arr[i].*member < arr[j].*member) {/* i sorts before j */}
}
quicksort(arr, &point::x, 0, n-1);
More generically, you could follow the example of std::sort and accept any comparison functor:
template <typename RandIter, typename Compare>
void quicksort(RandIter begin, RandIter end, Compare compare) {
// test points with
// if (compare(*it1, *it2)) {/* *it1 sorts before *it2 */}
}
quicksort(arr, arr+n,
[](point const &lhs, point const &rhs) {return lhs.x < rhs.x;});
And of course, unless you're learning how to implement a sorting algorithm, just use std::sort.
quicksort(arr,0,n-1);
then within quicksort, try to compare the arr[i].x
There are a few problems with your code.
1. quicksort accepts int* but you try to pass int value x
2. You try to pass int but you actually call an undefined variable arr.x
What you need to do is either call in the form of &arr[i].x, but to accomplish what you want, you probably want to pass the entire struct as a pointer.
You need to pass arr as the parameter, as that is the array to be sorted. arr.x is meaningless. You are not passing the string "arr.x" as a parameter which can somehow be interpreted as meaning sort on the x field - when the compiler sees this, it is looking for an x element of arr, which doesn't exist, as the error message suggests - only the elements of arr (e.g. arr[0]) have x elements (accessed as arr[0].x).
Assuming this is for academic purposes (why else would you declare your own sorting algorithm instead of using one of the ones already implemented with a custom comparator?), you can do this a few ways:
Array
std::array<point, 10> myArray; // declares an array of size 10 for points
template<size_t N>
void quicksort(std::array<point, N>& arr, ...)
{
// implement sort operating on arr
}
Vector
std::vector<point> myVector; // declares a dynamic array/vector of points
void quicksort(std::vector<point>& arr, ...)
{
// implement sort operating on arr
}
If for some god-awful reason, you want to keep it in C:
Legacy
const size_t SIZE = 10;
point arr[SIZE]; // declare an array of 10 points
void quicksort(point* p, const size_t n, ...)
{
// implement sort operating on elements in p passing in SIZE for n
}
I'd rather defined the function as:
void quicksort(void *a,int left,int right, size_t size, int (*fp)(void*,void*));
size is the size of one element of array and fp is a compare function which returns true if the two arguments are equal. Now you can pass the call the function as:
quicksort(arr,0,n-1,sizeof(arr)/sizeof(arr[0]), compare);
where function compare is something like:
int compare(void* a, void* b) { return *((int*)a) >= *((int*)b); }
Rest of the implementation of function is trivial I think.
(almost) never try to fool the system by passing a pointer to a member when you really want to pass a pointer to an object. Do as Grijesh suggested. Passing a member can lead to horrible side effects. For example, quicksort is going to sort all the integers together, regardless of which of them are X's and which are Y's. In milder cases you may get wrong compare criteria, and often hard to debug effects such as incorrect pointer optimization. Just be honest with the compiler and pass the object pointer if you need to pass an object pointer. There are very very very few exceptions, mostly to do with low-level system programming where the "other side' of the function call won't be able to handle the object.