1

C とこのサイトは初めてです。関数内の配列の配列で名前をランダムに選択しようとしています。次に、そのランダムな名前を main に戻し、そこで使用できるようにします。

#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

5 に答える 5

4

投稿されたコードにはいくつかの問題がありますが、これから始めましょう。

char * main_pointer;

これは常に悪いことです。「main_pointer」が初期化されていないままになります。あなたのコンパイラはあなたにこれを伝えたはずです。

test.c: 関数 'main' 内: test.c:12:7: 警告: 'main_pointer' がこの関数で初期化されていない状態で使用されています [-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

基本的に、ポインターは変数と同じように機能します。この場合、「in」は「p」と同じ値、アドレス「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);

この場合、実際に使用することはないため、関数に渡すことはあまり重要ではないようです。

コードが遭遇するもう 1 つの問題は、ポインターを使用して、関数のスコープ内からスタック上のその上の何かにデータをホイストしようとしているということです。これは危険です。データを保持したり、関数の外部で表示したりする必要がある場合は、グローバル スコープで宣言するか、「静的」属性を指定する必要があります。

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];
}
于 2013-06-17T04:40:12.023 に答える
3

You never set the value for main_pointer in main() function, it just has a garbage address.

于 2013-06-17T04:23:43.620 に答える
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];
}
于 2013-06-17T08:06:02.727 に答える
1

私はあなたのプログラムを修正しようとしましたが、現在は問題なく動作します。説明については、コード内のコメントを参照してください。

正しい実行コード:

#include "stdio.h"

#include "stdlib.h"

#include "string.h"

#include "time.h" // rand 関数用

int random_number(int, int);

char * random_name(char *);

int main(void)

{

    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;}

char * random_name(char * 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 random_number(int min, int max)

{

int roll;

int maximum = max - min;


srand(time(NULL)); 

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

return roll;

}

于 2013-06-17T07:25:54.010 に答える
0

変数random[7][5]は関数random_name に対してローカルです。関数が戻ると、変数は期限切れになります/利用できなくなります..

あなたの場合、変数randomへのポインターを返すと、未定義の動作が発生します

解決策:

1) 変数randomをグローバルに移動する 2) 変数randomを main 関数に移動し、変数を引数として渡す

于 2013-06-17T06:27:46.133 に答える