2016-11-02 1 views
-1

Ich habe versucht zu lösen Projekt Euler Frage 16 mit c. Ich habe keine Bignnum-Bibliotheken verwendet. Die Frage fragt 2^1000. Ich beschloss, jede Ziffer dieser Zahl in einem Array zu speichern.Zugriffsverletzung in C-Programm mit Zeigervariable?

Beispiel: 45 means arr[0]=4, arr[1]=5;

Das Problem ist, ich auf jeden Fall die Funktion int multi.

#include<stdio.h> 

#include<conio.h> 
int multi(int *base, int k);// does the multiplication of array term by 2 
void switcher();//switches every term when the fore mostvalue is >10 
int finder();// finds the array address of last value 
int arr[1000]; 
int summer();//sums all values of the array  

int main() 
{ 
    arr[1000] = { 0 }; 
    arr[0] = 1; 

    int i, j, sum, k, p; 

    for (i = 0; i < 1000; i++) 
    { 
     j = 0; 
     k = finder(); 
     p = multi(arr + k, j); 
    } 
    sum = summer(); 
    printf("sum of digits of 2^1000 is %d", sum); 
    _getch();  
} 
int multi(int *base, int k) 
{  
    int p; 
    if (base == arr) 
    { 
     *base = *base - 1; 
     *base = *base + k; 
     if (*base > 10) 
     { 
      *base = *base - 10; 
      switcher(); 
     } 
     return 0; 
    } 
    *base = *base * 2; 
    *base = *base + k; 
    if (*base > 10) 
    { 
     *base = *base - 10; 
     p = multi(base - 1, 1); 
    } 
    else 
    { 
     p = multi(base - 1, 0); 
    }  
} 
void switcher() 
{ 
    int j; 

    for (j = 0;; j++) 
    { 
     if (arr[j] == 0) 
     { 
      break; 
     } 
    } 
    j--; 
    for (; j > 0; j--) 
    { 
     arr[j + 1] = arr[j]; 
    } 
    arr[0] = 1; 
} 
int finder() 
{ 
    int j; 
    for (j = 0;; j++) 
    { 
     if (arr[j] == 0) 
     { 
      break; 
     } 
    } 
    return --j; 
}  

int summer() 
{ 
    int summ, i; 
    summ = 0; 
    for (i = 0; i<1000; i++) 
    { 
     summ = summ + arr[i]; 
     if (arr[i] == 0) 
      break; 
    } 
    return summ;  
} 

Es kompiliert, aber während der Laufzeit zeigt es Verletzung Zugriff schreib-, Basis war ......

erklären Sie diesen Fehler und wie es zu lösen?

+0

Ihr Array von 100 bemessen ist, aber du bist Looping in irgendeiner Funktion bis 1000 ... –

+0

Das sollte in Ordnung, da 2^1000 weniger als 100 Ziffern ist – Sashurocks

+3

2^1000 hat 302 Dezimalziffern. Und der letzte gültige Index eines Arrays mit K Elementen ist K - 1. ('arr [100] = {0};' weist null dem nicht existierenden hundertsten Element zu, füllt das Array nicht mit Null.) – molbdnilo

Antwort

0

Das Array hat 100 Bytes, aber Sie laufen für 1000. Auch in der Funktion Finder() haben Sie kein Limit für die Variable j, so dass Ihre Array-Größe 100 Bytes überschreitet.

Auch verwenden Memset Array-Variablen auf 0

+0

änderte es auf 1000; funktioniert immer noch nicht – Sashurocks

+0

, weil Sie das Array nicht initialisiert haben –

0

Wie gesagt in den Kommentaren zuweisen, 2^1000 has Dezimalziffern.
Sie gehen weit außerhalb Ihres Arrays.

Aber Ihr Code ist sehr kompliziert, weil Sie die Ziffern mit dem wichtigsten zuerst speichern.
Da Sie nur an den Ziffern interessiert sind und nicht an der Reihenfolge, in der sie geschrieben würden, können Sie die Nummer "in umgekehrter Reihenfolge" speichern, wobei die niedrigstwertige Ziffer zuerst angezeigt wird.
Dies macht den Code viel einfacher, da Sie "vorwärts" loopen können und Array-Elemente nicht mehr mischen müssen.

Mit -1 als „Ende der Reihe“ Marker, könnte es so aussehen:

void twice(int* digits) 
{ 
    int i = 0; 
    int carry = 0; 
    while (digits[i] >= 0) 
    { 
     digits[i] *= 2; 
     digits[i] += carry; 
     if (digits[i] >= 10) 
     { 
      carry = 1; 
      digits[i] -= 10; 
     } 
     else 
     { 
      carry = 0; 
     } 
     i++; 
    } 
    if (carry) 
    { 
     digits[i] = 1; 
     digits[i+1] = -1; 
    } 
} 

int main() 
{ 
    int digits[302] = {1, -1}; /* Start with 1 */ 
    twice(digits);   /* digits is now { 2, -1 } */ 
    return 0; 
}