将指针(字符串)传递给C函数

时间:2015-11-11 11:38:38

标签: c

请在结束前阅读:"哦不,这个问题再次出现......"

我现在正坐在C课程中,课程书中提供了以下示例:

#include <stdio.h>
#include <stdint.h>

void Terminal_PrintData(uint16_t * const Data);

int main(void){
    uint16_t StringData[] = "MyData";
    Terminal_PrintData(StringData);
}

void Terminal_PrintData(uint16_t * const Data)
{
    printf("Value: %s", *Data);
}

当我编译这部杰作时,这就是我得到的:

F:\AVR Microcontroller>gcc -o test test.c
test.c: In function 'main':
test.c:7:26: error: wide character array initialized from non-wide string
  uint16_t StringData[] = "MyData";

我的问题是:

  • 使用uint16_t声明字符串是否正确?
  • 将字符串传递给函数的推荐方法是什么?

3 个答案:

答案 0 :(得分:5)

您的直接问题:

  
      
  • 使用uint16_t声明字符串是否正确?
  •   

没有

所有字符串始终为char[]。还有宽字符串宽字符的字符串),其类型为wchar_t[],并且使用L前缀编写(例如{ {1}})。

  
      
  • 将字符串传递给函数的推荐方法是什么?
  •   

作为指向字符串中第一个字符的指针,因此L"hello"char *wchar_t *限定词在这里毫无意义;这意味着指针(不是字符串本身)是常量(参见here)。我建议改为写constwchar_t const *;它有不同的含义(即字符串不能改变),但它是正确和有意义的。

您提到此代码来自课程手册。我不确定你的意思是这些是你的教授发出的讲义,还是你买了一本出版的书。在任何一种情况下,如果此代码段代表图书/笔记的质量,获得退款

现在,让我们使用此代码。

此代码中存在错误,导致程序崩溃:

  • const wchar_t *printf("... %s ...", ..., *string, ...)string时总是错误的。不要取消引用那个指针。

如果你坚持使用&#34;宽&#34;字符(questionable),您将不得不改变一些事情:

  • 您需要包含char*并使用char,而不是使用<wchar.h>。据我所知,wchar_tuint16_t除非你在任何地方使用显式转换,否则不会有效。这是因为uint8_t没有8位,只有CHAR_BIT bits
  • 宽字符文字必须以char前缀开头。
  • 您需要使用L
  • ,而不是使用printf
  • 在格式字符串中,使用wprintf而不是%ls。 (Unless you use Microsoft's compiler。)

最后,一些不太严重的错误:

  • 如上所述,%s参数无用。作者可能意味着T * const(或等效T const *)。
  • 您可以删除const T *<stdint.h>。我们不再使用<stdio.h>,而uint16_t声明了一些广泛的字符<wchar.h> - 就像函数一样。

我最终得到以下代码:

<stdio.h>

这可以在Linux x86-64上按照预期编译并运行GCC和Clang。

答案 1 :(得分:3)

有两种字符串:&#34;非宽&#34;由char和&#34;宽&#34;组成的由wchar_t组成并且写为L""的单个wchar_t可以写为L'')。它们之间有转换功能;除此之外,你不能混杂它们。

根据系统的不同,wchar_t可以是16或32位宽。

答案 2 :(得分:0)

您应该将字符串视为字符数组(在本例中为8位字符),因此uint8_t就足够了。你通常做的是将字符串的开头(这是指向数组的指针)传递给你的函数。为了使其更安全,您还可以将字符串的长度作为参数传递,但通常您的字符串将以分隔符(\ 0)结束。

当您将stringData传递给您的函数时,您实际上是在说&stringData[0],字面意思是“数组的第一个元素([0])的地址(&amp;)”。