[英]Modify const char * in C
我正在練習面試。 Im當前遇到的問題是反轉C中的常量字符串。我知道由於str2是const,因此我可以修改str2指向的位置,但不能修改其值。 我下面有一個稱為reverse_const的函數。 它將const char * str_const反轉到位並打印。 但是,當我嘗試從main方法反轉后打印st2時,字符串不再反轉了。 就像reverse_const()一樣,它暫時更改了str2的存儲位置。 我在這里做錯了什么?
#include <stdio.h>
#include <string.h>
void reverse(char *str){
int c_size = strlen(str);
char *c_begin = str, *c_end = str + (c_size - 1);
int i;
for(i = 0; i < c_size / 2; i++){
*c_begin ^= *c_end;
*c_end ^= *c_begin;
*c_begin ^= *c_end;
c_begin++;
c_end--;
}
}
void reverse_const(const char *str_const){
int c_size = strlen(str_const);
char str[c_size];
strcpy(str, str_const);
char *c_begin = str, *c_end = str + (c_size - 1);
int i;
for(i = 0; i < c_size / 2; i++){
*c_begin ^= *c_end;
*c_end ^= *c_begin;
*c_begin ^= *c_end;
c_begin++;
c_end--;
}
str_const = str;
printf("%s\n", str_const);
}
int main(){
char str1[] = "Indiana";
char *str2 = "Kentucky";
printf("TESTS:\nString 1 pre-reversal: %s\n", str1);
reverse(str1);
printf("String 1 post-reversal: %s\n", str1);
printf("Constant string 2 pre-reversal: %s\n", str2);
reverse_const(str2);
printf("Constant string 2 post-reversal: %s\n", str2);
}
當您傳遞參數時,該函數將獲得一個副本。 str_const = str;
分配給該副本。 您可以將指針傳遞給指針,以能夠在函數之外更改指針的值,但是您正在將字符串副本分配在堆棧上,因此一旦離開了reverse_const
的范圍,字符串副本將變為無效,因此這里沒有道理。
如果您想讓字符串副本在reverse_const
的末尾reverse_const
下來,請使用malloc
分配數組,或者使用strdup
進行分配和復制。 您必須以某種方式返回通過malloc
malloc'ed
指針(通過指向指針參數的指針的返回值),然后調用者將有責任在完成malloc
分配的內存后free
它。
您需要編寫函數,以便有某種方式返回修改后的參數。
一種這樣的解決方案是通過引用傳遞 :
void reverse_const(const char **str_const){
const char *in = *str_const;
char *out = malloc(strlen(in)+1);
/* write to out */
*str_const = out;
}
但是更好的方法是使用返回值:
char *reverse_const(const char *str_const){
const char *in = str_const;
char *out = malloc(strlen(in)+1);
/* write to out */
return out;
}
返回類型可以是const char *
,但這是不必要的限制,因為您知道可以安全地修改返回的字符串。
注意,兩個示例都使用malloc
。 數組無法以這種方式在C語言中傳回,因為它們存在於堆棧中,並在函數退出時銷毀。
每當長時間運行的程序使用malloc
,在代碼中的某處確實應該有一個匹配的free
,否則您將發生內存泄漏。 這很痛苦,但是所有C程序員都必須掌握一些東西。
如果要在main()
返回反轉的str2
,則需要將足夠大小的緩沖區傳遞給reverse_const
來保存反轉的字符串,或者需要在reverse_const
為其動態分配存儲空間(局部變量長度數組不會做):
#include <stdlib.h>
...
void reverse_const (const char **str_const)
{
int c_size = strlen (*str_const);
char *str = calloc (c_size + 1, sizeof *str);
strcpy (str, *str_const);
char *c_begin = str, *c_end = str + (c_size - 1);
int i;
for (i = 0; i < c_size / 2; i++) {
*c_begin ^= *c_end;
*c_end ^= *c_begin;
*c_begin ^= *c_end;
c_begin++;
c_end--;
}
*str_const = str;
printf ("%s\n", *str_const);
}
int main (void) {
char str1[] = "Indiana";
char *str2 = "Kentucky";
printf ("TESTS:\nString 1 pre-reversal: %s\n", str1);
reverse (str1);
printf ("String 1 post-reversal: %s\n", str1);
printf ("Constant string 2 pre-reversal: %s\n", str2);
reverse_const ((const char **)&str2);
printf ("Constant string 2 post-reversal: %s\n", str2);
free (str2);
return 0;
}
輸出量
$ ./bin/revconststr
TESTS:
String 1 pre-reversal: Indiana
String 1 post-reversal: anaidnI
Constant string 2 pre-reversal: Kentucky
ykcutneK
Constant string 2 post-reversal: ykcutneK
返回指針
您還有其他選擇,可以將指向str
的指針返回給main()
str2
。 這通常是您期望看到的。 如果您有任何疑問,請告訴我:
char *reverse_const2 (const char **str_const)
{
int c_size = strlen (*str_const);
char *str = calloc (c_size + 1, sizeof *str);
strcpy (str, *str_const);
char *c_begin = str, *c_end = str + (c_size - 1);
int i;
for (i = 0; i < c_size / 2; i++) {
*c_begin ^= *c_end;
*c_end ^= *c_begin;
*c_begin ^= *c_end;
c_begin++;
c_end--;
}
//*str_const = str;
printf ("%s\n", *str_const);
return str;
}
int main (void)
{
char str1[] = "Indiana";
char *str2 = "Kentucky";
printf ("TESTS:\nString 1 pre-reversal: %s\n", str1);
reverse (str1);
printf ("String 1 post-reversal: %s\n", str1);
printf ("Constant string 2 pre-reversal: %s\n", str2);
str2 = reverse_const2 ((const char **)&str2);
printf ("Constant string 2 post-reversal: %s\n", str2);
free (str2);
return 0;
}
這里的問題是您修改了傳遞給reverse_const
的參數,但是C中的參數是按值傳遞的,這意味着它們已被復制。 你在功能修改該變量是原始指針的副本 ,改變副本當然不會改變原來的。
C沒有此處需要的按引用傳遞 ,但是可以通過使用指針進行模擬 ,對於函數,您需要將指針傳遞給指針,然后使用解引用運算符*
修改指向的指針指針指向該函數,並在調用該函數時使用地址運算符&
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.