I am trying to learn better how pointer work in C and pointer to pointer to structure things broke my mind. Here I have 3 questions:
If I have a structure and a pointer to pointer **tests to this structure (so this is something like an array) how can I use p to access to array members (the best way)? tests[i]->id fails (example of source is below)
Having that monstrous line with pointers below is something bad to have in the code but I would like to do work with it as well. I think I've mistaken with its template, the output for every next structure's address looks like jumps 32 bytes ahead, while size of structure is only 4 bytes. So in the line I want to (1) take the initial address of the tests top pointer, (2) add to it size of the structure TestCase multiplied by i so it points to correct array element and (3) add offset of the id field of the structure. And after that I will get address where I can write the id value in memory, right? Am I doing this correct?
Why *tests value was changed? Buffer overflow?
struct TestCase{
int id;
};
int main()
{
TestCase ** tests;
cout << "Size of TestCase: " << sizeof(TestCase) << endl;
*tests = (TestCase*)malloc(sizeof(TestCase*)*5);
cout << "*tests = " << *tests << endl;
for(int i = 0; i < 5; i++)
{
//*(int*)(tests+sizeof(TestCase)*i+(int)&(((struct TestCase*)NULL)->id)) = i;
int addr = tests; // address of structures array in memmory;
addr += sizeof(TestCase)*i; //address of current structure;
addr += (int)&(((struct TestCase*)NULL)->id); // Adding id parameter offset in memory to current address
*(int*)addr = i; // setting id for current structure equal to i
cout << (int*)(tests+sizeof(TestCase)*i+(int)&(((struct TestCase*)NULL)->id)) << endl;
}
cout << "*tests = " << *tests << endl;
return 0;
}
Output is:
Size of TestCase: 4
*tests = 0x600048600
0x23ab90
0x23abb0
0x23abd0
0x23abf0
0x23ac10
*tests = 0x600000000
P.S.: Updated cycle code from one monstrous line to step by step actions.
Assuming that you want tests to be an array-of-pointers-to-struct-TestCase with 5 pointers to 5 structs, then you need to
allocate an array of 5 pointers, and
initialize each pointer by allocating memory for the struct
Like this:
#include <stdio.h>
#include <stdlib.h>
struct TestCase
{
int id;
};
int main( void )
{
int i;
struct TestCase **tests;
// allocate memory for an array of 5 pointers
tests = malloc( 5 * sizeof(struct TestCase *) );
if ( tests == NULL )
exit( 1 );
// allocate memory for 5 structures (and save each pointer in the array)
for ( i = 0; i < 5; i++ )
{
tests[i] = malloc( sizeof(struct TestCase) );
if ( tests[i] == NULL )
exit( 1 );
}
// initialize the id in each struct
for ( i = 0; i < 5; i++ )
tests[i]->id = i;
// print the id in each struct
for ( i = 0; i < 5; i++ )
printf( "%d\n", tests[i]->id );
// free memory
for ( i = 0; i < 5; i++ )
free( tests[i] );
free( tests );
return 0;
}
I wasn't able to reproduce the problem described in point 2. Here's the code I tried (which I placed ahead of the code that frees memory)
printf( "%p\n", tests );
for ( i = 0; i < 5; i++ )
{
intptr_t addr = (intptr_t)tests;
addr += sizeof(struct TestCase)*i;
addr += (int)&(((struct TestCase*)NULL)->id);
printf( "%p\n", (void *)addr );
}
The output from the code is
0xc03950
0xc03950
0xc03954
0xc03958
0xc0395c
0xc03960
The address advances by 4 bytes as expected. Note that I changed the type of addr to intptr_t to guarantee that the pointer can be cast properly, but that doesn't effect the math in the subsequent two lines.
In your code tests is triple *, remove the additional * from the malloc line and test[0]->id assignments will work.
If you need a high level access to an offset, assign values as you initially wanted to in question 1. IE - tests[0]->id = 0x3834 , or memcpy for dynamic assignments. ThereĀ“s no need for all those references and casts.
Because tests was reassinged in the first line of your iterator.
Thanks to #user3386109 I was able finally to do everything I wanted. Well, instead of writing to address using creepy formula I am now reading from address using the same creepy formula:
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <stdlib.h>
using namespace std;
struct TestCase{
int ida;
int idb;
};
int main()
{
TestCase ** tests; //create pointer to pointer
cout << "Size of TestCase: " << sizeof(TestCase) << endl;
tests = malloc(sizeof(TestCase*)*5);
if(tests == NULL)
exit(1);
for(int i=0; i< 5; i++)
{
tests[i] = malloc(sizeof(struct TestCase));
if(tests[i] == NULL)
exit(1);
}
cout << "*tests = " << *tests << endl;
for(int i = 0; i < 5; i++)
{
tests[i]->ida = i;
tests[i]->idb = i+6;
cout << std::hex << &(tests[i]->idb) << ": " << *(long*)((long)(long*)(tests[i])+(long)&(((TestCase *)NULL)->idb)) << endl;
}
for(int i=0; i<5; i++)
{
free(tests[i]);
}
cout << "*tests = " << *tests << endl;
free(tests);
return 0;
}
Output:
$ ./a.exe
Size of TestCase: 8
*tests = 0x600048630
0x600048634: 6
0x600048654: 7
0x600048674: 8
0x600048694: 9
0x6000486b4: a
*tests = 0x600048630
Related
I keep getting this error when I try to pass this array of structures into the function AthleticContest():
cannot convert 'person' to 'person*'
Can someone please tell me what I am doing wrong? Am I passing the wrong thing into the function?
struct person
{
int athletic;
int smarts;
int spirit;
int contestVal;
};
int AthleticContest(person subjects[])
{
cout << "Athletic Contest!!!" << endl << endl;
for (int hh = 0; hh < 3; hh++)
{
int result = subjects[hh].athletic;
subjects[hh].contestVal = result;
cout << "Contestant # " << (hh+1) << ") " << subjects[hh].contestVal << endl;
}
int winner;
int tempWin = -1;
for (int hh = 0; hh < 3; hh++)
{
if (subjects[hh].contestVal > tempWin)
{
tempWin = subjects[hh].contestVal;
winner = hh;
}
else if (subjects[hh].contestVal == tempWin)
{
if (randomInt() > 4)
winner = hh;
}
}
cout << "Winner is Contestant # " << (winner+1) << endl;
return winner;
}
int main()
{
person subject[10];
subject[0].athletic = 5;
subject[0].smarts = 3;
subject[0].spirit = 1;
subject[1].athletic = 1;
subject[1].smarts = 3;
subject[0].spirit = 5;
subject[1].athletic = 3;
subject[1].smarts = 5;
subject[0].spirit = 1;
AthleticContest(subject[2]);
}
The error
When you call your function in main():
AthleticContest(subject[2]);
you pass as argument a single person, which is the third element of your array (the element with index 2). So the compiler understands that you try to pass this object of type person.
But your function's parameter is declared to be of type array of undetermined size (i.e. person[]). C++ treats such array arguments as if they were a pointer (to their first element), so like person*.
This is why you get this error message: these types are incompatible
The solution
To get rid of this error, a solution would be to pass a pointer to a subject, for example:
AthleticContest(&subject[2]); // passes the pointer to the third element
// or
AthleticContest(subject); // passes the pointer to the first element of the original array
However, be very careful, because your function has a very risky design: you expect the argument to be a pointer to an array of at least 3 consecutive elements. So if you call it with &subject[8], it would try to access subject[10] which would be out of bounds. If you'd call with &subject[2] it would work with garbege information, since you have initalized only the first two elements, and not the 3rd, 4th and 6th.
A better solution
It is not clear, why you do the constest just with 3 elements. A better option would be the caller to say how many contestant shall be used (the caller know the size of the array).
In main():
AthleticContest(subject, 2); // 2 is the number of contestants in array
Your function would be defined as:
int AthleticContest(person subjects[], int participants)
{
cout << "Athletic Contest!!!" << endl << endl;
for (int hh = 0; hh < participants; hh++)
...
for (int hh = 0; hh < participants; hh++)
...
}
A much better solution
You'd better go for std::vector instead of C++ arrays. They can behave like arrays:
vector<person> subject(2); // create a vector of 2 items
subject[0].athletic = 5;
...
But they are much more convenient because they can have a dynamic size and grow as you add new participants:
person hbolt = {4, 2, 1, 0};
subject.emplace_back (hbolt); // one more participant
AthleticContest(subject);
Your function could get the vector by reference or by value. Let's take by reference, since you intend to modify its content and could possibly want this modified data after the return:
int AthleticContest(vector<person> &subjects)
{
...
}
The big advantage, is that you can always know the size of the vector:
for (int hh = 0; hh < subjects.size(); hh++)
...
Here is an online demo.
Of course, if you don't want to take all the participants in the vector, you'd have to think about your function's argument(s): would you prefer a second argument n and always take the n first elements of the vector ? Or would you prefer n participants but start at an arbitrary offset ? In both case, you'd be wise to check that your indexing never goes out of bounds.
One thing you need to change to compile: You're passing a reference to a single element of the array instead of the array itself.
One more thing you might want to check is to change your signature for AthleticContest() so it'll be the right one in C++ to receive fixed-sized array or person as a parameter.
When fixed to compile, and you're code looks like this:
#include <iostream>
using namespace std;
struct person
{
int athletic;
int smarts;
int spirit;
int contestVal;
};
template <std::size_t size>
int AthleticContest(person (&subjects)[size])
{
cout << "Athletic Contest!!!" << endl << endl;
for (int hh = 0; hh < 3; hh++)
{
int result = subjects[hh].athletic;
subjects[hh].contestVal = result;
cout << "Contestant # " << (hh+1) << ") " << subjects[hh].contestVal << endl;
}
int winner;
int tempWin = -1;
for (int hh = 0; hh < 3; hh++)
{
if (subjects[hh].contestVal > tempWin)
{
tempWin = subjects[hh].contestVal;
winner = hh;
}
else if (subjects[hh].contestVal == tempWin)
{
if (5 > 4)
winner = hh;
}
}
cout << "Winner is Contestant # " << (winner+1) << endl;
return winner;
}
int main()
{
person subject[10];
subject[0].athletic = 5;
subject[0].smarts = 3;
subject[0].spirit = 1;
subject[1].athletic = 1;
subject[1].smarts = 3;
subject[0].spirit = 5;
subject[1].athletic = 3;
subject[1].smarts = 5;
subject[0].spirit = 1;
AthleticContest(subject);
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I'm using a library for an Arduino project that has a function I need to call. This function accepts just one parameter of type const char*. Let's call it foo.
I need to pass some int values to foo, so I convert them first using sprintf. So far so good.
The problem comes when I try to fill an array with int values converted to char and then call foo with each of the values in the array.
I hope this explains the problem better:
#include <iostream>
using namespace std;
// This function cannot be modified because
// is a part of a library
void foo(const char *bar){
cout << "Result: " << bar << endl;
}
int main() {
char *values[10]; // My array of values
char tmp[10]; // Temporary buffer for the int > char conversion
for(int i = 0; i < 10; i++){
int samplevalue = i * 2; // Just a sample value, not important
sprintf(tmp, "%d", samplevalue); // Copy the sample value to the temporary buffer
values[i] = tmp; // Assign the value of the temp var to a position in my values array
cout << values[i] << endl;
}
cout << "==============" << endl;
// Here comes the problem:
for(int i = 0; i < 10; i++){
foo(values[i]);
}
return 0;
}
The output of that code is the following:
0
2
4
6
8
10
12
14
16
18
==============
Result: 18
Result: 18
Result: 18
Result: 18
Result: 18
Result: 18
Result: 18
Result: 18
Result: 18
Result: 18
As you can see, all of the Result lines are equal to the last value assigned to the tmp var. I guess it's because each of the values in the values[10] array contains a pointer to the tmp variable instead of its actual value.
What I'd like to have is a different number on each Result line, as in the first for loop.
I guess it's pretty obvious that I'm not even near to be a C++ expert and any help will be highly appreciated.
Thanks!
A char * pointer and an array are not a string. Use std::string instead.
#include <iostream>
using namespace std;
// This function cannot be modified because
// is a part of a library
void foo(const char *bar)
{
cout << "Result: " << bar << endl;
}
int main(void)
{
std::string values[10]; // My array of values
char tmp[10]; // Temporary buffer for the int > char conversion
for (int i = 0; i < 10; i++) {
int samplevalue = i * 2; // Just a sample value, not important
sprintf(tmp, "%d", samplevalue); // Copy the sample value to the temporary buffer
values[i] = tmp; // Assign the value of the temp var to a position in my values array
cout << values[i] << endl;
}
cout << "==============" << endl;
// Here comes the problem:
for (int i = 0; i < 10; i++) {
foo(values[i].c_str());
}
return 0;
}
When using an array, all the pointers in your values array point to tmp, you can check that by looping through values and printing the address like this
fprintf(stdout, "%p\n", values[i]);
So because you sprintf() into tmp all the values, the value that will be printed is always the last one, there is no copy implied in
values[i] = tmp;
that just makes values[i] point to tmp, so when you access values[i] you really access tmp.
With std::string copy occurs.
Also, you should probably use a string stream to write numbers into each values[i] directly, because sprintf() is very dangerous.
Or even better use a real c++ solution like this one,
#include <iostream>
#include <vector>
#include <sstream>
// This function cannot be modified because
// is a part of a library
void foo(const char *bar)
{
std::cout << "Result: " << bar << std::endl;
}
int main(void)
{
std::vector<std::string> values;
for (int i = 0; i < 10; i++) {
values.push_back(std::to_string(2 * i));
std::cout << values[i] << std::endl;
}
std::cout << "==============" << std::endl;
for (size_t i = 0; i < values.size(); i++) {
foo(values[i].c_str());
}
return 0;
}
Note that now, you can change the number of elements in values and you can use it as an array if you need to, just read the documentation for std::vector.
Ok, I finally got to get it working. In Arduino strings are declared as String variable;, and the c_str() function converts a string into a const char *, so I convert the int number to String, and then to const char *:
for(int i = 0; i < 10; i++){
String tmp = String(i * 2);
values[i] = tmp.c_str();
}
And that's it! It works now :)
I'm trying to learn more about malloc() and need help clarifying the output. I want to reserve 10 bytes of memory and be able to access them individually but they must be in one block. Here is the code:
#include<iostream>
using namespace std;
#include<stdio.h>
#include<stdlib.h>
int main()
{
char neededbytes = 10;
char *p;
p = (char *)malloc(neededbytes * sizeof(char));
if(p==NULL)
{
cout<<"Error! memory not allocated.";
exit(0);
}
else
{
for (int i = 0; i < neededbytes; i++)
{
p[i] = 0;
}
for (int i = 0; i < neededbytes; i++)
{
cout<<"Address at index " << i << " is ";
cout<<&p+i<<endl;
}
}
free(p);
}
The output of the program shows that all addresses are 8 bytes apart. Shouldn't they be only one byte apart? Is there a way for me to know if char consumes 8 bytes on my architecture?
&p+i is the same as (&p)+(i), and since p has type char*, &p has type char**. As a result, adding i will actually add i * sizeof(char *) bytes to the address denoted by &p.
What you want is p + i, which will add i * sizeof(char) bytes to the address stored in p. In other words, you already have a pointer to contiguous data when you use malloc(). Of course, this is C++, so char * is handled specially by std::cout, std::cerr, and the std::ostream class in general. You'd need to do something like static_cast<void *>(p + i) rather than just p + i as you would use in C.
As others have stated, you should avoid using malloc() and free() in C++ when possible; C++ has the new[] and delete[] operators for your purpose.
cout<<&p+i<<endl; should just be cout<<static_cast<void*>(p+i)<<endl;
It's because you are using the address of operator, the offset will be i * sizeof(char *) in that case which on your system is apparently 8 * i bytes.
Try this instead
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
int main()
{
char neededbytes = 10;
char *p;
p = static_cast<char *>(malloc(neededbytes));
if (p == NULL)
{
cout << "Error! memory not allocated.";
exit(-1);
}
for (int i = 0; i < neededbytes; i++)
p[i] = 0;
for (int i = 0; i < neededbytes; i++)
{
cout << "Address at index " << i << " is ";
cout << static_cast<void *>(p + i) << endl;
}
free(p);
}
You could look at the byte alignment of char in your compiler output settings but I bet char is always 1 byte. Try a few changes like this (I think you are accessing the wrong array element at &p+i) :
int main()
{
int neededbytes = 10;
char *p=NULL;
p = malloc(neededbytes * sizeof(char));
if(p==NULL)
{
cout<<"Error! memory not allocated.";
exit(0);
}
else
{
for (int i = 0; i < neededbytes; i++)
{
p[i] = 0;
}
for (int i = 0; i < neededbytes; i++)
{
cout<<"Address at index " << i << " is ";
// Dave cout<<p+i<<endl;
cout<<&(p+i)<<endl;
}
}
free(p);
}
NB: Dave shared the correct syntax of p+i. Thanks Dave
Change cout<<&p+i<<endl; to cout<<static_cast<void*>(p+i)<<endl;.
Here's a site that talks about memory alignment on GNU systems. It will always be 8(16 for 64 bit systems) byte aligned. There are some libc (stdlib.h) functions that can force alignment for you listed there though.
http://www.gnu.org/software/libc/manual/html_node/Aligned-Memory-Blocks.html
I have a nested boost::shared_ptr which was occasionally getting destroyed when getting assigned to another one and going out of scope. I figured out that the use_count was not updating unless I copy the pointer to a temp. The code is self-explanatory. In the first for-loop, the use_count doesn't update, whereas it updates on the other.
#include <vector>
#include <boost/shared_ptr.hpp>
#include <iostream>
using namespace std;
int main(int argc, char const *argv[])
{
typedef int T;
typedef std::vector<T> content_1d_t;
typedef boost::shared_ptr<content_1d_t> storage_1d_t;
typedef std::vector<storage_1d_t> content_2d_t;
typedef boost::shared_ptr<content_2d_t> storage_2d_t;
int dim1 = 10;
int dim2 = 1;
content_2d_t* content_1 = new content_2d_t();
content_1->reserve(dim2);
storage_2d_t storage_1(content_1);
for (int i = 0; i < dim2; ++i)
{
storage_1->push_back(storage_1d_t(new content_1d_t(dim1)));
}
//content_2d_t* content_2 = new content_2d_t(dim2);
storage_2d_t storage_2 = storage_1;
for (int i = 0; i < dim2; ++i)
{
cout<< "use count before : "<< storage_1->operator[](i).use_count()<<endl;
storage_2->operator[](i) = storage_1->operator[](i);
cout<< "use count after: "<< storage_1->operator[](i).use_count()<<endl;
}
for (int i = 0; i < dim2; ++i)
{
cout<< "use count before : "<< storage_1->operator[](i).use_count()<<endl;
storage_1d_t ref = storage_1->operator[](i);
storage_2->operator[](i) = ref;
cout<< "use count after: "<< storage_1->operator[](i).use_count()<<endl;
}
/* code */
return 0;
}
output
use count before : 1
use count after: 1
use count before : 1
use count after: 2
Since you do storage_2d_t storage_2 = storage_1; obviously, assigning the elements directly back onto themselves should not increase use counts.
I the second loop you print the use count during the time where you hold the temporary copy (ref). Making it explicit, you can see that indeed - as expected - the "after" count is not actually higher:
for (int i = 0; i < dim2; ++i) {
cout << "use count before : " << (*storage_1)[i].use_count() << endl;
{
storage_1d_t ref = (*storage_1)[i];
(*storage_2)[i] = ref;
cout << "use count during: " << (*storage_1)[i].use_count() << endl;
}
cout << "use count after: " << (*storage_1)[i].use_count() << endl;
}
Now prints
use count before : 1
use count during: 2
use count after: 1
See it Live On Coliru
Brainwave Did you mean to deep-clone storage_1 into storage_2? It appears you have been confused by the fact that your outer storage_2d_t is also a shared pointer and hence you refer to the same vector by reference.
storage_2d_t storage_2 = boost::make_shared<content_2d_t>(*storage_1);
// or
storage_2d_t storage_2 = boost::make_shared<content_2d_t>(storage_1->begin(), storage_1->end());
VISUAL C++ Question
Hi,
I have array of 3 elements and I want to shift its elements to the right and replace the shifted index cell with "SHIFTED" string and this should loop until all the cells has "SHIFTED" string.
For example:
int a[x]={0,1,2};
Initial index and elements Order:
[0]=0
[1]=1
[2]=2
should become in the:
1st loop:
[0]=SHIFTED
[1]=0
[2]=1
2nd Loop:
[0]=SHIFTED
[1]=SHIFTED
[2]=0
3rd Loop:
[0]=SHIFTED
[1]=SHIFTED
[2]=SHIFTED
I know I can do that with memmove() but I don't want to use any function in it.
Would you please help me; here is my work:
#include <iostream>
#include <string>
#include <stdio.h>
#include <cstdlib>
using namespace std;
int const ARRAY_SIZE=3;
int main()
{
int Array[ARRAY_SIZE];
int iniPostion,newPostion;
string x="SHIFTED";
for(iniPostion=0; iniPostion<ARRAY_SIZE; iniPostion++)
{
Array[iniPostion] = iniPostion;
cout << "Cell [" << iniPostion << "] Initial Element is: (" << Array[iniPostion] << ")" << endl;
}
cout << endl;
for(newPostion=0; newPostion<ARRAY_SIZE; newPostion++)
{
Array[newPostion]=newPostion;
cout << "Cell [" << newPostion << "] New Element is: (";
if(Array[newPostion-1]<0)
{
cout << x << ")\n";
}
else
{
cout << Array[newPostion-1] << ")" << endl;
}
}
return 0;
}
As Peter mentioned in his answer, you cannot assign a string to a int. I've assumed SHIFTED to be -1. So every time you shift you bring in a -1 in the gap created.
You need two loops. The outer loops iterates N (3) times and inner loop starts at the end of the array and copies (n-1)th element to nth position:
for(int count = 0;count < N;count++){
for(newPostion=ARRAY_SIZE-1; newPostion > count;newPostion--)
Array[newPostion]=Array[newPostion - 1]; // copy
Array[newPostion]= -1; // fill the gap.
// print.
for(iniPostion=0; iniPostion<ARRAY_SIZE; iniPostion++) {
cout << "Cell [" << iniPostion << "] Initial Element is: (" << Array[iniPostion] << ")" << endl;
}
cout<<endl;
}
Sample run:
# g++ a.cpp && ./a.out
Cell [0] Initial Element is: (0)
Cell [1] Initial Element is: (1)
Cell [2] Initial Element is: (2)
Cell [0] Initial Element is: (-1)
Cell [1] Initial Element is: (0)
Cell [2] Initial Element is: (1)
Cell [0] Initial Element is: (-1)
Cell [1] Initial Element is: (-1)
Cell [2] Initial Element is: (0)
Cell [0] Initial Element is: (-1)
Cell [1] Initial Element is: (-1)
Cell [2] Initial Element is: (-1)
It is a bit unclear, how you can expect to have string ("SHIFTED") in an array of integers.
However, for this operation you can use the rotate algorithm:
#include <iostream>
#include <algorithm>
#include <string>
int const ARRAY_SIZE=3;
void print(std::string* array) {
for (int i = 0; i != ARRAY_SIZE; ++i) {
std::cout << array[i] << ' ';
}
std::cout << '\n';
}
int main()
{
std::string Array[ARRAY_SIZE] = {"0", "1", "2"};
print(Array);
//the last item ends up at the beginning of the array
std::rotate(Array, Array + ARRAY_SIZE - 1, Array + ARRAY_SIZE);
//now overwrite the item that used to be last
Array[0] = "SHIFTED";
print(Array);
return 0;
}
It would probably be simpler and more efficient with a suitable container, such as std::deque or std::list where you could pop_back the last value and push_front the new value.
I have array of 3 elements and I want to shift its elements to the right and replace the shifted index cell with "SHIFTED" string and this should loop until all the cells has "SHIFTED" string.
This doesn't make sense at all. You have an array of numbers (integers), which of course can't contain a string. What you can do is e.g. inserting 0 or -1 to denote the shifted element.
The shifting itself can be easily implemented through a std::rotate operation.
But since all elements contain the same thing in the end, why don't you just assign them directly without all the shifting?
Here is my simple solution in plain old C
#include <stdio.h>
#include <stdlib.h>
void main(int argc, char **argv) {
int MAX_LEN = 11;
int numOfShifts = 1;
if ( argc > 1 ) {
numOfShifts = atoi(argv[1]);
}
printf("Number of shifts = %d\n",numOfShifts);
int arr[] = { 0,1,2,3,4,5,6,7,8,9,10 };
int i;
int n; // number of shifts index
for ( n = 0; n < numOfShifts; n++ ) {
for ( i = MAX_LEN - 1; i >= 0; i-- ) {
if ( i == 0 ) {
arr[i] = -1;
} else {
arr[i] = arr[i-1];
}
}
}
// output
for( i = 0; i < MAX_LEN; i++ ) {
printf("Arr[%d] = %d\n", i, arr[i]);
}
}
This reeks of homework...
Is there a reason you can't just keep track of how many shifts you've done and just take that into account when you print?
#include <iostream>
int const ARRAY_SIZE=3;
class Shifter
{
public:
Shifter(const int* array_, size_t size_)
: array(array_), size(size_), shifts(0) {}
void Shift(size_t steps = 1) { shifts += steps; if(shifts > size) shifts = size; }
void Print(std::ostream& os) const;
private:
const int* array;
size_t size;
size_t shifts;
};
void Shifter::Print(std::ostream& os) const
{
for(size_t i = 0; i < size; ++i)
{
os << "Cell [" << i << "] = ";
if(i < shifts)
os << "SHIFTED";
else
os << array[i - shifts];
os << std::endl;
}
}
std::ostream& operator <<(std::ostream& os, const Shifter& sh)
{
sh.Print(os);
return os;
}
int main(void)
{
// Initialize the array.
int a[ARRAY_SIZE];
for(size_t iniPostion=0; iniPostion < ARRAY_SIZE; iniPostion++)
a[iniPostion] = iniPostion;
Shifter sh(a, ARRAY_SIZE);
std::cout << "Initial contents:" << std::endl;
std::cout << sh << std::endl;
// Do the shifts.
for(size_t newPostion = 0; newPostion < ARRAY_SIZE; newPostion++)
{
std::cout << "Shift by 1..." << std::endl;
sh.Shift();
std::cout << sh << std::endl;
}
return 0;
}
You can simple move memory.
// shift down
int a[ 10 ];
memmove( a, a +1, sizeof( a ) -sizeof( a[ 0 ] ) );