论坛风格切换
您好,欢迎光临本站!   登录 注册新用户
  • 3558阅读
  • 7回复

[教程]C语言学习笔记----指针【一】 [复制链接]

上一主题 下一主题
 

发帖
6808
黑豆
158
威望
24650
贡献值
0
交易币
0
红豆
426
只看楼主 倒序阅读 0 发表于: 2013-04-21

指针变量

1 指针就是内存地址;
系统对变量的访问形式有两种:
直接访问:按变量地址存取变量值的方式
间接访问:      



如上所示,int i=3,然后特殊变量P存放的内容是变量i的地址,利用P来访问变量i2000是变量i空间的地址。3i的值。变量P指向变量iP是指向变量i的指针变量。
2 定义指针变量int *P,*p1;  float *P;
   注意:1*号毫无意义,如果硬要说意义的话就是:C语言规定所有变量必须先定义后使用,指针变量也是这样,但是为了表示指针变量的特殊性,所以就加了一个*号。
      (2)一个指针变量只能指向同一个数据类型,定义*Pint型,那就不能指向float
3指针变量赋值int i=3; int *P; P=&i;   &是取地址运算符,取i的空间的地址给P。所以P里面存放的是i空间的地址。*Pi空间存放的值,即*P=3
注意:&ii空间的地址,是一个整型数据,这个数据赋值给P,但是不能直接给P赋值,如P=1000是不行的,因为变量的地址是由编译系统分配的,用户是不知道的,更不能随便给赋地址值。
(4) &*辨析:
main()
{
   int i=100; int *P;  
   p=&i;
   printf("%d\n",i);  直接访问变量
   printf("%d\n",*P);  间接访问变量
}  
A. int *P 中的*没有意义,只能说明定义的是一个指针变量,printf(*P)中的*是指针运算符。
B.&*P的计算&*的优先级一样,自右向左结合,先计算*P100,然后计算&&100.
  *&P的计算是一样的,先计算& 再计算*
C. 指针加1,不是单纯的加1,而是加一个所指变量的字节数。假设整型指针变量P所指的地址是2000,执行P++后,P的地址是2002,因为整型占两个字节。


(5) 指针作为函数参数;
  1. #include <stdio.h>
  2. void swap(int *p1,int *p2)
  3. {
  4.    int t;
  5.    t=*p1; *p1=*p2; *p2=t;
  6. }
  7. main()
  8. {
  9.     int a,b; int *q1,*q2;
  10.     q1=&a; q2=&b;
  11.     printf("请输入两个数字");
  12.    scanf("%d,%d",&a,&b); printf("%d,%d\n",a,b);
  13.     printf("%d,%d\n",q1,q2);
  14.     if(a>b) { swap(q1,q2); }
  15.     printf("%d,%d\n",a,b);printf("%d,%d\n",q1,q2);    
  16. }

这个实例看出:a,b的值发生了交换,但是q1q2的值没有交换。在Swap()函数中*p1*p2发生了交换,他们的值变换了,但是p1p2的值并没有发生交换,因为p1p2是地址,而*p1*p2是值,我们只对值执行了交换。同理,q1q2也没有发生变化。
如果不用指针变量作为实参,而用普通变量的话,swap交换后是不能返回到main函数中的,因为定义变量t,*p1*p2都是是在swap()函数中定义的,他们都是局部变量。


数组的指针和指向数组的指针变量(一维数组)

(1)一个数组的地址是这个数组的起始地址(&a[0],这个起始地址成为数组的指针。
(2)指向数组的指针变量:这个变量中存放了数组的起始地址。要注意,这个指针变量是P而不是*P
(3)赋值int a[10],*p;   p=&a[0]; 将指针变量P指向数组a[0],&a[0]是数组a的首地址,所以P指向了数组a
(4) 1.如果数组为int型,则指针变量必须指向int类型;
   2. 数组名代表数组的首地址; p=a;  p=&a[0]; 这两个语句的作用是一样的。即a=&a[0]
   3. 允许用一个已经定义过的数组的地址作为定义指针时的初始化值。
       float score[20]; float *p=score;将数组score的首地址赋给p,而不是*p*在这儿是毫无意义的。
(5)访问地址p是指向数组a的指针变量,那么数组元素a[5]的地址有如下几种表示形式
             p+5 , a+5 ,&a[5];
(6)访问元素: 也有三种方法: *(p+5) , *(a+5), a[5];
(7)指针变量能带下标p是指向一个数组的指针变量。 p[5](指针带下标)等价于*p+5
(8)假设p指向数组a,指针变量可以取代数组名操作,如p++是可以的,数组名a也可以表示数组的首地址,不过他属于常量,如a++是错误的。
(9)用指针变量对数组中的元素逐个访问时,一般有两种方法:
     *p++:指针变量p的值发生了变化。
     *(p+i):指针变量p的值没有发生变化。
(10)引用以数组元素,有两种方法:下标法和指针发。
     任意输入10个数,将10个数按逆序输出:
  下标法
  1. main()
  2. {
  3.    int a[10],i;
  4.    for(i=0;i<10;i++)
  5.      scanf("%d",&a);
  6.    printf("\n");
  7.    for(i=9;i>=0;i--)
  8.    printf("%d",a);
  9. }
数组名法
  1. main()
  2. {
  3.    int a[10],i;
  4.    for(i=0;i<10;i++)
  5.      scanf("%d",&a);
  6.    printf("\n");
  7.    for(i=9;i>=0;i--)
  8.    printf("%d",*(a+i));
  9. }
指针变量法A
  1. main()
  2. {
  3.    int a[10],i,*p;
  4.    for(i=0;i<10;i++)
  5.      scanf("%d",&a);
  6.    printf("\n");
  7.    for(i=9;i>=0;p--)
  8.    printf("%d",*(p+i));
  9. }
指针变量法B

main()
  1. {
  2.    int a[10],i,*p;
  3.    p=a;
  4.    for(i=0;i<10;i++)
  5.      scanf("%d",&a);
  6.    printf("\n");
  7.    for(p=a+9;p>=a;p--)
  8.    printf("%d",*p);
  9. }


(11)数组指针作为函数参数有两种形式:
      形参、实参都是数组名 :这种方法一般是不用的。
  1. main()
  2. {
  3.    int a[10];
  4.    ..
  5.    sort(a,10)   //数组名作为实参
  6. }
  7. sort(int x[],int n)   //数组名作为形参
  8. {
  9.     ....
  10. }
形参是指针变量,实参是数组名
  1. main()
  2. {
  3.    int a[10];
  4.    ..
  5.    sort(a,10)
  6. }
  7. sort(int *x,int n) //指针作为形参 ,x首先接受实参数组a的首地址,x等价于*(x+i);
  8. {
  9.     ....
  10. }
形参和实参都是指针变量
  1. main()
  2. {
  3.    int a[10];
  4.    int *p;
  5.     p=a;
  6.    ..
  7.    sort(p,10) //指针作为实参
  8. }
  9. sort(int *x,int n) //指针作为形参 ,x首先接受实参数组a的首地址,x等价于*(x+i);
  10. {
  11.     ....
  12. }
形参是数组名、实参是指针变量
  1. main()
  2. {
  3.    int a[10];
  4.    int *p;
  5.     p=a;
  6.    ..
  7.    sort(a,10)
  8. }
  9. sort(int x[],int n) //指针作为形参 ,x首先接受实参数组a的首地址,x等价于*(x+i);
  10. {
  11.     ....
  12. }
指针运算的详细说明:验证实例求真相!

关于++(--)和*的运算总是混在一起,以前总是似是而非的,现在就详细的解决掉!
一:++的运算:
   如果n=3 ,则n的值和m的值如下表所示
n的值m的值运算分解
m=n++43
m=n; n=n+1
m=++n44n=n+1; m=n
m=-n++4-3m=-n; n=n+1
m=- ++n4-4n=n+1 ;m=-n;

解析:++是自增运行,自增运算的结果是其本身发生了变化,如指针p=2000,那么p++的值是2001,p值是2001,而如果是p+1,那么p+1的值是2001,但是p的依然是2000,因为p本身没有加1。
m=n++是先赋值再+1,意思是先执行m=n,然后n在执行n+1;以下同理,过程如上表运算分解所示。
二:++和*的综合运算

a=*p++和a=(*p)++的本质区别
(1) a=*p++  
相当于运算分解
a=*p++a=*(p++)a=*p ; p=p+1
解析:    前面已经说过了++和*的运算符优先级是相同的,他们的运算方向是自右向做。所以
a=*p++相当于a=*(p++),先得到*p,然后p+1->p;
    含义: 先取出P所指向的单元中的内容3赋值给a ,然后再使p指向下一个地址单元2002,在这个过程中,a值变成了3,指针变量p指向了2002这个空间。

(2)a=(*p)++

相当于运算分解
a=(*p)++a=(*p)++a=*p ; *p=*p+1
解析:  先取出变量p所指向的空间中的内容赋值给a,然后p所指向的空间中的内容加1.
     需要注意的是,当p中的内容赋值给a后,p所指向的空间中的内容加1,而不是指针变量p加1,指针变量p并没有发生改变,也就是说p的指向并没有变化,还是指向原来的空间,但是p所指向的内容变化了。而在(1)中,p的发生了变化,也就是指向发生了改变,指向了下一个空间。


发帖
4
黑豆
16
威望
6
贡献值
0
交易币
0
红豆
0
只看该作者 2 发表于: 2013-05-19
很好的资料唉,

但是英语底子差,还是学易语言好些。
发帖
25
黑豆
8
威望
25
贡献值
0
交易币
0
红豆
0
只看该作者 3 发表于: 2013-11-19
学习了,支持楼主.
发帖
783
黑豆
256
威望
1049
贡献值
0
交易币
0
红豆
15
只看该作者 4 发表于: 2013-12-24
虽然一下看不懂,但是也来顶顶
发帖
114
黑豆
298
威望
356
贡献值
0
交易币
0
红豆
0
只看该作者 5 发表于: 2014-01-15
我看不懂,只是好奇点啊。
加我的QQ:1833752569   好友验证:七剑战歌
免费一起交流学习、资源、
发帖
114
黑豆
298
威望
356
贡献值
0
交易币
0
红豆
0
只看该作者 6 发表于: 2014-01-15
发帖
13
黑豆
6
威望
13
贡献值
0
交易币
0
红豆
0
只看该作者 7 发表于: 2014-02-09
最近在学,但看得晕乎乎的。

内容来自[手机版]
快速回复
限100 字节
 
上一个 下一个