请在结束前阅读:"哦不,这个问题再次出现......"
我现在正坐在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
声明字符串是否正确?答案 0 :(得分:5)
您的直接问题:
- 使用uint16_t声明字符串是否正确?
没有
所有字符串始终为char[]
。还有宽字符串(宽字符的字符串),其类型为wchar_t[]
,并且使用L
前缀编写(例如{ {1}})。
- 将字符串传递给函数的推荐方法是什么?
作为指向字符串中第一个字符的指针,因此L"hello"
或char *
。 wchar_t *
限定词在这里毫无意义;这意味着指针(不是字符串本身)是常量(参见here)。我建议改为写const
或wchar_t const *
;它有不同的含义(即字符串不能改变),但它是正确和有意义的。
您提到此代码来自课程手册。我不确定你的意思是这些是你的教授发出的讲义,还是你买了一本出版的书。在任何一种情况下,如果此代码段代表图书/笔记的质量,获得退款。
现在,让我们使用此代码。
此代码中存在错误,导致程序崩溃:
const wchar_t *
当printf("... %s ...", ..., *string, ...)
为string
时总是错误的。不要取消引用那个指针。如果你坚持使用&#34;宽&#34;字符(questionable),您将不得不改变一些事情:
char*
并使用char
,而不是使用<wchar.h>
。据我所知,wchar_t
和uint16_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;)”。