2012-10-13 152 views
4

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

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

第二个问题是,我创建A Q炭,其在我创建它的点的* P指针的值。但它的价值和地址也是“h”,但为什么?它必须是这个char对象的内存地址!这是毫无意义:d(MinGW的 - GCC)

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

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

+1

这不是安全的。 'p'没有任何内存供您输入。 – chris

回答

5

思考的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) misunderstaning。此运算符期望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打印单个字符。

+0

所以,你说cin不分配内存,那么我的“哈哈”在哪里?指针如何包含整个字符串? q是一个简单的字符变量,所以它可以包含p的任何字符,并且我没有分配我的“哈哈”文本,所以这就是为什么我的“h”没有内存地址?很明显,但我有一个问题然后: 当我将字符复制到q(char q = * p),它不是真正的复制,它只是指向该数据,这是不分配?所以问题无处不在,我的哈哈文本没有分配,所以我不能有任何地址? – Iburidu

+0

好的,我用int创建了一个程序,并且int已经被分配,我可以cout << p;它会写回地址。程序简短:“int a [10]; int * p = a; cin >>(char *)p; cout << p <<”,“<< atoi((char *)p);” – Iburidu

+1

因为你没有赋予'p'任何值甚至'0' - 那么它指向一些随机地址。您在程序中将“哈哈”复制到一些随机内存中 - 它可能会导致任何事情,这是未定义的行为 - 甚至可能会导致向您的上司发送电子邮件,说明您有更好的工作 - 但也可能发生这种随机内存没有使用 - 所以它看起来像你的程序工作正常。 – PiotrNycz

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 

&qchar*类型,一个指针到char的。发送char*值到cout不会打印指针(存储器地址)的值;它会打印它指向的字符串。 (虽然我得到一些奇怪的结果,当我跑我自己,我可能失去了一些东西)如果你想看到指针的值,将其转换为void*

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

(或者你可以使用的一个且该C++ - 特定铸件;我不知道这是最好的)

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

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

return 0; 
} 
+0

是的,在我的代码上,我采取了前两行,但它明显,所以我没有放在这里。我明白了,但cout <<&q必须是cout << p然后,对吧?而不是。 &q =“h”和p =“haha” – Iburidu

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),而字符变量实际上只包含一个字符(不是一组字符)。

处理指针时的基本运算符是&(的地址)和*(值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; 
} 

意见,我希望它可以帮助

+0

是的,很明显,如果我将位置分配给p,那么它会向&q写入“h和一些乱码”,但是如果我不将位置分配给p, h“,与* p相同。所以q =&q? :D但我认为PiotrNycz是正确的,这是因为“哈哈”没有分配,所以它没有内存地址,所以&q(这是p)不能指向任何地方,但为什么它停止后“h “ 然后? – Iburidu

+0

@Iburidu在您的机器/编译器上发生的特定情况不是一般情况。将数据存储在未分配的内存空间中的结果是不可预知的。在你的情况下,内存已经满了零,所以打印字符串开始&q恰好打印出“h”只是偶然的,没有更多。 – Hisham

+0

好吧,我通过添加char a [100]来分配; int * p = a;但为什么p ==“哈哈”,如果它应该是一个内存地址(&a [0])? – Iburidu