2015-12-13 2 views
0

Я относительно новичок в C и не могу понять, что не так с кодом?Правильный способ передачи массива в функцию?

Во время компиляции я получаю 2 предупреждения и ошибку дампа ошибки сегментации во время выполнения. Может ли кто-нибудь объяснить, почему? Я запускаю Ubuntu как виртуальную машину. И это правильный способ объявить/передать массив в функцию?

#include <stdio.h> 

//Loop handlers 
int i, j, m, n; 
int c; 
int cap[26]; 


//Funtions prototype 
void countingChars(void); 
void vertcalHistogram(int [], int size); //Warning: expected ‘int *’ but argument is of type ‘int’ (helloworld) 
void dashes(void); 

int main (void) 
{ 
    countingChars(); 
    vertcalHistogram(cap[26], 26); //Warning: passing argument 1 of ‘vertcalHistogram’ makes pointer from integer without a cast [enabled by default] (helloworld) 
    //dashes(); 
    getchar(); 
    return 0; 
} 

void countingChars(void) 
{ 
    while((c = getchar()) != EOF) 
    { 
     if(c >= 65 && c <= 90) 
      ++cap[c - 65]; 

     if(c >= 97 && c <= 122) 
      ++cap[c - 97]; 

     for(i = 0; i < 26; i++) 
      printf("%d", cap[i]); 
     printf("\n"); 

    } 
} 
void dashes(void) 
{ 
    printf("\n"); 
    printf("\n"); 

    for(i = 0; i < 40; i++) 
     printf("_"); 

    printf("\n"); 

    for(i = 0; i < 40; i++) 
     printf("_"); 

} 

void vertcalHistogram(int cap[], int size) 
{ 
    for(i = 0; i < size; i++) 
    { 
     printf("||"); 
     for(j = 0; j < cap[i]; j++) 
      printf("*"); 
     printf(" ~~ %d", cap[i]); 
     printf("\n"); 
    } 
} 
+1

Прежде всего прекратить использование [количество магии] (https://en.wikipedia.org/wiki/Magic_number_%28programming%29). Затем узнайте о ['isalpha'] (http://en.cppreference.com/w/c/string/byte/isalpha) и [других связанных функциях] (http://en.cppreference.com/w/c/ строка/байт # Character_classification). –

+1

Если вы получаете предупреждения о компиляции, вы должны показать их (желательно, когда их генерирует компилятор). Вы должны использовать локальные переменные, а не глобальные, по крайней мере для 'i',' j', 'm',' n' и 'c' - я не изучил' cap'. Однобуквенные глобальные переменные почти неизбежно поддельны. Глобальная переменная должна иметь значащее имя (оно используется во многих местах), и вы не можете справиться с этим в одной букве. –

+1

'vertcalHistogram (cap [26], 26);' - вы передаете элемент за пределами массива в виде массива. Неправильно. Вам нужна 'vertcalHistogram (cap, 26);'. Это объясняет предупреждения компиляции и дамп ядра. Передача произвольного, неопределенного (но возможно, нулевого) целого числа в качестве указателя приведет к сбоям. Прислушайтесь к компилятору; исправьте предупреждения перед запуском кода. –

ответ

2

cap[26] является 27-й элемент cap, и так как cap[] является массивом int, 27-й элемент типа int. Вам необходимо пройти cap, а не cap[26].


Кроме того, вы могли бы сделать себе большую пользу для того, чтобы «рассматривать все предупреждения как ошибки» вариант вашего компилятора, чтобы даже не попробовать запустить программу, если вы получите предупреждение.

Кроме того, попробуйте это: #define COUNTOF(x) (sizeof(x)/sizeof((x)[0])) так, то вы можете вызвать вашу функцию как это: vertcalHistogram(cap, COUNTOF(cap));

1

Правильный путь, чтобы передать адрес самого или адрес первого элемента массива:

vertcalHistogram(cap, 26); 

или

vertcalHistogram(&cap[0], 26); 

Но это не представляется необходимым си nce cap - глобальная переменная в вашем коде.

cap[26] находится за пределами массива. Помните, что индексирование C начинается с 0. Итак, для массива размером 26, 0 - 25 - допустимый диапазон индексов.

+0

Лучше избегать глобалов; функция 'vertcalHistogram()' может использоваться более широко, поскольку она принимает массив как аргумент, а не полагается на глобальный. Остальная часть кода должна быть де-глобализирована. –

1

cap[26] означает int по индексу 26 в массиве cap.

Если вы хотите передать cap, написать cap:

verticalHistogram(cap, 26); 
0

cap[26] 1 элемент прошел последний элемент массива charcap[]. Исходный код передает char, а не массив. Конечно, не то, что предназначено.

void vertcalHistogram(int [], int size); 
int cap[26]; 
... 
vertcalHistogram(cap[26], 26); // bad 
... 
void vertcalHistogram(int cap2[], int size) // Changed name for clarity 

В C массивы не действительно передаются функции.

Деталь: Вместо этого используйте следующее. Массив cap является формальным параметром до vertcalHistogram(). C не передает массивы, вместо этого он преобразует массив в адрес и тип первого элемента. Этот фактический параметр передается функции. Функция получает адрес cap2[].

vertcalHistogram(cap, 26); // good 
Смежные вопросы