2013-06-17 3 views
1

Новое на C и этом сайте. Я пытаюсь случайным образом выбрать имя в массиве массивов в функции. Затем вернитесь, что случайное имя основной, где я могу использовать его:Возврат случайного имени от функции к основному

#include <stdio.h> 
#include <time.h>  // For rand function 

int random_number(int, int); 

char * random_name(char *); 

int main(void) 
{ 
char * main_pointer; 

printf("\nIn main:\nmain_pointer = %s\n", main_pointer); 

return 0; 
} 
char * random_name(char * MAIN_POINTER) 
{ 
int x = random_number(0,7); 

char random[7][5] = 
{"0Sam", "1Sam", "3Sam", "4Sam", "5Sam", "6Sam", "7Sam"}; 

MAIN_POINTER = &random[x][0]; 

printf("In the function:\nrandom = %s\nMAIN_POINTER = %s\n", (&random[x][0]), MAIN_POINTER); 

return MAIN_POINTER; 

} 
int random_number(int min, int max) 
{ 
int roll; 
int maximum = max - min; 

srand(time(NULL)); 
roll = (rand() % maximum) + min; 
return roll; 
} 

Пример запуска:

In the function: 
random = 0Sam 
MAIN_POINTER = 0Sam 

In main: 
main_pointer = Ø'Þ¿¦¼i· 

Как вы можете видеть, что это становится мусором.

+4

Ваш код не вызывает вашу функцию в 'main', так что вам нужно исправить код, чтобы соответствовать выходной. – Gabe

ответ

2

исправить как этот

#include <stdlib.h> 
int random_number(int, int); 
const char *random_name(void); 

int main(void){ 
    const char * main_pointer; 

    main_pointer = random_name(); 
    printf("\nIn main:\nmain_pointer = %s\n", main_pointer); 

    return 0; 
} 
const char *random_name(void){ 
    int x = random_number(0,7); 
    const char *random[7] = 
     {"0Sam", "1Sam", "3Sam", "4Sam", "5Sam", "6Sam", "7Sam"}; 

    return random[x]; 
} 
+0

Спасибо, синепикс, ты гений. Этот код работает и делает то, что я хочу! – Samuel

3

Вы никогда не устанавливаете значение для main_pointer в функции main(), оно просто имеет адрес мусора.

+3

Isaach это первая ошибка :, следующая ошибка будет * «MAIN_POINTER указывает на локальный объект и случайный [x] [0]; объем и случайность случайного [] [] массива находится в функции random_name(), и вы возвращаете адрес локального объекта, который является незаконным. "* (включить это также тогда код будет исправлен) –

4

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

char * main_pointer; 

Это всегда плохая вещь, чтобы сделать, это оставляет «main_pointer», как неинициализированным. Ваш компилятор должен был сказать вам это.

test.c: In function ‘main’: test.c:12:7: warning: ‘main_pointer’ is used uninitialized in this function [-Wuninitialized]

Если вы используете GCC, а затем добавить опцию компилятора «-Wall», чтобы получить более диагностический выход, и всегда пытаются присвоить значение по умолчанию для ваших переменных, например

char * main_pointer = NULL; 

Следующая проблема:

char * random_name(char * MAIN_POINTER) 
.... 
MAIN_POINTER = &random[x][0]; 

Хотя это законно, я не думаю, что это то, что вы ожидаете. Когда вы передаете указатели как аргументы функции, подобные этому, адрес указатель указывает на переданный и хранится в новой переменной указателя. Любые внесенные изменения сделаны в эту новую копию, и когда функция возвращается, они теряются.

char* test(char* in) 
{ 
    in = in + 1; 
    return in + 10; 
} 

.... 
    char* p = (char*)1000; // 'p' now points to memory location 1000. 
    char* q = test(p); 
    printf("p = %p, q = %q\n", p, q); 

Напечатает:

1000 1011

По существу, указатели работают так же, как переменные, в данном случае «в» была инициализирована в то же значение, как «р», адрес «1000», когда мы добавлено 1 к нему, была изменена только приватная переменная «in».

Единственная особенность указателя заключается в том, что вы можете «разыменовать» его. Если вы хотите вашу функцию «random_name», чтобы иметь возможность изменить указатель main_pointer, вам нужно будет передать адрес указателя и разыменования, что:

void random_name(char** main_pointer) // address of the pointer 
{ 
    ... 
    (*main_pointer) = random[x]; 
} 

Поскольку вызов random_name отсутствует из вашего кода, я не могу сказать, если вы ожидали получить это следующим образом:

main_pointer = random_name(main_pointer); 

не кажется, как много точки передавая ее функции в этом случае, так как вы никогда не использовать его.

Еще одна проблема, с которой ваш код столкнется, заключается в том, что вы пытаетесь использовать указатель на данные для подъема из области действия функции над чем-то над ней в стеке. Это опасно. Если вам нужны данные для сохранения или видимости вне функции, ее необходимо либо объявить в глобальной области, либо задать атрибут «статический».

const char* random_names[] = { "0Sam", "1Sam", "2Sam", ... }; 

// or 

void random_name(const char** main_pointer) 
{ 
    size_t x = random(0, 7); 
    static const char* random_names[] = { "0Sam", "1Sam", "2Sam", ... }; 
    (*main_pointer) = random_names[x]; 
} 
0

Переменная случайным образом [7] [5] является локальной по отношению к функции random_name. Переменная будет истекать/не доступен, как только функция возвращает ..

В вашем случае, возвращающая указатель на переменную случайного приведет к непредсказуемому поведению

Solution:

1) Перемещение переменной random в глобальный 2) Перемещение переменной random в основную функцию и передачу переменной в качестве аргумента

1

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

Правильный ход код:

#include "stdio.h"

#include "stdlib.h"

#include "string.h"

#include «время. h "// Для функции rand

int random_number (int, int);

char * random_name (char *);

INT Основной (недействительными)

{

char * main_pointer=NULL; /*Uni:Initialize this pointer to NULL*/ 

    /*Uni: You have still not allocated any memory/storage for main_pointer 
     and the main_pointer basically points NOWHERE at this point,so 
     printing its value doesnot make any sense here */ 

    /*Uni:Allocate memory for main_pointer*/ 
    main_pointer = (char *)malloc(5*sizeof(char)); 
    /*Uni:Call the random_name function to get the random Name*/ 
    random_name(main_pointer); 

    /*Uni:Now print mainpointer */ 
    printf("\nIn main:\nmain_pointer = %s\n", main_pointer); 

    return 0;} 

символ * random_name (символ * MAIN_POINTER)

{

int x = random_number(0,7); 

    char random[7][5] = 
    {"0Sam", "1Sam", "2Sam", "3Sam", "4Sam","5Sam","6Sam"}; 


/*Uni: When you declare any Array, the array name itself is a pointer, 
    so here &random is a double pointer 
    Note: If you want to return only the VALUE of nth string, 
    then simply writing random[x] would suffice 
    random[0]: First string 
    random[1]: Second string 
    . 
    . 
    . 
    random [6]: 7th string 
    So,we can access any string at nth position as random[n];*/ 


/*Commenting this as here double char pointer is being assigned to 
    single char pointer*/ 
/*MAIN_POINTER = &random[x][0];*/ 

/*Uni:Copying string STARTING at Random[x] position.Each row of 
    random_Array holds a string of length 5 characters*/ 

/*Range check ,so that we don`t read out of bound array */ 
if(0<=x<=6) 
{ 
    printf("Uni:Value of x %d, Random Name %s",x,random[x]); 
    strncpy(MAIN_POINTER,random[x],5); 
} 

/*Uni: No need of returning pointer here,as we have copied 
    the string value (Random name) in MAIN_POINTER already*/ 
return MAIN_POINTER;} 

INT случайное_число (интермедиат мин, Int макс)

{

int roll; 

int maximum = max - min; 


srand(time(NULL)); 

roll = (rand() % maximum) + min; 

return roll; 

}

+0

' srand() 'следует вызывать только __once__, обычно в' main() '. Если вы собираетесь исправить код, вы должны исправить этот вызов 'srand()' внутри функции random_number(). – Blastfurnace

Смежные вопросы