指针基础问题,希望能得到好的解答

bbb16517 2007-11-08 11:05:26
假如现在定义如下变量:

char *p,*q;
那么 *p是指向指针域中的值吗?p是不是地址? &p又是什么?

char b[10];
b是不是地址?b[n]是否相当于指针?

他们之间应该如何赋值?

有时候见到 p=b, 有时候见到*p=&q(这个不太确定了,反正是 *东东=&东东)

最后一个问题:

在函数调用的时候,为什么外面传进来的是字符数组,而函数的形参是字符指针呢?为什么不用字符数组做参数?

本人对这些问题不是很清楚,希望各位能给我一个详尽的解答,谢谢~!

...全文
155 19 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
LuckySong7 2007-12-30
  • 打赏
  • 举报
回复
大家对汇编不是很清楚,如果学过汇编再看指针就非常容易了。
回11楼提的问题
那样写不矛盾。
例如:
char ch = 'a';
char *p;
p = &ch;
现在p存储的是ch这个变量的内存单元的地址,也就是说存储指针p内存单元里存的是ch的偏移地址。
*p也就相当于ch了,&(*p)就相当于&(ch)。


回楼主
p里存的是地址,&p是这个存储p指针的内存偏移地址。
可以用char **pp; pp = &p; 指针的指针pp现在存的是p的偏移地址。

char b[10];
char *p;
数组名就是指针,b是数组的首地址,也是指针,所以就可以p = b。
b[n]不是指针,它是数组b索引为n的变量值。例如char ch = b[0];
可以这样赋值p = &b[n]。
调用函数如果传得是一个字符数组也可以用 char array[]接受参数。
例如
void f(char array[])
{
}

array不是形参,是实参。

http://www.asmedu.net/
bbb16517 2007-12-30
  • 打赏
  • 举报
回复
终于弄明白了,谢谢各位
mzf333 2007-12-30
  • 打赏
  • 举报
回复
p是地址,&p是取地址.你用scanf就会知道,少了&取地址符号会出现什么问题吧...
software061104 2007-12-30
  • 打赏
  • 举报
回复
如果说*是把某样东西当做指针,&是取某东西在内存中的地址;
我想请问为什么取指针的地址时的情况:
char *p;
&(*)p应该等于p吧?//大学时候老师是这么讲的

如果&(*)p==p,也就是说&取到的地址是指针*p所指向实体的地址,而不是指针本身的地址,这是否与你说的有些矛盾?

也请大家给予解答。
---------------------------------我觉得&(*)p应该等于p是错误的,
char a;
char *p=&a;//其中的*作为一个符号而已,&作为其a的地址赋植给p
或:char *P,a;
p=&a;
这些东东基础书上都有,好好研究下,应该能知道的,呵呵--
bbb16517 2007-12-30
  • 打赏
  • 举报
回复
不对,又有点糊涂了。

指针变量,也有地址空间的吧?

int *p;
int i=1;
p=&i;

&(*p)取的是什么,&p取的又是什么?
Xuon 2007-12-30
  • 打赏
  • 举报
回复
int i=6,j;
int *p=&i;
int *q=&j;
*q=*p;
同样j=6

bbb16517 2007-12-30
  • 打赏
  • 举报
回复
哦,那也就是说,取地址符&去*p的时候是取指针指向变量实体的地址,也就是p。

搜嘎,谢谢。
Xuon 2007-12-30
  • 打赏
  • 举报
回复
提醒:
char *p
这里的*是指针操作符。

接下来如果*p出现在赋值号的右边,p为指针变量,则*表示取内容了。
例如:
int i=6,j;
int *p=&i;
j=*p;
则j=6
bbb16517 2007-12-30
  • 打赏
  • 举报
回复
to:juicee

如果说*是把某样东西当做指针,&是取某东西在内存中的地址;
我想请问为什么取指针的地址时的情况:
char *p;
&(*)p应该等于p吧?//大学时候老师是这么讲的

如果&(*)p==p,也就是说&取到的地址是指针*p所指向实体的地址,而不是指针本身的地址,这是否与你说的有些矛盾?

也请大家给予解答。
yangliushier 2007-12-30
  • 打赏
  • 举报
回复
定义指针和指针的初始化一起的
char *p;
p=s;
其中p的是地址,
*只是一个标志
bbb16517 2007-12-30
  • 打赏
  • 举报
回复
to:juicee

如果说*是把某样东西当做指针,&是取某东西在内存中的地址;
我想请问为什么取指针的地址时的情况:
char *p;
&(*)p应该等于p吧?//大学时候老师是这么讲的

如果&(*)p==p,也就是说&取到的地址是指针*p所指向实体的地址,而不是指针本身的地址,这是否与你说的有些矛盾?

也请大家给予解答。
slave_cool 2007-11-08
  • 打赏
  • 举报
回复
指针有它本身存储的地方,是左值.
数组名是编译时常量,没有它本身存储的地方.



[数组和指针的分配]

数组是开辟一块连续的内存空间,数组本身的标示符代表整个数组,可以用sizeof取得真
实的大小

指针则是只分配一个指针大小的内存,并可把它的值指向某个有效的内存空间

[空间的分配]

[全局的和静态的]
char *p= "hello ";
一个指针,指向只读数据块(section)里的 "hello ",可被编译器放入字符串池(也就是说,
你在写一个char *q= "hello ",可能和p共享数据)

char a[]= "hello ";
一个数组,分配在可写数据块(section),不会被放到字符串池中

[局部]
char *p= "hello ";
一个指针,指向只读数据块(section)里的 "hello ",可被编译器放入字符串池(也就是说,
你在写一个char *q= "hello ",可能和p共享数据),另外,在函数中可以返回它的地址,也就
是说,指针是局部变量,他指向的数据却是全局的.

char a[]= "hello ";
一个数组,分配在堆栈上,初始化由编译器进行(短的话直接用指令填充,长的就从全局字
符串表拷贝),不会被放到字符串池中(但是却可能从字符串池中拷贝过来),也不应该返回
它的地址.

[代码中的字面字符串]
printf( "%s\n ", "hello ");
这两个字面常量( "%s\n "和 "hello "),都在只读数据块里

[用途]
1.全局指针
用于不需要修改内容,却可能会修改指针的情况(当然,不修改也没人反对)

2.全局数组,用于不需要修改地址,却需要修改内容的场合

3.既需要修改指针,有需要修改内容怎么办呢?定义一个数组,在定义一个指针指向它就可
以了

4.函数中如果不需要修改字符串的内容,应该尽量用char*p= "xxx "这种写法.初始化的局
部字符数组影响效率,一般应该尽量避开(应该使用的情况下则不要犹豫)




  指针是C/C++语言的特色,而数组名与指针有太多的相似,甚至很多时候,数组名可以作为指针使用。于是乎,很多程序设计者就被搞糊涂了。而许多的大学老师,他们在C语言的教学过程中也错误得给学生讲解: "数组名就是指针 "。很幸运,我的大学老师就是其中之一。时至今日,我日复一日地进行着C/C++项目的开发,而身边还一直充满这样的程序员,他们保留着 "数组名就是指针 "的误解。

  想必这种误解的根源在于国内某著名的C程序设计教程。如果这篇文章能够纠正许多中国程序员对数组名和指针的误解,笔者就不甚欣慰了。借此文,笔者站在无数对知识如饥似渴的中国程序员之中,深深寄希望于国内的计算机图书编写者们,能以 "深入探索 "的思维方式和精益求精的认真态度来对待图书编写工作,但愿市面上多一些融入作者思考结晶的心血之作!

  魔幻数组名

  请看程序(本文程序在WIN32平台下编译):

1. #include <iostream.h>
2. int main(int argc, char* argv[])
3. {
4.  char str[10];
5.  char *pStr = str;
6.  cout < < sizeof(str) < < endl;
7.  cout < < sizeof(pStr) < < endl;
8.  return 0;
9. }
  1、数组名不是指针

  我们先来推翻 "数组名就是指针 "的说法,用反证法。

  证明 数组名不是指针

  假设:数组名是指针;

  则:pStr和str都是指针;

  因为:在WIN32平台下,指针长度为4;

  所以:第6行和第7行的输出都应该为4;

  实际情况是:第6行输出10,第7行输出4;

  所以:假设不成立,数组名不是指针

  2、数组名神似指针

  上面我们已经证明了数组名的确不是指针,但是我们再看看程序的第5行。该行程序将数组名直接赋值给指针,这显得数组名又的确是个指针!

  我们还可以发现数组名显得像指针的例子:

1. #include <string.h>
2. #include <iostream.h>
3. int main(int argc, char* argv[])
4. {
5.  char str1[10] = "I Love U ";
6.  char str2[10];
7.  strcpy(str2,str1);
8.  cout < < "string array 1: " < < str1 < < endl;
9.  cout < < "string array 2: " < < str2 < < endl;
10.  return 0;
11. }
  标准C库函数strcpy的函数原形中能接纳的两个参数都为char型指针,而我们在调用中传给它的却是两个数组名!函数输出:

string array 1: I Love U
string array 2: I Love U
  数组名再一次显得像指针!

  既然数组名不是指针,而为什么到处都把数组名当指针用?于是乎,许多程序员得出这样的结论:数组名(主)是(谓)不是指针的指针(宾)。

  整个一魔鬼。

  揭密数组名

  现在到揭露数组名本质的时候了,先给出三个结论:

  (1)数组名的内涵在于其指代实体是一种数据结构,这种数据结构就是数组;

  (2)数组名的外延在于其可以转换为指向其指代实体的指针,而且是一个指针常量;

  (3)指向数组的指针则是另外一种变量类型(在WIN32平台下,长度为4),仅仅意味着数组的存放地址!

  1、数组名指代一种数据结构:数组

  现在可以解释为什么第1个程序第6行的输出为10的问题,根据结论1,数组名str的内涵为一种数据结构,即一个长度为10的char型数组,所以sizeof(str)的结果为这个数据结构占据的内存大小:10字节。

  再看:

1. int intArray[10];
2. cout < < sizeof(intArray) ;
  第2行的输出结果为40(整型数组占据的内存空间大小)。

  如果C/C++程序可以这样写:

1. int[10] intArray;
2. cout < < sizeof(intArray) ;
  我们就都明白了,intArray定义为int[10]这种数据结构的一个实例,可惜啊,C/C++目前并不支持这种定义方式。

  2、数组名可作为指针常量

  根据结论2,数组名可以转换为指向其指代实体的指针,所以程序1中的第5行数组名直接赋值给指针,程序2第7行直接将数组名作为指针形参都可成立。

  下面的程序成立吗?

1. int intArray[10];
2. intArray++;
  读者可以编译之,发现编译出错。原因在于,虽然数组名可以转换为指向其指代实体的指针,但是它只能被看作一个指针常量,不能被修改。

  而指针,不管是指向结构体、数组还是基本数据类型的指针,都不包含原始数据结构的内涵,在WIN32平台下,sizeof操作的结果都是4。
顺便纠正一下许多程序员的另一个误解。许多程序员以为sizeof是一个函数,而实际上,它是一个操作符,不过其使用方式看起来的确太像一个函数了。语句 sizeof(int)就可以说明sizeof的确不是一个函数,因为函数接纳形参(一个变量),世界上没有一个C/C++函数接纳一个数据类型(如 int)为 "形参 "。

  3、数据名可能失去其数据结构内涵

  到这里似乎数组名魔幻问题已经宣告圆满解决,但是平静的湖面上却再次掀起波浪。请看下面一段程序:

1. #include <iostream.h>
2. void arrayTest(char str[])
3. {
4.  cout < < sizeof(str) < < endl;
5. }
6. int main(int argc, char* argv[])
7. {
8.  char str1[10] = "I Love U ";
9.  arrayTest(str1);
10.  return 0;
11. }
  程序的输出结果为4。不可能吧?

  一个可怕的数字,前面已经提到其为指针的长度!

  结论1指出,数据名内涵为数组这种数据结构,在arrayTest函数体内,str是数组名,那为什么sizeof的结果却是指针的长度?这是因为:

  (1)数组名作为函数形参时,在函数体内,其失去了本身的内涵,仅仅只是一个指针;

  (2)很遗憾,在失去其内涵的同时,它还失去了其常量特性,可以作自增、自减等操作,可以被修改。

  所以,数据名作为函数形参时,其全面沦落为一个普通指针!它的贵族身份被剥夺,成了一个地地道道的只拥有4个字节的平民。

  以上就是结论4。

  结束语

  最后,笔者再次表达深深的希望,愿我和我的同道中人能够真正以谨慎的研究态度来认真思考开发中的问题,这样才能在我们中间产生大师级的程序员,顶级的开发书籍。每次拿着美国鬼子的开发书籍,我们不免发出这样的感慨:我们落后太远了。



Pointer
Holds the address of data
Array
Holds data

Pointer
Data is accessed indirectly, so you first retrieve the
contents of the pointer, load that as an address (call it "L "),
then retrieve its contents.
If the pointer has a subscript [i] you instead retrieve the
contents of the location 'i ' units past "L "
Array
Data is accessed directly, so for a[i] you simply retrieve the
contents of the location i units past a.

Pointer
Commonly used for dynamic data structures
Array
Commonly used for holding a fixed
number of elements of the same type of data

Pointer
Commonly used with malloc(), free()
Array
Implicitly allocated and deallocated

Pointer
Typically points to anonymous data
Array
Is a named variable in its own right

yu2007428 2007-11-08
  • 打赏
  • 举报
回复
看看书就能明白了,
bboo 2007-11-08
  • 打赏
  • 举报
回复
>>一般来说 p = &p;
p 跟 &p 是两回事
jsjacky1101 2007-11-08
  • 打赏
  • 举报
回复
同意楼上的,还是建议楼主多看一下书,这些基本知识书上都有.
没别的意思,只是提个建议!^_^
juicee 2007-11-08
  • 打赏
  • 举报
回复
记住*是把某样东西的值当作指针,取它的值当作内存中地址,取那个地址中存储的值,具体取值空间看指针类型。
&是取某样东西在内存中的地址。
当然在声明的时候他们都只是一个符号而已,没有实际的动作,声明时*表示被声明的标识符是一个指针类型,而&表示其为一个引用类型。
比如int *p;声明一个指向int型的指针p,如果你要取得p所指向的地址中存储的值,那么就用*p,如果你要取得存储p本身的内存地址的值,那就用&p;
xugang_2001 2007-11-08
  • 打赏
  • 举报
回复
char *p,*q;
那么 *p是指向指针域中的值吗?p是不是地址? &p又是什么?

=================================
*p是指向该地址的指, p本身是代表一个地址, &p是存放该地址的内存指,一般来说 p = &p;

char b[10];
b是不是地址?b[n]是否相当于指针?
==============================
b是b[10]的首地址,相当于b=&b[0]; b[n]不是指针,而是具体的值

他们之间应该如何赋值?
=======================
p = b = &b[0];

在函数调用的时候,为什么外面传进来的是字符数组,而函数的形参是字符指针呢?为什么不用字符数组做参数?
=====================================================
func(char * pstr),这里以char* pstr作为形参,但是外部传入可以是 func(b) 或者 func(&b[0]),也就是说只要外部传入可以间接转换成函数声明时的形参就可以了,这里函数传递的时候会做一个隐形的转换。比如 pTmp = b/&b[0]; pstr = pTmp;
mx81831 2007-11-08
  • 打赏
  • 举报
回复
我觉得2楼回答的很好。
LZ可以好好理解一下。
tiantangniao232 2007-11-08
  • 打赏
  • 举报
回复
char *p,*q;
那么 *p是指向指针域中的值吗?p是不是地址? &p又是什么?

=================================
*p是指向该地址的指, p本身是代表一个地址, &p是存放该地址的内存指,一般来说 p = &p;
-------------------------------------------------------------------------------------------
p = &p???
&p应该是指针 p 本身在内存单元中的地址吧!

65,203

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧