指针的小细节

初始化赋值自增

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 
 4 int main()
 5 {
 6     int a = 3,*p1,*p2;
 7     p1 = &a;
 8     p2 = p1;//同类型可赋值 
 9     printf("a = %d,p1 = %d,p2 = %d\n",a,*p1,*p2);
10     
11     *p1 = 10;//实际就是改变了a地址所包含的值 间接改变a值 
12     printf("a = %d,p1 = %d,p2 = %d\n",a,*p1,*p2);
13     
14     *p2 = 33;//实际就是改变了a地址所包含的值 间接改变a值 
15     printf("a = %d,p1 = %d,p2 = %d\n",a,*p1,*p2);
16     
17     a = 89;//直接改变a自身的值 
18     printf("a = %d,p1 = %d,p2 = %d\n",a,*p1,*p2);
19     
20     *p1 = *p1 + 1;//自增 
21     printf("a = %d,p1 = %d,p2 = %d\n",a,*p1,*p2);
22     
23     ++*p1;
24     printf("a = %d,p1 = %d,p2 = %d\n",a,*p1,*p2);
25     
26     (*p1)++;
27     printf("a = %d,p1 = %d,p2 = %d\n",a,*p1,*p2);
28     
29     //下面是对地址加一,是以一个字节增加的,所以p1不再指向a了,*p1也就变了 
30     *p1++;
31     printf("a = %d,p1 = %d,p2 = %d\n",a,*p1,*p2);
32     
33     --*p1;
34     printf("a = %d,p1 = %d,p2 = %d\n",a,*p1,*p2);
35     //a和*p2并不会改变 
36     
37     --*p2;
38     printf("a = %d,p1 = %d,p2 = %d\n",a,*p1,*p2); 
39     return 0;
40 }
View Code

经典指针例子

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 
 4 void swap1(int x,int y)
 5 {
 6     int t;
 7     t = x;
 8     x = y;
 9     y = t;
10 }
11 
12 void swap2(int *px,int *py)
13 {
14     int t;
15     t = *px;
16     *px = *py;
17     *py = t;
18 }
19 
20 void swap3(int *px,int *py)
21 {
22     int *t;
23     t = px;
24     px = py;
25     py = t;
26 }
27 
28 int main()
29 {
30     int a = 1,b = 2;
31     int *pa = &a,*pb = &b;
32     swap1(a,b);
33     cout << a << " " << b << " " << *pa << " " << *pb << endl;
34     
35     a = 1,b = 2;
36     swap2(pa,pb);
37     cout << a << " " << b << " " << *pa << " " << *pb << endl;
38     
39     a = 1, b = 2;
40     swap3(pa,pb);
41     cout << a << " " << b << " " << *pa << " " << *pb << endl;
42      
43     return 0;
44 }
View Code

指针,数组,地址之间的关系

在定义数组时,编译器必须分配基地址和足够的存储空间,以存储数组的所有元素。

数组基地址是内存中存储数组的起始位置,也是数组第一个元素的地址。

数组和指针

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define rep(i,x,y) for(int i = x;i <= y;i++) 
 4 int main()
 5 {
 6     int a[100],*p,sum = 0;
 7     
 8     rep(i,0,99) 
 9     a[i] = i + 1;
10     
11     p = a;
12     //p = &a[0];等价于上面 
13     cout << *p << endl; 
14     
15     p = a + 1;
16     //p = &a[1];等价于上面 
17     cout << *p << endl; 
18     //第一种求和 
19     sum = 0;
20     for(p = a;p <= &a[99];p++)
21     sum += *p;
22     cout << sum << endl;
23     
24     //第二种求和 
25     sum = 0;
26     for(int i = 0;i < 100;i++)
27     sum += *(a + i);
28     cout << sum << endl;
29     
30     //第三种求和
31     p = a;
32     sum = 0;
33     for(int i = 0;i < 100;i++)
34     sum += p[i];
35     cout << sum << endl;
36     //数组名可以用指针形式 
37     return 0;
38 }
View Code

有个本质区别

数组a是指针常量,不是变量 a = p,a++,a+=2;都是非法的,不能改变a的值

使用指针计算数组元素个数和数组元素的存储单元数。

指针运算是c的重要特征之一

如果指针变量p指向特定类型变量,那么表达式p+1代表该类型的下一个变量内存地址 p+i,p++,p+= i;都是有意义的

如果p和q指向数组元素指针,p - q产生一个int型的值,该值表示p和q之间的数组元素个数。同样指针加一或减一并非指针值+1或-1

而是加上或减去该指针所指的哪个变量数据类型长度,即它所指的存储单元所占用字节数。

如果p指向数组a[1]的指针,int型的,a[1]地址2004,p--值是2002

 1 #include<stdio.h> 
 2 
 3 int main()
 4 {
 5    double a[2],*p,*q;
 6    p = &a[0];
 7    q = p + 1;
 8    printf("%d\n",q-p);//计算p,q之间的元素个数 
 9    //printf("%d\n",(int) q - (int) p);//计算指针p和q之间的字节数 
10    return 0;
11  } 
View Code

 

数组名作为函数参数

数组的形参a实际是一个指针。当进行参数传递时,主函数传递的是数组a的基地址,数组本身不被复制。

编译器允许在作为参数声明的指针中使用数组方括号

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 
 4 int sum(int a[],int n)
 5 {
 6     int s = 0;
 7     for(int i = 0;i < n;i++)
 8     s += a[i];
 9     return s;
10 }
11 int main()
12 {
13     int a[100];
14     for(int i = 0;i < 100;i++)
15     a[i] = i + 1;
16     cout << sum(a,100) << endl;
17     return 0;
18 }

 

posted @ 2019-09-22 15:51  ChunhaoMo  阅读(202)  评论(0编辑  收藏  举报