2016-06-13 88 views
0

我遇到了问题。我想用一个CopyString()函数将const char* s和char* s复制到缓冲区。它不应该是一个问题,但由于某种原因,我的编译器不会做我期望它做的事情(我使用PICro的MikroC)。在c中传递char *到const char *

void CopyString(char * dest, const char * src, uint8 maxLength){ 
    uint8 i; 
    for(i=0 ; src[i] && (i < maxLength) ; i++){ 
     dest[i] = src[i]; 
    }; 
} 

char test[3]={'2', '0', ' '}; 
CopyString(buf, test, 3);//gives an error (illigal pointer conversion) 
CopyString(buf, (const char *)test, 3); //Doesn't pass the pointer to the array... No idea why not... Do you? 

void CopyString2(char * dest, char * src, uint8 maxLength){ 
    uint8 i; 
    for(i=0 ; src[i] && (i < maxLength) ; i++){ 
     dest[i] = src[i]; 
    }; 
} 
const char test[3]={'2', '0', ' '}; 
CopyString2(buf, "20 ", 3);//All ok 
CopyString2(buf, test, 3); //gives an error (illigal pointer conversion) 

任何人都知道如何做到这一点?目前我在一个C文档中使用了CopyString2()CopyString(),这个文档看起来不太好,也不需要。为什么会通过char*const char*给出问题? const char*唯一的做法是确保char数组中的数据在函数内不会改变,对吧?

编辑: 在这里编辑'整个'示例代码(应该是一个最小,完整和可验证的例子)。我使用Keil编译器(我用它来编程ARM单片机的编译器),它编译得很好(就像我期望的那样),但是使用MikroC PIC编译器(就我所知,这是编译器的调用方式)。 :

18 384 Illegal pointer conversion main.c (line 18, message no. 384)

23 384 Illegal pointer conversion main.c (line 23, message no. 384)

void CopyString(char * dest, const char * src, unsigned char maxLength){ 
    unsigned char i; 
    for(i=0 ; src[i] && (i < maxLength) ; i++){ 
     dest[i] = src[i]; 
    }; 
} 

void CopyString2(char * dest, char * src, unsigned char maxLength){ 
    unsigned char i; 
    for(i=0 ; src[i] && (i < maxLength) ; i++){ 
     dest[i] = src[i]; 
    }; 
} 

void main(){ 
    char buf[16]={0,}; 
    char test1[3]={'2', '0', ' '}; 
    const char test2[3]={'2', '0', ' '}; 

    CopyString(buf, test1, 3);//gives an error (illigal pointer conversion); 
    CopyString(buf, (const char *)test1, 3); //Doesn't pass the pointer to the array 

    CopyString2(buf, "20 ", 3);//All ok 
    CopyString2(buf, test2, 3); //gives an error (illigal pointer conversion); 
} 
+3

发布您的*实际代码*。 – EOF

+0

当发布关于构建错误的问题时,请在问题主体中包含实际错误,完整,全部和*未编辑*。还包括编译器给出的任何可能的信息说明。最好复制粘贴生成日志。 –

+1

您的示例不是*完整*(请参阅[mcve])。此外,如果您收到编译错误,还会发布*完整*错误消息。 – user694733

回答

3

这是一个与如何为PIC控制器实现const变量有关的问题。在PIC控制器中,RAM和代码位于不同类型的内存中。 RAM是SD-RAM,代码是闪存(RAM可通过寄存器和RAM操作访问,代码只能自动解码,或者通过复杂的汇编操作序列读取)。由于RAM非常小,常量值为存储为代码存储器中的返回字面指令(为了绕过读取闪存的困难,否则)更大。

所以你不能在两种类型上都做同样的操作。这是你需要学习生活的东西。我建议你看看这段代码的反汇编,看看到底发生了什么。

+0

edaboard有一个相关的线程http://www.edaboard.com/thread266196.html – Toby

+0

@Toby虽然edaboard线程是关于传递一个const char *到一个需要char *的函数。在这种情况下,我可以首先将字符串复制到RAM中,因为该函数可能需要该字符串不是常量。但我的问题是关于将char *传递给接受const char *的函数。我没有看到为什么这样的函数不接受char *的原因。无论如何,谢谢你的回应! – Sander

+0

@SurDin我相信它总是发生在单片机的世界里:常量只存储在闪存中。如果有编译器不这样做,我认为这是没有意义的。我也使用Keil(arm)编译器,它不会将char *的任何问题作为const char *参数传递,尽管它仍然只在flash中存储const char *。为什么PIC会不同?也许是因为这两种内存需要不同类型的内存访问序列。尽管如此,它对我来说并没有什么意义。但无论如何;感谢您的回答! – Sander

2

我以前在其他编译器很久以前看到了这一点 - 注意我以前从未使用过该编译器。

C的“阵列是一个指针”的概念导致很多与新手的问题。为了防止这种情况发生,一些编译器编写者非常不习惯(这是一个词!查找它!),并要求您将一个字符的地址传递给一个const char *而不仅仅是一个数组。

你可以试试CopyString2(buf, &test[0], 3);

甚至CopyString2(buf, (const char *)&test[0], 3);

+0

您的第一个建议确实导致与之前相同的错误。由于某种奇怪的原因,你的第二个建议不会传递正确的指针。 – Sander