char和char *(指针)

时间:2012-10-13 21:24:02

标签: c++ pointers char dereference type-mismatch

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

第一个问题是在这一点上。如果我创建一个指针,它的值是一个memoryaddress(如果我指向一个非指针对象),但这次它在我的例子中是“哈哈”。为什么它在char *中以这种方式工作?以及如何通过cin>>为其增加价值P +

我的第二个问题是,我创建了一个q 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]分配内存; char * p = a;然后&amp; q = h»ŢĹ,所以“h”和一些混乱。但它应该是一个记忆地址!我的问题是,为什么不解决呢?

5 个答案:

答案 0 :(得分:6)

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打印单个字符。

答案 1 :(得分:2)

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

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

处理指针时的基本运算符是&amp;(地址)和*(值at)。 &amp;检索变量的地址,所以如果我们有[char q;]那么[&amp; 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;
}

我希望它有所帮助

答案 2 :(得分:1)

你应该有类似的东西:

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

答案 3 :(得分: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将保持此值

答案 4 :(得分:0)

更好的方法是:

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