字符和字符*(指针)

char and char* (pointer)

本文关键字:字符 指针      更新时间:2023-10-16

我想了解指针是如何工作的,所以我创建了这个小程序。 首先,我创建一个指向字符的 P 指针。

第一个问题是在这一点上。如果我创建一个指针,它的值是一个内存地址(如果我将其指向非指针对象),但这次在我的示例中它是"哈哈"。为什么它在字符*中以这种方式工作?我如何用 cin>> p 为它增加价值?

我的第二个问题是,我创建了一个 q char,它在我创建它的点处具有 *p 指针的值。但是它的值和地址也是"h",但为什么呢?它必须是这个字符对象的内存地址!这是毫无意义的:D(明威 - 海湾合作委员会)

#include <iostream>
int main() 
{
/* char *p;
cin >> p;                      //forexample: haha */
char * p = "haha";
char q = *p;
std::cout << "&q = " << &q << std::endl;   //&q = h
std::cout << "q  = " <<  q << std::endl;   //q = h
return 0;
}

更多:如果我先用字符 a[100]; 字符 *p=a; 然后 &q = h»ŢĹ,所以"h"和一些混乱。 但它应该是一个内存地址! 我的问题是,为什么它不是地址呢?

char* p;视为内存中的地址。您没有初始化此指针,因此它不指向任何内容,因此无法使用它。

为了安全起见:将指针初始化为零:

char *p = 0; // nullptr in C++11

或初始化为一些自动

void foo() {
char a[100];
char *p = a;
}

或全局内存:

char a[100];
void foo() {
char *p = a;
}

或获取动态内存:

char* p = new char [100];

然后,您可以使用 p(如果不是 NULL)来读取数据并从 p 读取...


因为你对operator >> (std::istream&, char* p)的误解.该运算符期望p指向一些内存(自动,全局,动态 - 无论如何) - 它不会自行分配内存。 它只是从输入流中读取字符,直到空格并将其复制到p指向的内存中 - 但p必须已经指向某个内存。


用于获取char q;的地址。当然你可以取q的地址:&q,它的类型是char* p。但是&qp不同,这个q=*p只是复制p指向q的第一个字符,它不能改变q的地址——它的地址是不可更改的。对于cout << &q-operator << (ostream&, char* p)期望p指向 NULL 终止的字符串 - 并且&q指向包含"H"但这个字符后面是什么没有人知道的内存 - 所以你会在屏幕上得到一些垃圾。使用cout << q打印单个字符。

关于指针,要学习并始终记住的第一件事是确保为它们分配内存,否则程序将无法正常运行。

实际上,您的代码应该按如下方式修改以分配内存,以便"cin"可以将用户输入写入分配的内存中:

int main() {
char *p = new char[1024];      // allocate memory so cin
cin >> p;                      //forexample: haha
char q = *p;
cout << "&q = " << &q << endl; 
cout << "q = " << q << endl;   
return 0;
}

现在,字符指针是一个变量,指向内存中保存一组字符的位置(不一定是一个字符,可能不止一个,也许没有,如特殊值 null 的情况),而字符变量实际上保存单个字符(不是一组字符)。

处理指针时的基本运算符是 &(地址) 和 *(值在)。&检索变量的地址,所以如果我们有[char q;],那么[&q]将是一个字符指针。另一方面,* 检索给定指针处的值,因此如果我们有 [char *p;],那么 [*p] 将是内存中 p 指向的字符。

现在回到您的示例,注释内联用于说明

int main() {
// allocate a place of 1024 character in memory
// and let p points to that place
char *p = new char[1024];      
// call cin to read input from the user and save
// it in memory at the location pointed to by p
// NOTE: cin would put an extra NULL character 
// at the end to terminate the string
cin >> p;                      //forexample: haha
// Now p would be pointing to a piece of memory like this
// [h] [a] [h] [a] []
// use the value at operator to de-reference the pointer
// p, the result would be a single character which 
// will be the first character in memory p is pointing at
char q = *p;
// printing the value of (the address of q)
// Note you have a problem here as cout will
// be handling the memory starting at the address 
// of q as a string while it is not, so you
// will get a string starting with "h" and followed
// by whatever is there in memory by the time of execution
cout << "&q = " << &q << endl;
// printing the value of the character q
cout << "q = " << q << endl; 
return 0;
}

我希望它有所帮助

你应该有这样的东西:

#include <iostream>
using namespace std;

在程序的顶部。或者可以省略using并引用std::cinstd::cout.

int main() {
char *p;

p是一个指针,但你还没有初始化它,所以它可能指向任何地方或任何地方。您需要初始化它,例如:

p = new char[100];

cin >> p;                      //forexample: haha

如果您已将p初始化为指向某处,这没关系 - 除了如果您输入太多数据,您可能会溢出它指向的缓冲区。对于像这样的简单测试程序来说,这是可以的,但在实践中,您需要采取措施来避免它。

char q = *p;
cout << "&q = " << &q << endl; //&q = h

&q的类型是char*,一个指向char的指针。将char*值发送到cout不会打印指针的值(内存地址);它打印它指向的字符串。(虽然当我自己运行它时,我得到了一些奇怪的结果;我可能错过了一些东西。如果要查看指针值,请将其转换为void*

count << "&q = " << (void*)&q << endl;

(或者,您可以使用特定于C++的强制转换之一;我不确定哪个是最好的。

cout << "q = " << q << endl;   //q = h

这里q只是一个char,所以这打印了它作为一个字符的值:h

return 0;
}

字符串literate将存储在.rdata部分中,该部分将被读取,因此使用std CIN读取它会使程序崩溃

第二件事,当你写这个的时候:

char *p = "some text";

然后指针 p 指向一个已分配和只读的内存,因为 rdata 部分肯定会由 Windows 加载器分配和准备,但正如我所说,.rdata 无法修改

那么当你写这个的时候:

char q = *p;

您只需将 q 分配给 p 中的第一个字符,因为 * 返回指针当前指向的值,因此如果您尝试这样做:

++p;
q = *p;

Q 将保留"a"而不是"h",因为指针是一个指向从第一个开始的一些字符的地址,因此增加 1 将使指针指向第二个字符,Q 将保存此值

更好的方法是:

int arraySize;
cin>>arraySize;
char *a=new char[arraySize];
cin >> a;