指针与数组

声明:char、string类型的数组和指针有另外的特性,请参看:
1 、指向变量的指针与指向数组的指针区别 
对普通变量
对数组
int a;
int *p = &a;
int a[8];
int *p = a;
int a;
int *p;
p = &a;
int a[8];
int *p;
p = a;
 
2 、指针类型与指针所指类型区别
 
指针类型( p 的类型)
指针所指类型( *p 的类型)
 
去掉指针名剩下部分
去掉 * 和指针名后剩下部分
int *p
int *
int
int **p
int **
int *
int (*p)[8]
int (*)[8]
int ( )[8]
int *p[8]
int *[8]
int [8]
int *(*p)[8]
int *(*)[8]
int *( )[8]
void *p
void( 空类型 )
不指向任何类型
 
  理解:
对于 p 来说,修饰它的是 int * ,可以理解为 ( int * ) p ,所以它的类型是 int*
对于 * p 来说,修饰它的是 int ,可以理解为 ( int ) (* p) ,所以它的类型是 int 型。
 
3 、数组与指针区别
int a[20];
int *p = a;
求地址
求内容(值)
a = (a+0) = &a[0]= p = (p+0) = &p[0]
*a = a[0] = *(a+0) = *p = p[0] = *(p+0)
(a+1) = &a[1] = (p+1) = &p[1]
a[1] = *(a+1) = p[1] = *(p+1)
(a+i) = &a[i] = (p+i) = &p[i]
a[i] = *(a+i) = p[i] = *(p+i)
 
4 、指针运算几种形式区别
int a[10] = {1, 3, 5, 7, 9, 11 } ;
int * p = a ;
原型
1
2
p 变否
备注
p++
先取 p 所指地址
p
再指向数组下个元素地址
p+1
p 值改变
不能写成 a++
先求 &a[0] 
求地址
再指向 a[1] ,结果为 &a[1]
结果为地址
*p++
先取 p 所指内容(值)
*p
再指向数组下个元素
p+1
p 值改变
不能写成 *a++
先求 a[0]  
求值
再指向 a[1] ,结果为 &a[1]
结果为地址
(*p)++
先取 p 所指内容(值)
*p
再将该值加 1
*p+1
p 值不变
可以写成 (*a)++
先求 a[0]
 
求值
再将 a[0] 内容加上 1 ,即为 1+1 2
结果为值
 
5 、指针类型匹配与转换
1 )指针类型必须匹配:不要把指针和整形数混淆。
例如:
int a=20;
int *p;
 
a     int 型,整形数
&a    int* 型,整形指针, a 的地址
p     int* 型,整形指针
*p    int 型,整形数
 
p=&a;       // 正确, p &a 都是 int*
p=a;        // 错误, p int* 型, a int 型,二者不匹配
*p=a;       // 正确, *p a 都是 int  
*p=&a;      // 错误, *p int 型, &a int* 型,二者不匹配
 
2 )指针类型要和实际存储匹配
例如:
float f=3.8;
float *fp;
int i=8;
int *ip;
 
f    float
&f   float* 型, f 的地址
fp   float*
*fp  float
i    int
&i   int* 型, i 的地址
ip   int*
*ip  int
 
ip=&i;     // 正确, ip &i 都是 int*
ip=i;      // 错误, ip int* 型, i int 型,二者不匹配
*ip=i;     // 正确, *ip i 都是 int
*ip=&a;    // 错误, *ip int 型, &i int* 型,二者不匹配
fp=&f;     // 正确, fp &f 都是 int*
fp=f;      // 错误, fp float* 型, f float 型,二者不匹配
*fp=f;     // 正确, *fp f 都是 float
*fp=&f;    // 错误, *fp int 型, &f float* 型,二者不匹配
 
ip=&f;    // 错误, ip int* 型, &f float* 型,二者不匹配
fp=&i;    // 错误, fp float* 型, &i int* 型,二者不匹配
ip=f;       // 错误, ip int* 型, f float 型,二者不匹配
fp=i;       // 错误, fp float* 型, i int 型,二者不匹配
 
3 )不匹配的指针类型,可以强制转换(不提倡使用)
例如:
int a=20;
int *p=a;
p=a;            // 错误,类型不匹配
p=(int*)a;      // 正确,强制将 a int 转换为 int*
*p=&a;          // 错误,类型不匹配
*p=(int)&a      // 正确,强制将 &a int* 型转换为 int
float f=3.8;
float *fp=&f;
int *ip=&f;         // 初始化指针出错, *ip &f 类型不匹配
int *ip=(int*)&f;   // 初始化正确,强制将 &f float* 型转换为 int*
 
6 、字符数组与字符指针
char* s1="hello";
char s2[]="world";
两个表达式的含义是一样的 .
如果讲不同之处的话 ,VC6 中编译时 , 对这两种定义进行了不同的处理 ;
char *s1 = "hello"; 中的 "hello", 编译时指针指向的区域位于 PE 文件的 .rdata 节中 , 是只读的 .
不信的话 , 你可以试试 :
main()
{
char *s1="hello";
char s2[]="world";

*(s2+2)='x'; //
正确
*(s1+2)='x'; //
执行时出错 .
}
 
1 )严格的说两个表达的意思是不完全一样的,因为前者是个字符串指针,这个指针 S1 所存的地址就是存储字符串前 8 个字节即 hello 的那个地址。
2 而后者是字符数组。每个字符都有一个独立的地址。
 
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

电脑小玩家

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值