下面的函数有什么错误:
int square(volatile int *ptr)
{
return *ptr * *ptr;
}
这段代码的目的是用来返指针*ptr指向值的平方,但是,由
于*ptr指向一个volatile型参数,编译器将产生类似下面的代码:
int square(volatile int *ptr)
{
int a,b;
a = *ptr;
b = *ptr;
return a * b;
}
由于*ptr的值可能被意想不到地该变,因此a和b可能是不同的。结果,这段代码可能返不
是你所期望的平方值!(本人理解:理论上是这样,但是经过多次试验,没发现有问题,姑且先这样记着吧!)
正确的代码如下:
long square(volatile int *ptr)
{
int a;
a = *ptr;
return a * a;
}
调试的程序:
#include<stdio.h>
int square(volatile int * ptr)
{
// return *ptr**ptr;
int a,b;
a = *ptr;
b = *ptr;
//return a*b;
return a*a;
}
void main()
{
int a = 10;
int *i = &a; //指针初始化 int *i = NULL
b = square(i);
printf("the square of a is:%d\n",b);
}
(1)一般应该是
int a[5],b;
int *p=a;
int *q=&b;
为什么呢?int *P=&a;运算顺序是int *(p=&a)而不是int (*p)=(&a);一般的初始化指针可以通过以下的一些方法:
int *q=0; int *p=NULL;
初始化指针变量q,有两个作用,首先会在当前系统堆栈区给q开辟一个随机地址&q,同时将*q(指针q所指向的空间的内容)的值修改为0。
具有值NULL的指针不指向任何值。
int *p,a; p=&a;
或者定义的时候就初始化,或者int *p=&a;
2.指针里存放的虽然是地址,而且地址长度是一样的,地址长度是一样的sizeof(int *) 和sizeof(char*)在32位机器都是4个字节,但是定义不同类型的指针意义在于程序执行时需要确切地知道如何移动指针,以及如何读取指针所指单元的内容。
比如:int a[10]; int *p = a;
现在p指向数组的首地址假设这个地址是0x00000000,那么*p = a[0]那么怎么指向a[1]呢?执行p = p+1后 *p=a[1]了请注意 p=p+1不是 0x00000000+1而是0x00000000+4(在32位的机器上)为什么是加4而不是加1 因为int型在32位机器上是占四个字节所以指向下一个数组元素的地址就需要把地址移动四个字节这就是指针需要类型的原因。
int a;
char *p;
a=4;/*输出的值是否相等取决于此处的赋值范围*/
p=&a;
printf("%d\n",a);
printf("%d\n",*p);
如果a在-128~128间输出都是相等的超出范围后就不一样了。这个就像我上面说的如果是char型那么printf函数从指针开始读取1个字节输出,如果是int型那么printf函数从指针开始读取四个字节 a = 4 在内存中存储的为 0x04 0x00 0x00 x00(intel的CPU应该是这样存储的不同的cpu是不一样的好像地址依次增加)所以当当a在-128~128时printf("%d\n",a); printf("%d\n",*p); 都输出0x04 (从指针开始读取一个字节和4个字节是一样的)如果a大于128 比如在内存中存储的为 0x04 0xFF 0x00 0x00这样printf("%d\n",*p); 就只读取了 0x04,0xFF被抛弃了,所以就不一样了。
3.数组指针的初始化
如果要将一块地址空间(也就是针变量里的值置零)进行初始化,一般这么写: char pstr[20]={NULL};//初始化时这么写,或者是:
memset(pstr,NULL,sizeof(pstr));//代码中这么写,当然也可以是动态分配。 char *pstr = new char[20];//只要记住delete[]回收内存就可以了