我正在学习使用C ++编程微控制器。 NewbieHack.com有一个很好的教程,但我被困在一个处理指针的部分。
在他的代码中,他编写了一个名为Send_A_String
的函数void Send_A_String(char *StringOfCharacters)
{
while(*StringOfCharacters > 0)
{
Send_A_Character(*StringOfCharacters++);
}
}
在他的int main()部分代码中,他按以下方式调用函数
Send_A_String("NewbieHack.com");
使用“NewBieHack.com”让我感到困惑,因为函数的输入是char类型变量。如何使用指针允许您将字符串分配给char类型变量?
如果措辞不清楚,我道歉。任何帮助将不胜感激。
答案 0 :(得分:2)
这样做的原因是"NewbieHack.com"
是一个空终止的char数组,可以显示为{'N', 'e', 'w', 'b', 'i', 'e', 'H', 'a', 'c', 'k', '.', 'c', 'o', 'm', '\0'}
。
因此,当您进行Send_A_String("NewbieHack.com")
调用时,const字符串"NewbieHack.com"
将被转换为指向char数组开头的const char*
(在本例中为'N')
在while循环中,您将迭代char数组,直到您到达char数组的末尾(即'\ 0')。
答案 1 :(得分:1)
它不是char类型。它是指向char char *
的指针。你可以看到一个指针作为一个数组的起始地址,所以你基本上有一个char数组,这实际上是一个字符串。
*StringOfCharacters
这里取消引用指针,意思是地址StringOfCharacters
处的字符。
*StringOfCharacters++
这必须分为两个:StringOfCharacters++
递增指针,所以现在指针指向数组中的下一个char(请注意这是指针算术),但因为它是运算符后缀增量,它将返回下一部分的旧指针值:*StringOfCharacters
再次取消引用指针,给你一个字符。希望我很清楚。
答案 2 :(得分:1)
虽然这是可疑的,但按照polkadotcadaver的评论,我会解释。
(未加前缀)字符串文字实际上是const char []类型,而不是std :: string。 char []实际上在调用函数时衰减为char *。 Send_A_String不是const-correct(因为它确实应该接受const char *),但这可能只会导致编译器发出警告。
请注意,输入不是char类型变量,而是指向char类型的变量!这一切都有所不同。所以const char []“NewbieHack.com”衰变为const char *,它与char *兼容。
现在指针指向char []的第一个char,即'N'。由于它是一个指针,你需要使用运算符*取消引用它才能到达char。
循环测试字符串结尾('\ 0'),然后调用带有解除引用的指针调用Send_A_Character,即指针指向的字符,并将指针前进一。因此,指针现在指向char [],'e'的第二个字符。等等,直到结束。
答案 3 :(得分:1)
写作:
Send_A_String("NewbieHack.com");
实际上与下面的写作相同
const char* sz = "NewbieHack.com";
Send_A_String(sz); // with dangerous conversion const char* -> char*
更正确的版本是:
char sz[] = "NewbieHack.com";
Send_A_String(sz);
至少应该没有警告。但实际上Send_A_String应该将其参数更改为const char *,因为它不会更改字符串字符,而只会增加指针。
[编辑]
如果让您困惑的是以下几行:
Send_A_Character(*StringOfCharacters++);
然后你可以按如下方式重写它:
StringOfCharacters++; // increment pointer to next char
char c = *StringOfCharacters; // dereference pointer to get char
Send_A_Character(c); // use char
现在应该很容易掌握最新情况
答案 4 :(得分:1)
发生的事情是这样的。
字面意思" NewbieHack.com"真的是指向一个'字符串' (或数组)由编译器终止的字符。它位于给定地址某处的RAM段中,例如
0xface0000 = 4E 65 77 64 69 65 48 61 N e w b i e h a
0xface0008 = 63 6B 2e 63 6f 6D 00 c k . c o m \0
在您的示例中调用函数
Send_A_String("NewbieHack.com");
编译器将地址传递给函数。因此,Send_A_String循环遍历字符串中的字符,将其打印出来,直到遇到空字符(或0)。
这里的语法有一个细微差别很重要。在函数定义中列出参数' char * StringOfCharacters'表示StringOfCharacters是字符的指针(地址)。稍后,语法(* StringOfCharacters> 0)表示对变量StringOfCharacters中包含的地址进行deference,并在那里使用该值。使用' *'在两种情况下都没有相同的含义。我会看看我是否可以说明:
void Send_A_String(char *StringOfCharacters) /* StringOfCharacters = 0xface0000 */
{
while(*StringOfCharacters > 0)
/* iteration 1 : *0xface0000 = 0x4E or 'N' so print it out below */
/* iteration 2 : *0xface0001 = 0x65 or 'e' so print it out below */
/* iteration 3 : *0xface0002 = 0x4E or 'w' so print it out below */
...
/* iteration 15 : *0xface000e = 0x00 or 0 or NULL so stop */
{
Send_A_Character(*StringOfCharacters++);
/* here the *StringOfCharacters gets done first */
/* the ++ is applied after the function returns */
/* iteration 1 : print 'N' then increment, StringOfCharacters now = 0xface0001 */
/* iteration 2 : print 'e' then increment, StringOfCharacters now = 0xface0002 */
/* iteration 3 : print 'w' then increment, StringOfCharacters now = 0xface0003 */
...
/* iteration 14 : print 'm' then increment, StringOfCharacters now = 0xface000e */
}
}
希望有所帮助。
答案 5 :(得分:-1)
此功能无效。首先是这个电话
Send_A_Character(*StringOfCharacters++);
不应编译,因为表达式*StringOfCharacters++
不是指针。
此外,没有任何意义上的呼叫(如果上述呼叫包含拼写错误)
Send_A_Character(StringOfCharacters++);
因为你会得到堆栈溢出。
也是这种情况
while(*StringOfCharacters > 0)
应改为
while( *StringOfCharacters )
因为char类型可以表现为有符号的字符。
我会按以下方式重写函数
void Send_A_String( const char *StringOfCharacters )
{
while ( *StringOfCharacters )
{
Send_A_Character( ++StringOfCharacters );
}
}
编辑:对不起。我没有看到有两个不同的函数Send_A_String和Send_A_Character。:)所以我改变了以下方式的函数
void Send_A_String( const char *StringOfCharacters )
{
while ( *StringOfCharacters )
{
Send_A_Character( *StringOfCharacters++ );
}
}