学习的最大理由是想摆脱平庸,早一天就多一份人生的精彩;迟一天就多一天平庸的困扰。
目录
指针这里分为八个小部分,分别是“指针变量”、“通过指针引用数组”、“*通过指针引用多维数组”、“通过指针引用字符串”、“*指向函数的指针”、“*返回指针值的函数”、“*指针数组和多重指针”、“*动态内存分配与指向它的指针变量” 。
一个变量有地址,一个数组包含若干元素,每个数组元素都在内存中占用存储单元,它们都有相应的地址。指针变量既可指向变量,当然也可指向数组元素(把某一元素的地址放到一个指针变量中)。所谓数组元素的指针就是数组元素的地址。可以用一个指针变量指向一个数组元素。 引用数组元素可用下标法,也可用指针法,即通过指向数组元素的指针找到所需的元素。
程序中的数组名不代表整个数组,只代表数组首元素的地址。
- int a[10]={1,3,5,7,9,11,13,15,17,19}; //定义a为包含10个整型数据的数组
- int *p; //定义p为指向整型变量的指针变量
- p=&a[0]; //把a[0]元素的地址赋给指针变量p
p | &a[0] | → | 1 | a[0] |
3 | ||||
5 | ||||
7 | ||||
9 | ||||
11 | ||||
13 | ||||
15 | ||||
17 | ||||
19 |
- p=&a[0]; //p的值是a[0]的地址
- p=a; //p的值是数组a首元素(即a[0])的地址
在指针已指向一个数组元素时,可以对指针进行以下运算: 加一个整数(用+或+=),
p+1
表示指向同一数组中的下一个元素;
减一个整数(用-或-=),
p-1
表示指向同一数组中的上一个元素;
自加运算,
p++,++p
自减运算,
p--,--p
两个指针相减,如p1-p2(只有p1和p2都指向同一数组中的元素时才有意义),结果是两个地址之差除以数组元素的长度。
注意:
两个地址不能相加,p1+p2是无实际意义的。 如果p的初值为&a[0],则p+i和a+i就是数组元素a[i]的地址,或者说,它指向a数组序号为i的元素。 *(p+i)或*(a+i)是p+i或a+i所指向的数组元素,即a[i]。[]是变址运算符,即将a[i]按a+i计算地址,然后找出此地址单元中的值。
执行p+1时并不是将p的值(地址)简单地加1,而是根据定义的基类型加上一个数组元素所占用的字节数。
array是实参数组名,arr为形参数组名。当用数组名作参数时,如果形参数组中各元素的值发生变化,实参数组元素的值随之变化。
在该函数被调用时,系统会在fun函数中建立一个指针变量arr,用来存放从主调函数传递过来的实参数组首元素的地址。如果在fun函数中用运算符sizeof测定arr所占的字节数,可以发现sizeof(arr)的值为4(用Visual C++时)。这就证明了系统是把arr作为指针变量来处理的(指针变量在Visual C++中占4个字节)。 当arr接收了实参数组的首元素地址后,arr就指向实参数组首元素,也就是指向array[0]。
以变量名和数组名作为函数参数的比较
实参类型 | 变量名 | 数组名 |
要求形参的类型 | 变量名 | 数组名或指针变量 |
传递的信息 | 变量的值 | 实参数组首元素的地址 |
通过函数调用能否改变实参的值 | 不能改变实参变量的值 | 能改变实参数组的值 |
注意:
实参数组名代表一个固定的地址,或者说是指针常量,但形参数组名并不是一个固定的地址,而是按指针变量处理。在函数调用进行虚实结合后,形参的值就是实参数组首元素的地址。 在函数执行期间,它可以再被赋值。
有一个整型数组a,有10个元素,要求输出数组中的全部元素。
- //下标法
- #include <stdio.h>
- int main()
- { int a[10];
- int i;
- printf("please enter 10 integer numbers:");
- for(i=0;i<10;i++)
- scanf("%d",&a[i]);
- for(i=0;i<10;i++)
- printf("%d ",a[i]);
- //数组元素用数组名和下标表示
- printf("%\n");
- return 0;
- }
- //通过数组名计算数组元素地址,找出元素的值
- #include <stdio.h>
- int main()
- { int a[10];
- int i;
- printf("please enter 10 integer numbers:");
- for(i=0;i<10;i++)
- scanf("%d",&a[i]);
- for(i=0;i<10;i++)
- printf("%d ",*(a+i));
- //通过数组名和元素序号计算元素地址找到该元素
- printf("\n");
- return 0;
- }
- //指针变量指向数组元素
- #include <stdio.h>
- int main()
- { int a[10];
- int *p,i;
- printf("please enter 10 integer numbers:");
- for(i=0;i<10;i++)
- scanf("%d",&a[i]);
- for(p=a;p<(a+10);p++)
- printf("%d ",*p);
- //用指针指向当前的数组元素
- printf("\n");
- return 0;
- }
用下标法比较直观,能直接知道是第几个元素。
用地址法或指针变量的方法不直观,难以很快地判断出当前处理的是哪一个元素。
单用指针变量的方法进行控制,可使程序简洁、高效。
通过指针变量输出整型数组a的10个元素。
- #include <stdio.h>
- int main()
- { int i,a[10],*p=a; //p的初值是a,p指向a[0]
- printf("please enter 10 integer numbers:");
- for(i=0;i<10;i++)
- scanf("%d",p++);
- p=a; //重新使p指向a[0]
- for(i=0;i<10;i++,p++)
- printf("%d ",*p);
- printf("\n");
- return 0;
- }
用指针方法对10个整数按由大到小顺序排序。(选择排序法)
- #include <stdio.h>
- int main()
- { void sort(int x[],int n); //sort函数声明
- int i,*p,a[10];
- p=a; //指针变量p指向a[0]
- printf("please enter 10 integer numbers:");
- for(i=0;i<10;i++)
- scanf("%d",p++); //输入10个整数
- p=a; //指针变量p重新指向a[0]
- sort(p,10); //调用sort函数
- for(p=a,i=0;i<10;i++)
- { printf("%d ",*p); //输出排序后的10个数组元素
- p++;
- }
- printf("\n");
- return 0;
- }
- void sort(int x[],int n) //定义sort函数,x是形参数组名
- { int i,j,k,t;
- for(i=0;i<n-1;i++)
- { k=i;
- for(j=i+1;j<n;j++)
- if(x[j]>x[k]) k=j;
- if(k!=i)
- { t=x[i]; x[i]=x[k]; x[k]=t;}
- }
- }
- ///
- void sort(int *x,int n) //形参x是指针变量
- { int i,j,k,t;
- for(i=0;i<n-1;i++)
- { k=i;
- for(j=i+1;j<n;j++)
- if(*(x+j)>*(x+k)) k=j; //*(x+j)就是x[j],其他亦然
- if(k!=i)
- { t=*(x+i); *(x+i)=*(x+k); *(x+k)=t;}
- }
- }
- ///