12

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

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

我的第二个问题是,我创建了 aq char,它在我创建它时具有 *p 指针的值。但是它的值和地址也是“h”,但为什么呢?一定是这个char对象的内存地址!这是毫无意义的:D(mingw - gcc)

#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;
}

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

4

5 回答 5

12

想想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。但&q不同的是p,这q=*p只是复制指向的第一个字符pq它不能改变地址q——它的地址是不可改变的。For cout << &q-operator << (ostream&, char* p)期望p指向 NULL 终止的字符串 - 并&q指向包含"H"但没有人知道这个字符之后的内存 - 所以你会在屏幕上看到一些垃圾。用于cout << q打印单个字符。

于 2012-10-13T21:31:27.127 回答
3

首先要学习并永远记住指针是确保为它们分配内存,否则您的程序将无法正常运行。

您的代码实际上应该修改如下以分配内存,以便“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 的情况一样),而字符变量实际上是保存单个字符(不是一组字符)。

处理指针时的基本运算符是 &(address of) 和 *(value at)。& 检索变量的地址,所以如果我们有 [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] [\0]

    // 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;
}

我希望它有帮助

于 2012-10-13T21:46:12.727 回答
1

你应该有类似的东西:

#include <iostream>
using namespace std;

在程序的顶部。或者可以省略usingand 引用std::cinand std::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;
}
于 2012-10-13T21:45:32.167 回答
0

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

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

char *p = "some text";

然后指针 p 指向已分配和只读的内存,因为 rdata 部分肯定会由 windows 加载程序分配和准备,但正如我所说的 .rdata 不能修改

那么当你写这个时:

char q = *p;

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

++p;
q = *p;

q 将保存 'a' 而不是 'h' 因为指针是一个地址,它指向从第一个字符开始的一些字符,因此增加一个它将使指针指向第二个字符,并且 q 将保存该值

于 2018-07-21T08:15:10.070 回答
0

更好的方法是:

    int arraySize;
    cin>>arraySize;
    char *a=new char[arraySize];
    cin >> a;
于 2018-10-09T11:13:17.470 回答