Другие люди более или менее ответили на вопрос, поэтому я собираюсь сделать что-то немного другое: я собираюсь вставить здесь полный пересмотр вашей программы. Я исправил ошибку, о которой вы спрашивали, но также внес много других изменений. Я хочу, чтобы вы внимательно прочитали пересмотренную программу и подумали о , почему я изменил некоторые вещи.
// Note: This program uses C99 features; must be compiled with e.g.
// -std=c99 (for GCC). Nonetheless it is C, not C++.
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
static void
printdigits(const int num[], int top)
{
for (int i = top - 1; i >= 0; i--) {
assert(0 <= num[i] && num[i] < 10);
putchar('0' + num[i]);
}
putchar('\n');
}
int
main(int argc, char **argv)
{
if (argc != 2) {
fprintf(stderr, "usage: %s n\ncomputes 2^n\n", argv[0]);
return 1;
}
char *eptr;
long n = strtol(argv[1], &eptr, 10);
if (eptr == argv[1] || *eptr != '\0') {
fprintf(stderr, "%s: '%s' is not a number\n", argv[0], argv[1]);
return 1;
}
if (n < 1) {
fputs("n must be at least 1\n", stderr);
return 1;
}
unsigned int num[n]; // could be short or even char, but memory is not tight
int top = 1;
num[0] = 2;
for (int i = 1; i < n; i++) {
int carry = 0;
for (int j = 0; j < top; j++) {
num[j] = num[j] * 2 + carry;
carry = 0;
if (num[j] >= 10) {
assert(num[j] < 20); // largest possible is 2*9+1 = 19
carry = 1;
num[j] -= 10;
if (j+1 >= top) {
assert(top < n);
num[j+1] = carry;
top++;
break;
}
}
}
#ifndef NDEBUG
printf("Iteration %d: top=%d num=", i, top);
printdigits(num, top);
#endif
}
#ifndef NDEBUG
putchar('\n');
#endif
printdigits(num, top);
return 0;
}