Join 136,179 C++ Programmers for FREE! Get instant access to thousands of C++ experts, tutorials, code snippets, and more! There are 2,012 people online right now. Registration is fast and FREE... Join Now!
Alright, this is the code (just skip it, I'll make it simpler under it):
CODE
#include <iostream> using namespace std;
int b[30000][2], br, n; void rek(int x, int a[30000][2]) { int prom; prom = x; for (int i = 0; i < n; i++) cout << a[i][0] << " " << a[i][1] << endl; cout << endl; while (1) { a[prom][1]++; if (a[prom][1] == 2) { br++; b[prom][1]++; } else if (a[prom][1] > 2 || b[prom][1]) { if (x+1 < n) rek(x+1, a); return; } prom = a[prom][0]-1; } } int main() { int a[30000][2] = {0}; br = 0; cin >> n; for (int i = 0; i < n; i++) { cin >> a[i][0]; b[i][0] = a[i][0]; b[i][1] = 0; } int x = 0; rek (x, a); cout << br << endl; system ("Pause"); return 0; }
All I want is that array a[30000][2] comes UNCHANGED after rek() function. I thought it would work on this way, but it doesn't. Can I make it somehow work? Maybe with pointers?
arrays ARE pointers... at least very close to them. The syntax a[x] <==> *(a+x).
If you want to pass an array to a function but not change the original array then you will have to allocate an array local to the function, copy the data (use memcpy for speed) and then manipulate the new array in the function.
CODE
int func(int *arrayIn) { int newArray[30000][2]; if (memcpy(newArray, arrayIn, sizeof(int) * 2 * 30000)) { // use the new array } else { // something went wrong in the copy... } return; }
I edited a code a bit: instead of rek(x+1, a); it's rek(x+1, *a);
and instead of void rek(int x, int a[30000][2]) {
it's void rek(int x, int *ar) { int a[30000][2]; memcpy(a, ar, sizeof(int)*(n+1)*2);
...and now it looks like this, but the effect is the same:
CODE
#include <iostream> using namespace std;
int b[30000][2], br, n; void rek(int x, int *ar) { int a[30000][2]; memcpy(a, ar, sizeof(int)*(n+1)*2); int prom; prom = x; for (int i = 0; i < n; i++) cout << a[i][0] << " " << a[i][1] << endl; cout << endl; while (1) { a[prom][1]++; if (a[prom][1] == 2) { br++; b[prom][1]++; } else if (a[prom][1] > 2 || b[prom][1]) { if (x+1 < n) rek(x+1, *a); return; } prom = a[prom][0]-1; } } int main() { int a[30000][2] = {0}; br = 0; cin >> n; for (int i = 0; i < n; i++) { cin >> a[i][0]; b[i][0] = a[i][0]; b[i][1] = 0; } int x = 0; rek (x, *a);
cout << br << endl; system ("Pause"); return 0; }
The problem in short is this: In array of n numbers, where number in line 2 represents number 1 (in first line is n), and number in i+1 line represents number i, find how many numbers are closed in circles.
Example: 6 - this is n
3 6 2 4 1 3
Number 5 points to number 1, number 1 to 3, number 3 to number 2, number 2 to number 6, number 6 to number 3, number 3 to number 2...
This means numbers 5 and 1 are not in the circle, but 2, 6 and 3 are. (also number 4 points to itself, so the solution is 4 numbers).
EDIT: The problem is that I have 0.1 second time limit (of execution of the code), so I can't put array a[30000][2] to 0 with for loop each time.
This post has been edited by Unknown Hero: 4 Sep, 2007 - 07:11 PM
Just to be clear about something said earlier - arrays aren't the same thing as pointers, but their syntax is equivalent. (Much is explained in this section of the C FAQ) http://c-faq.com/aryptr/index.html
In general, if you want to create a copy of an array, then you can either copy it in a loop, or you can wrap the array in a struct, and pass the struct (Which will be copied)
CODE
struct array_wrapper { int arr[30000][2]; };
void rek( array_wrapper a );
Though, much of the time, copying an array just for a function call is unnecessary. (especially with a large array like that, its alot of overhead every time the function is called) Out of interest, what reason exactly requires the entire array to be copied?
This post has been edited by Bench: 5 Sep, 2007 - 03:53 AM
The first big difference is how pointers are accessed in memory, it may surprise you that pointer accesses are wildly different from array accesses. Take the following code for example:
#include <stdio.h> #include <stdlib.h>
int main(void) { int a[1]; int *b = malloc(1 * sizeof * ;
a[0] = 1; b[0] = 1;
return(0); }
If you take the time to look at the assembler output for the lines that assign 1 to a[0] and b[0] then you might be surprised to see something like this:
Sparing you the gory details of assembler language, the array access simply moves directly to the location in memory referenced by a[0] and places the value 1 there, there are no other signifigant operations. The pointer access, however, is more complicated. The address of the pointer is first accessed and the contents read, in this case, the content is the address of the memory being pointed to. Next, the value of the subscript, 0 in this case, is added to the memory address just acquired from the pointer, only then is the memory referenced by b[0] accessed. The obvious conclusion is that arrays and pointers are not equivalent in this case.
The Author isn't quite right. The difference that he has mentioned depends more on Compiler Optimization. There is no hard and fast rule about how Arrays are to be implemented at Runtime (although there are guidelines). mov dword ptr [ebp-8] , 1 and mov eax,dword ptr [ebp-4] + mov dword ptr [eax],1 are both valid instructions and any compiler could use these if it wanted to. Each Compiler will have a different method of implementing arrays and pointers. Even changing Compiler Optimizations result in variations in code.
On one optimization level, assignment is done using the exact same instructions as that for the pointer, while on another the LEA instruction is used (which is really smart as it can perform addition and retrieve the element's address in just one instruction. You guessed it, Full optimization)
But the fact still remains that Pointers aren't Arrays. This isn't exactly the right way to prove it.
Bench's Link explains the differences in a lot more detail.