簡體   English   中英

C:反向字符串功能不影響指針

[英]C: reverse string function not affecting pointer

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

int reverse(char *, int);

main()
{
    char *word = "Thanks for your help";

    reverse(word, strlen(word));
    printf("%s", word);     

    getchar();

}

int reverse(char *line, int len)
{
    int i, j;
    char *newline = malloc(strlen(line));

    for (i = len - 1, j = 0 ; i >= 0; i--, j++)
    {
        newline[j] = line[i];
    }
    newline[j] = '\0';
    line = &newline;
}

嘿伙計。 我有一個似乎無法解決的簡單C問題。

上面的程序用於接收字符串並向后打印。 反向是完成此功能的功能。

具體地說,問題是當我在main()中打印單詞時,字符串看起來沒有變化。 我試圖將line的地址設置為newline的地址,但是它沒有任何作用。

int reverse(char *line, int len)
{
    int i, j;
    char *newline = malloc(strlen(line));

    for (i = len - 1, j = 0 ; i >= 0; i--, j++)
    {
        newline[j] = line[i];
    }
    newline[j] = '\0';
    line = &newline;             // Your problem is here
}

您只是分配給本地line指針。 這對調用函數沒有任何影響。

考慮改為:

char *reverse(char *line, int len)
{
    // ...
    return newline;
}

其他建議:

  • 打開編譯器警告, 並注意它們 您有很多小錯誤(例如, reverse目前未返回任何內容,但被聲明為return int )。
  • 鑒於reverse的第一個參數是一個指向C字符串(以NUL終止)的指針,因此也不需要采用length參數。
  • reverse函數不一定需要定義為返回字符串的副本reversed 相反,它可以就地反轉字符串。 請注意,您不能將字符串文字傳遞給此類函數,因為它們是只讀的。

這是我的寫法:

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

void reverse(char *str)
{
    size_t i, j;
    for (i = strlen(str) - 1, j = 0 ; i > j; i--, j++)
    {
        // Swap characters
        char c = str[i];
        str[i] = str[j];
        str[j] = c;
    }
}

int main(void)
{
    // Mutable string allocated on the stack;
    // we cannot just pass a string literal to reverse().
    char str[] = "Here is a test string";

    reverse(str);

    printf("Result: \"%s\"\n", str);
    return 0;
}

請注意, for循環條件是i > j ,因為我們希望每個循環僅遍歷數組的一半,而不要交換每個字符兩次。

結果:

$ ./a.exe
Result: "gnirts tset a si ereH"

看一下下面的代碼:

void addOne(int a) {
   int newA = a + 1;
   a = newA;
}

int main() {
  int num = 5;
  addOne(num);
  printf("%d\n", num);
}

您知道為什么會打印5,而不是6嗎? 這是因為當您將num傳遞給addOne ,實際上是制作了num的副本。 addOnea更改為newA ,它將更改副本(稱為a ),而不是原始變量num C具有按值傳遞的語義。

您的代碼也遇到相同的問題(以及其他一些問題)。 當您調用reverse ,將生成word的副本(不是字符串的副本,而是指向字符串的字符指針的副本)。 當您將line更改為指向新字符串newLine ,您實際上並沒有更改傳入的指針。 您正在更改指針的副本。

那么,您應該如何實施逆向? 這取決於:有兩種選擇。

  1. reverse可以返回包含原始字符串的新分配的字符串,即為反向。 在這種情況下,您的函數簽名應為char *reverse ,而不是int reverse。
  2. reverse可以修改原始字符串。 也就是說,您永遠不會分配新的字符串,而只需移動原始字符串的字符即可。 通常,這是可行的,但不適用於您的情況,因為用字符串文字初始化的char指針不一定指向可寫內存。
  3. reverse實際上可以更改傳入的指針以指向新字符串(您在當前代碼中嘗試執行的操作)。 為此,您必須編寫一個函數void reverse(char **pointerToString) 然后,您可以分配*pointerToString = newLine; 但這不是一個好習慣。 現在無法訪問原始傳入的參數,並且如果已對其進行了malloc分配,則無法將其釋放。

暫無
暫無

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

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