指针的初始化
来源:互联网 发布:网络充值卡怎么用 编辑:程序博客网 时间:2024/06/11 03:57
通俗的讲,指针是一个地址,指针的初始化就是让指针指向一个确定的地址。*是指针的解引用符,意思是取指针指向的地址里的数据。
因此,int a;
int *p = &a;
// 这里是初始化,表示的是指针初始化为a的地址,实际相当于
int *p; p = &a;
*p = 10;
// 这是表示对指针解引用,想p所指向的地址写入10
从函数调用的角度来讲,一个函数在那里,并不会自己运行,只有你去调用它它才会运行。在函数调用发生时,C/C++实际做的是用实际参数代替形参。例如:
void func(int* a)
{
(* a) = 12;
}//这样操作有无问题?
int* p;
func(p); // 在这里(函数调用)的时候,实际相当于有如下过程:int *a;
a =p;(实参代替形参); *a = 10; 因此,这样操作是否有问题,关键在于p(实参)本身是否有问题。如果p本身指向了一个确切的地址,则a=p也使a(形参)实际指向了一个确切的地址,如果p本身没初始化,那么a=p也使a实际指向了一个未初始化的地址。
下面是在一篇博客上讲述的对指针初始化的几种情况:
1.一般指针的初始化
int *p=1;
char *q=’a’;
都是错误的写法,一般应该是
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 0x00(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[]回收内存就可以了
4.类指针的初始化
动态分配一个类指针,比如:
A *pA = new A
那么这时一定要保证类中具有构造函数。如果A *pA=0 (好像是调用的默认构造函数吧,这个记得不太清楚了!)
class A{
public:
A(){cout<<"A cst"<<endl;}
virtual ~A(){cout<<"A decst"<<endl;}
void doSomething(){cout<<"a is doing someting"<<endl;}
};
class B:public A{
public:
B(){cout<<"B cst"<<endl;}
~B(){cout<<"B decst"<<endl;}
//void doSomething(){cout<<"b is doing something"<<endl;}
};
int main()
{
A *aptb;(这里尽然通过编译,显然指针没有指向任何实例)
aptb->doSomething();
system("pause");
return 0;
}
上述例子中并没有错,只是这个习惯不好,如果在其他程序需要通过指针来做赋值操作什么的话,就会出现错误访问了非法内存。一般给指针一个实例只是为了防止访问了非法内存而造成错误。
- 指针的初始化
- 指针数组的初始化
- 字符指针的初始化
- 指针的初始化
- 指针的初始化
- 指针的初始化
- 指针的初始化
- 关于指针的初始化
- 指针的初始化总结
- 指针数组的初始化
- 指针的初始化微程序
- 指针的初始化问题
- 指针的初始化
- 指针数组的初始化
- 指针的初始化
- 指针的初始化
- 指针的初始化
- 指针的初始化
- 递归解决全排列问题
- strerror 线程全局变量 转换成 char* 信息
- 基本的SQL*Plus报表和命令
- 宏定义中的可变参数
- Java Random生成序列号例子
- 指针的初始化
- 11g调度(1)
- fl2440 移植u-boot-2010.09全纪录3----------DM9000网卡支持
- C#中null类型有关问题
- html中css三种常见的样式选择器
- VS2010调试X86汇编程序
- 【soj 2370】Just The Simple Fax( http://soj.me/show_problem.php?pid=2370)
- 高性能的大型系统经验 -- 将数据分类、并缓存
- Nginx