从指针生成整数,从整数生成指针,无需强制转换

时间:2017-03-28 05:18:35

标签: c string pointers

我有一个函数,它接受一个字符串并返回它的反转形式:

char reverse_string(char* message){

char* reversed="";
assert(message!=NULL);

int last_index=strlen(message)-1;
int a;

for(a=0; a <strlen(message);a++){
    strcat(reversed, &message[last_index]);
    last_index--;
}

return reversed;
}

然后打电话给我,我这样做了:

strncpy(rev_one, reverse_string(msg_one), MAX_LENGTH);

变量声明如下:

char* msg_one;
char* msg_two;
char* rev_one;
char* rev_two;

我基本上将一个字符串反转,然后将其存储到另一个字符串中。我没有得到任何其他错误,除了:

 ../display.c: In function 'reverse_string':
 ../display.c:38: warning: return makes integer from pointer without a cast
 ../display.c: In function 'string_init':
 ../display.c:45: warning: passing argument 2 of 'strncpy' makes pointer from integer without a cast
 ../display.c:46: warning: passing argument 2 of 'strncpy' makes pointer from integer without a cast

我在另一篇文章中读到该函数不应该有return语句,除非它分配了传递的变量,但是我将反转的字符串存储在另一个变量中。删除return语句是个好主意吗?我将如何解决这个问题,感谢您的帮助,谢谢!

更新: 我阅读了所有的评论,这是我的最终代码,我尝试了内存分配并修复了返回类型,代码没有返回任何错误,但我想确保它的好,我感谢一些反馈它:

char* reverse_string(char* message){

assert(message!=NULL);
char* reversed=(char*)malloc(sizeof(char));

if (reversed == 0)
    {
        printf("ERROR: Out of memory\n");
    }


int last_index=strlen(message)-1;
int a;

for(a=0; a <strlen(message);a++){
    strcat(reversed, &message[last_index]);
    last_index--;
}

return reversed;
}

我想将内存分配reversed[MAX_LENGTH]分配到#define MAX_LENGTH 20,但我一直收到一条错误,说&#34;函数返回局部变量的地址&#34;所以我使用了malloc,但我只掌握了基本知识。

更新2 好的,所以我更新了最后一个代码,并根据建议

修复了内存分配大小

我还从下面的一条评论中做了一些笔记,并提出了另一种快速方法

char* reverse_string_into(char* reversed, char* message){
assert(message!=NULL);

const size_t len = strlen(message);
const size_t last = len - 1;

int i;
for (i=0; i<len; i++){
    reversed[i] = message[last - i];
}
return NULL;
}

可以吗?我回忆起记忆问题吗?

3 个答案:

答案 0 :(得分:0)

消息很清楚:

  1. return reversed返回一个地址(指针值),但返回类型为char,将其更改为char *
  2. 如果您进行上一次编辑,这将立即消失,因为声明reverse_string函数返回char您的strncpy您的用法是错误的:第二个参数必须是地址
  3. 还有一些问题:reverse的分配,你的逆转算法很奇怪,......

答案 1 :(得分:0)

警告是由于代码中的以下问题引起的:

以下原型不正确,因为您的目的是返回char *而不是char

 char reverse_string(char* message) 

应该是

char *reverse_string(char* message) 

以下问题不会导致您的警告,但是,您的代码中存在此问题

此外,在函数reverse_string中,您应该分配内存并将其指向reversed。目前,没有为reversed分配内存,当你执行strcat时,它将导致写入您不拥有的内存,并可能导致未定义的行为。传递给strcat的目标字符串中必须有足够的内存来保存结果(连接字符串)。有关它的用法,请参阅strcat的手册页。

答案 2 :(得分:0)

您的代码存在一些问题:

  1. 函数reverse_string的签名使其返回char而不是char*。这就是为什么你的第38行警告。
  2. 在函数reverse_string中,您尝试使用单个字符串来存储strcat中的所有数据,然后您尝试返回此内存。
  3. 在函数reverse_string中,您在strlen循环中反复调用forstrlen通过遍历其给定的char指针来工作,直到它找到空字符,然后返回它看到的字符数。如果在循环之前调用strlen,缓存其结果,然后在循环中使用该缓存结果,那么您可以确定您的代码不会浪费周期重新计算每次迭代的长度循环。
  4. 由于您的reverse_string函数返回char并且strncpy期望指向char的指针,编译器会警告您它正在​​按照您的要求执行操作通过从整数(char被提升为)的指针来做。
  5. malloc分配要求分配的内存字节数。用sizeof(char)调用它将分配1个字节。但是,如果要复制超过该数量的数据,那么您将需要分配与要复制的所有数据一样多的内存,包括空终止字符。因此,您需要使用malloc或更多来调用strlen(message) + 1作为要分配的大小。否则你的代码可能会破坏内存。
  6. 这里有一个反转功能可能是什么样子以及如何使用它们的例子(这不是完美的代码,而是简单的可编辑和可用):

    #include <stdio.h>
    #include <string.h>
    
    /*
     * Reverses a null terminated character array in place.
     * Note that the memory pointed at by the "string" parameter must
     * really be writable. I.e. you can't pass this a string stored in ROM.
     */
    char* reverse_string_inplace(char* string)
    {
        const size_t len = strlen(string);
        const size_t last = len - 1;
        const size_t mid = len / 2;
    
        for (size_t i = 0; i < mid; i++)
        {
            char tmp = string[i];
            string[i] = string[last - i];
            string[last - i] = tmp;
        }
        return string;
    }
    
    char* reverse_strncpy(char *dst, const char* src, size_t dstsiz)
    {
        if (dst != NULL && dstsiz > 0)
        {
            const size_t len = strlen(src);
            const size_t last = len - 1;
            size_t i = 0;
    
            if (dstsiz > len)
            {
                for (; i < len; i++)
                {
                    dst[i] = src[last - i];
                }
            }
            dst[i] = '\0';
            return dst;
        }
        return NULL;
    }
    
    int main(void)
    {
        char hello_str[] = "hello";
        char goodbye_str[] = "goodbye";
        char even_str[] = "even";
        char* strings[] = {hello_str, goodbye_str, even_str};
    
        for (int i = 0; i < 3; i++)
        {
            char buf[80];
    
            fputs("'", stdout);
            fputs(strings[i], stdout);
            fputs("' -> '", stdout);
            fputs(reverse_strncpy(buf, strings[i], sizeof(buf)), stdout);
            fputs("' or '", stdout);
            fputs(reverse_string_inplace(strings[i]), stdout);
            fputs("'", stdout);
            fputs("\n", stdout);
        }
        return 0;
    }
    

    以下是此代码的输出结果:

    $ ./main
    'hello' -> 'olleh' or 'olleh'
    'goodbye' -> 'eybdoog' or 'eybdoog'
    'even' -> 'neve' or 'neve'