簡體   English   中英

使用指向 function 的指針反轉字符串,它執行字符串反轉

[英]Reverse String with a pointer to a function, which executes the String reverse

我想用一個指向 function 的指針來反轉一個字符串,它執行字符串反轉。 我覺得我沒有正確掌握使用指向變量或函數的指針的概念,所以如果有人能解釋我,我會非常感激,我在這里想錯了:

1) 定義一個指向 function 的指針:

char *strrev(char *str)
{
  char *p1, *p2;

  if (! str || ! *str)
        return str;
  for (p1 = str, p2 = str + strlen(str) - 1; p2 > p1; ++p1, --p2)
  {
      *p1 ^= *p2;
      *p2 ^= *p1;
      *p1 ^= *p2;
   }
   return str;
}

2) 現在在我的 main 中定義一個指針,它與我在上面定義的 function 匹配:

int main(void) {

    char (*functPtr)(char);
    functPtr = &strrev;

3)現在我定義了我要反轉的String,定義一個新的指針,讓指針指向String的地址空間。

char str[50] = "Hello, World";
char *pointer[50];
pointer[50] = &str[50];

4)最后我定義了一個新的字符串並寫入function的結果,它通過指針調用,該指針指向指向function的指針。

char t[50] = (*functPtr)(pointer[50]);
printf("%s\n", str);
return(0);
}

不幸的是,我收到各種錯誤消息,例如:

Ü1.c:29:10: error: array initializer must be an initializer list or string literal
    char t[50] = (*functPtr)(pointer[50]);
         ^
    Ü1.c:27:5: warning: array index 50 is past the end of the array (which contains 50 elements) [-Warray-bounds]
        pointer[50] = &str[50];
        ^       ~~
    Ü1.c:26:5: note: array 'pointer' declared here
        char *pointer[50];
        ^
    Ü1.c:29:30: warning: array index 50 is past the end of the array (which contains 50 elements) [-Warray-bounds]
        char t[50] = (*functPtr)(pointer[50]);
                                 ^       ~~
    Ü1.c:26:5: note: array 'pointer' declared here
        char *pointer[50];
        ^
    2 warnings and 1 error generated.

我在這個答案中總結了我的評論,因為它為評論的細節提供了更多空間。

char (*functPtr)(char); 應該是char *(*functPtr)(char *); 因為它需要一個指向char 而不是 char 的指針。 同樣,它返回一個指針。

char *pointer[50]; 將是 50 個指針的數組,您想說“指向 50 個字符數組的指針”。 在 C 我們沒有這么說。 我們只是說“一個指向 char 的指針”,並沒有說有多少。 所以char *pointer; 就足夠了。

char t[50] = (*functPtr)(pointer[50]); 在 C 中不正確。

您想將funcPtr的結果分配給數組t 但是在這里,您將初始化與分配混合在一起。 char t[50]; 聲明一個 50 個字符的數組。 您可以通過給它一個值來初始化它,例如char t[50] = "Hello World"; 這將使編譯器將“Hello World”復制到數組中。

但是您嘗試將 function 指針分配給數組。 您可能打算將 function 的結果放入數組中。

另請注意,您不能將一個數組“分配”給另一個數組。 你只能復制它。

所以正確的代碼是:

char *(*functPtr)(char *);
functPtr = &strrev;

char str[50] = "Hello, World";

char t[50];
char *s= funcPtr(str);  // call the function and save the returned pointer
strcpy(t, s);           // now copy the result to your array.
printf("%s\n", t);      // and print it

注意: char str[50] = "Hello, World"; 是正確的,你會知道, char *str = "Hello, World"; 是錯的。 為什么? 因為第二個str將指向只讀 memory (“字符串文字”)並且任何修改它的嘗試都會中止程序。 但在這里你做對了。

1) 定義一個指向 function 的指針:

不,您沒有定義指向 function 的指針。 您定義了一個名為 strrev 的strrev

2) 現在在我的 main 中定義一個指針,它與我在上面定義的 function 匹配:

int main(void) {

    char *(*functPtr)(char *);
    functPtr = &strrev;

是的,您定義了一個指向 function 的指針,並使用 function strrev的地址對其進行了初始化。 由於表達式中使用的 function 指示符被隱式轉換為指向 function 的指針,因此您可以編寫

int main(void) {

    char *(*functPtr)(char *);
    functPtr = strrev;

3)現在我定義了我要反轉的String,定義一個新的指針,讓指針指向String的地址空間。

char str[50] = "Hello, World";
char *pointer[50];
pointer[50] = &str[50];

除了包含字符串的字符數組的定義之外,所有其他記錄都沒有任何意義。 對於初學者, function strrev將字符串反轉到位。 它不會創建傳遞給它的字符串的反向副本。

如果你想聲明一個指針,它將獲得由 function 返回的反向字符串的地址,它等於原始字符串的地址,那么你可以寫

char *pointer = functPtr( str );

4)最后我定義了一個新的字符串並寫入function的結果,它通過指針調用,該指針指向指向function的指針。

char t[50] = (*functPtr)(pointer[50]);
printf("%s\n", str);

您已經定義了一個指針,它將獲取從 function 返回的值。 所以再聲明一個數組是沒有意義的。 而且 arrays 沒有賦值運算符。 並且 function 將原始字符串反轉到位。 為什么要使用原始反轉字符串的重復副本再創建一個數組? 這完全沒有意義。

您的程序可以如下所示

#include <stdio.h>
#include <string.h>

char * strrev( char *s )
{
    size_t n = strlen( s );

    if ( n )
    {
        for ( char *first = s, *last = s + n; first < --last; ++first )
        {
            char c = *first;
            *first = *last;
            *last = c;
        }
    }

    return s;
}

int main(void) 
{
    char * ( *fp )( char * ) = strrev;

    char s[] = "Hello, World";

    puts( s );
    puts( fp( s ) );

    return 0;
}

程序 output 是

Hello, World
dlroW ,olleH

如果您最初希望 function 不會反轉原始字符串,而是制作原始字符串的反轉副本,那么在這種情況下,定義一個額外的字符數組確實是有意義的,它將獲得原始字符串的反轉副本。

在這種情況下,程序可能看起來像。

#include <stdio.h>
#include <string.h>

char *reverse_copy( char *s1, const char *s2 )
{
    *( s1 += strlen( s2 ) ) = '\0';

    while (*s2)
    {
        *--s1 = *s2++;
    }

    return s1;
}

int main(void) 
{
    char * ( *fp )( char *, const char * ) = reverse_copy;

    char s[] = "Hello, World";
    char t[sizeof( s )];
    puts( s );
    puts( fp( t, s ) );

    return 0;
}

程序 output 是

Hello, World
dlroW ,olleH

現在原始字符數組s沒有改變,而數組t得到了存儲在數組s中的原始字符串的反向副本。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM