2016-12-28 1 views
-1

У меня проблема, я не могу понять. Я написал этот код, чтобы перетасовать элементы массива:Нулевой указатель, использующий const вместо объявления переменной

#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 

const char *array[]={"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"}; 

int main(int argc, char **argv) 
{ 
int i, tmp, randomize, size; 

size = sizeof(array)/sizeof(*array); 

srand(time(NULL)); 

for(i=size;i>0;i--){ 
    randomize=0+(rand()%size); 
    tmp=(int)array[i]; 
    array[i]=array[randomize]; 
    array[randomize]=(char*)tmp; 
} 

for(i=0;i<size;i++) 
    printf("%s", array[i]); 
    return 0; 
} 

Когда я запускаю программу, это iutput:

azlngiwexbv(null)uscphqjyrodmtk 

Я не могу понять, почему указатель иногда утратившим я не могут понять, почему, изменяя исходный код таким образом:

#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 

int main(int argc, char **argv) 
{ 
char *array[]={"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"}; 
int i, tmp, randomize, size; 

size = sizeof(array)/sizeof(*array); 

srand(time(NULL)); 

for(i=size;i>0;i--){ 
    randomize=0+(rand()%size); 
    tmp=(int)array[i]; 
    array[i]=array[randomize]; 
    array[randomize]=(char*)tmp; 
} 

for(i=0;i<size;i++) 
    printf("%s", array[i]);  
return 0; 
} 

Все работает нормально. Спасибо.

+2

'tmp = (int) array [i];' ... why? –

+0

Чтобы избежать этого предупреждения: –

+0

предупреждение: присваивание делает целое число из указателя без литого [-Wint-conversion] tmp = array [i]; ^ –

ответ

3

Начать цикл от size-1, вы указываете массив в array[size] (первая итерация цикла).

for (i=size-1; i>=0; i--) 
+0

Из массива, выбирающего нулевой символ завершения, который объясняет вывод нулевого символа –

+1

@ Jean-FrançoisFabre нет, совсем нет.Даже если 'array' был nul-terminated (это не так), нуль все равно будет находиться в пределах его границ. Это просто UB. – Quentin

+0

pbn, ваше предложение работает, спасибо. Но я до сих пор не понимаю, почему, объявив переменную char * array в основной функции, программа работает: - \ –

0

Вам следует избегать кастинга, когда это возможно, и это редко бывает необходимо.

Если вы планируете использовать argc и argv[], используйте простую форму для main(): int main(void). Это приведет к удалению некоторых предупреждений компилятора, и вы должны включить их; удалите все предупреждения, выпущенные вашим компилятором.

Вы бросили указатель char на int хранить его в tmp, а затем бросили tmp обратно (char *). Просто объявите tmp как указатель на char для начала. Первый цикл отсчитывается от size до 0; это за пределами массива, чтобы начать, но почему бы просто не использовать обычную конструкцию цикла: for (i = 0; i < size; i++)? Кроме того, вам следует использовать size_t для индексов массива; это целочисленный тип без знака, гарантирующий возможность хранения любого индекса массива, а также тип, возвращаемый оператором sizeof.

Кроме того, в вашей первой версии вы указали array как массив указателей на const char. Вы можете это сделать, но вам нужна переменная временного хранения tmp, чтобы согласиться с классификатором const.

Вот ваш код с вышеуказанными изменениями. Нет отливок, он компилируется без предупреждений, и он работает.

#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 

int main(void) 
{ 
    const char *array[] = {"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"}; 

    const char *tmp; 
    size_t i, size; 
    int randomize; 

    size = sizeof(array)/sizeof(*array); 

    srand(time(NULL)); 

    for(i = 0; i < size; i++){ 
     randomize = (rand() % size); 
     tmp = array[i]; 
     array[i] = array[randomize]; 
     array[randomize] = tmp; 
    } 

    for(i = 0; i < size; i++) 
     printf("%s", array[i]); 
    putchar('\n'); 

    return 0; 
} 
Смежные вопросы