使用带有字符类型变量的指针
Using pointers with char type variables
我正在学习使用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类型的变量。如何使用指针将字符串分配给字符类型的变量?
如果措辞不明确,我深表歉意。如有任何帮助,我们将不胜感激。
这之所以有效,是因为"NewbieHack.com"
是一个空终止的字符数组,可以可视化为{'N', 'e', 'w', 'b', 'i', 'e', 'H', 'a', 'c', 'k', '.', 'c', 'o', 'm', ' '}
。
因此,当您调用Send_A_String("NewbieHack.com")
时,常量字符串"NewbieHack.com"
将被强制转换为指向char数组开头的const char*
(在本例中为'N')。
在while循环中,您将迭代char数组,直到到达char数组的末尾(即"\0")。
尽管这是可疑的,根据polkadotcadaver的评论,我会解释。
(未固定)字符串文字的类型实际上是const-char[],而不是std::String。当函数被调用时,char[]实际上会衰减为char*。Send_A_String不是常量正确的(因为它确实应该接受常量char*),但这可能只会导致编译器发出警告。
请注意,输入不是字符类型变量,而是指向字符类型变量的指针!这让一切变得不同。因此const char[]"NewbieHack.com"衰减为const char*,它与char*兼容。
现在指针指向char[]的第一个字符,即'N'。由于它是一个指针,您需要使用运算符*来取消对它的引用,以便获取字符。
循环测试字符串结尾("\0"),然后调用带有取消引用的指针(即指针指向的字符)的Send_A_Character,并将指针前进一个。因此,指针现在指向char[]的第二个字符"e"。以此类推,直到到达终点。
写入:
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应该将其参数更改为constchar*,因为它不会更改字符串字符,而只是递增指针。
[编辑]
如果让你困惑的是下面这行:
Send_A_Character(*StringOfCharacters++);
然后你可以重写如下:
StringOfCharacters++; // increment pointer to next char
char c = *StringOfCharacters; // dereference pointer to get char
Send_A_Character(c); // use char
现在应该很容易理解发生了什么
发生的事情是这样的。
"NewbieHack.com"实际上是指向编译器以null结尾的字符串(或数组)的指针。它位于给定地址的某个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
调用示例中的函数时
Send_A_String("NewbieHack.com");
编译器正在将地址传递给函数。因此,Send_A_String循环遍历字符串中的字符,将它们打印出来,直到遇到null字符(或0)。
这里的语法有一个微妙的差异,这很重要。在列出参数的函数定义中,'char*StringOfCharacters'表示StringOfCharacters是指向字符的指针(地址)。稍后,语法(*StringOfCharacters>0)表示尊重变量StringOfCharacters中包含的地址,并使用其中的值。在这两种情况下,使用"*"的含义并不相同。我看看我是否能举例说明:
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 */
}
}
希望能有所帮助。
它不是字符类型。它是指向字符char *
的指针。你可以看到一个指针作为数组的起始地址,所以你基本上有一个char数组,witch实际上是一个字符串。
这里的*StringOfCharacters
取消引用指针,意思是地址StringOfCharacters
处的字符。
*StringOfCharacters++
这必须一分为二:StringOfCharacters++
递增指针,所以现在指针指向数组中的下一个字符(请注意,这是指针算法),但由于它是运算符后缀增量,它将返回下一部分的旧指针值:*StringOfCharacters
开关再次取消指针的引用,给你一个字符。希望我是清白的。
此函数无效。首先呼叫
Send_A_Character(*StringOfCharacters++);
不应编译因为表达式*StringOfCharacters++
不是指针。此外,没有任何意义的调用(如果上面的调用包含拼写错误)
Send_A_Character(StringOfCharacters++);
因为你会得到堆栈溢出。
还有这种情况
while(*StringOfCharacters > 0)
应该改为
while( *StringOfCharacters )
because类型的char可以表现为签名的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++ );
}
}
- 在C++中打印指向不同基元数据类型的指针的内存地址
- int数据类型的指针指向的是什么,如果是一个类的私有数据成员,我们创建了该类的两个对象?
- 表观调用前面的表达式必须具有指向 func 类型的指针
- 为什么"具有常量成员的结构"类型的指针不能指向"具有非常量成员的结构"?
- 从模板创建通用打印函数,以打印基元数据类型变量的值
- 指向 POD 类型的指针之间的静态转换与重新解释转换
- 将C++子类成员函数(虚拟实现)传递给 C 类型函数指针
- 指针数据类型变量如何包含对象?
- 获取函数中基元类型的指针
- 成员变量指针的函数参数包
- 将 std::vector::d ata 传递给函数期望类型**(双指针)
- 使用带有字符类型变量的指针
- 为什么在链表中使用指向结构的指针而不是常规结构类型变量呢
- 将数组变量分配给 C++ 中相同数据类型的指针
- 为什么我不能将一个类型(比如双精度)的变量的地址分配给 int 类型的指针?
- 为什么变量指针包含相同数据类型的地址?
- 指向用户定义类型的类的全局变量指针
- 是指向任何类型变量的指针
- 为什么指向不同char类型的指针不能混合,而不同char类型的变量可以相互转换
- 将指向不同变量类型的指针传递给函数,并在以后的赋值中重用它们