呵呵哒!手把手教你什么是指针

柔情只为你懂 2023-07-04 11:11 74阅读 0赞

1.地址和指针的概念

地址:一个变量的地址称为该变量的“指针”。
指针:指针是一个地址,而指针变量是存放地址的变量。

特别注意:只有整型变量的地址才能放到指向那个整型变量的指针变量中,以此类推。

2.指针变量的引用

有两个有关的运算符:

(1)& : 取地址运算符。

(2)* :指针运算符(或称为“间接访问”运算符),取指针所指向的对象的内容。

例如:&a为变量的a的地址,*p为指针变量p所指向的存储单元的内容(即p所指向的变量的值)

  1. //通过指针变量的访问整型变量
  2. #include <stdio.h>
  3. void main(){
  4. int a,b;
  5. int *pointer_1,*pointer_2;
  6. a=100;b=10;
  7. pointer_1=&a;//把变量a的地址赋给pointer_1
  8. pointer_2=&b;//把变量b的地址赋给pointer_2
  9. printf("%d,%d\n",a,b);
  10. printf("%d,%d\n",*pointer_1,*pointer_2);
  11. }

知识点巧懂:

(1)&*pointer_1的含义是什么?

&和*这两个运算符的优先级级别相同,按照自右向左的方便结合,因此先进行*pointer_1的运算,它就是变量a,然后在执行&运算。也就是说:&*pointer_1=&a,即变量a的地址

(2)*&a的含义是什么?

先进行&a运算,得到a的地址,再进行*运算,也就是说:*&a=a。而且*&a和*pointer_1的作用也是一样的。

(3)(*pointer_1)++相当于a++

由于&和*这两个运算符的优先级级别相同,按照自右向左的方便结合,括号是必要的。

3.指针变量运用

(1)算法实现:不交换整型变量的值,而是交换两个指针变量的值(即a和b的地址)。

  1. #include <stdio.h>
  2. void main(){
  3. int *p1,*p2,*p,a,b;
  4. scanf("%d%d",&a,&b);
  5. p1=&a;
  6. p2=&b;
  7. if(a<b){
  8. p1=&b;
  9. p2=&a;
  10. }
  11. printf("a=%d,b=%d\n\n",a,b);
  12. printf("max=%d,min=%d\n",*p1,*p2);
  13. }

(2)算法实现:不交换两个指针变量的值,而是交换整型变量的值 (即a和b)。

  1. #include <stdio.h>
  2. void main(){
  3. void swap(int *p1,int *p2);
  4. int a,b;
  5. int *pointer_1,*pointer_2;
  6. scanf("%d%d",&a,&b);
  7. pointer_1=&a;
  8. pointer_2=&b;
  9. if(a<b){
  10. swap(pointer_1,pointer_2);
  11. }
  12. printf("%d %d\n",a,b);
  13. }
  14. void swap(int *p1,int *p2){
  15. int temp;
  16. temp=*p1;
  17. *p1=*p2;
  18. *p2=temp;
  19. }

(3)输入a,b,c这3个整数,按照大小顺序输出

  1. #include <stdio.h>
  2. void main(){
  3. void exchange(int *q1,int *q2,int *q3);
  4. int a,b,c,*q1,*q2,*q3;
  5. scanf("%d%d%d",&a,&b,&c);
  6. q1=&a;
  7. q2=&b;
  8. q3=&c;
  9. exchange(q1,q2,q3);
  10. printf("%d%d%d",a,b,c);
  11. }
  12. void exchange(int *q1,int *q2,int *q3){
  13. void swap(int *q1,int *q2);
  14. if(*q1<*q2) swap(q1,q2);
  15. if(*q1<*q3) swap(q1,q3);
  16. if(*q2<*q3) swap(q2,q3);
  17. }
  18. void swap(int *q1,int *q2){
  19. int temp;
  20. temp=*q1;
  21. *q1=*q2;
  22. *q2=temp;
  23. }

4.通用指针引用数组元素

按照C语言的规定:如果指针变量p已指向数组中的一个元素,则p+1指向同一数组中的下一个元素,而不是p的值(地址)简单的加1。例如,数组元素是float型,每个元素占4个字节,则p+1意味着使p的值(是地址)加4个字节,以使指向下一个元素。(Visual C++6.0中,对int,long和float型,d=4,对char型)

(1)p+i和a+i就是a[[i]的地址,或者说,它们指向a数组的第i个元素。

(2)*(p+i)或*(a+i)是p+i或a+i所指向的数组元素。即a[i]。

(3)指向数组的指针变量也可以带下标,如p[i]与*(p+i)等价

5.输出数组中的全部元素

(1)下标法

  1. #include <stdio.h>
  2. void main(){
  3. int a[10];
  4. int i;
  5. for(i=0;i<10;i++){
  6. scanf("%d",&a[i]);
  7. }
  8. for(i=0;i<10;i++){
  9. printf("%d",a[i]);
  10. }
  11. printf("\n");
  12. }

(2)通过数组名计算数组元素地址,找出元素的值

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

(3)用指针变量指向数组元素

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

也可以简写成为如下

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

但是不可以写成如下

for(p=a;a<(p+10);a++)

这样是不行的,因为数组名a代表数组首元素的地址,它是一个指针常量,它的值在程序运行期间是固定不变的,既然a是常量,所以a++是无法实现的。

6.通过指针变量输出a数组的10个元素

常见错误代码:

  1. #include <stdio.h>
  2. void main(){
  3. int a[10];
  4. int *p;
  5. int i;
  6. p=a;
  7. for(i=0;i<10;i++){
  8. scanf("%d",p++);
  9. }
  10. for(i=0;i<10;i++,p++){
  11. printf("%d",*p);
  12. }
  13. printf("\n");
  14. }

纠正代码

  1. #include <stdio.h>
  2. void main(){
  3. int a[10];
  4. int *p;
  5. int i;
  6. p=a;
  7. for(i=0;i<10;i++){
  8. scanf("%d",p++);
  9. }
  10. p=a;//添加这条语句,可以使得指针回到首地址
  11. for(i=0;i<10;i++,p++){
  12. printf("%d",*p);
  13. }
  14. printf("\n");
  15. }

知识点巧懂

(1)*p++,由于++和*同优先级,结合方向为自右向左,因此它等价于*(p++)。作用是先得到p指向的变量的值,然后再p+1=p。

(2)*(p++)和*(++p)作用不同。

(3)*(p—)相当于a[i—],先对p进行”*“运算,然后p自减。

(4)*(++p)相当于a[i—],先对p自加,然后p进行”*“运算。

7.用选择法对10个整数按照由小到大顺序排序

(1)逐个取出数组的元素进行数字的排序

  1. #include <stdio.h>
  2. void main(){
  3. void sort(int x[],int n);
  4. int *p,i,a[10];
  5. p=a;
  6. for(i=0;i<10;i++){
  7. scanf("%d",p++);
  8. }
  9. p=a;
  10. sort(p,10);
  11. p=a;
  12. for(i=0;i<10;i++){
  13. printf("%d",*p++);
  14. }
  15. }
  16. void sort(int x[],int n){
  17. int i,j,k,t;
  18. for(i=0;i<n-1;i++){
  19. k=i;
  20. for(j=i+1;j<n;j++)
  21. if(x[j]>x[k]){
  22. k=j;
  23. }
  24. if(k!=i){
  25. t=x[i];
  26. x[i]=x[k];
  27. x[k]=t;
  28. }
  29. }
  30. }

(2)用指针的方法进行数字的排序

  1. #include <stdio.h>
  2. void main(){
  3. void sort(int *x,int n);
  4. int *p,i,a[10];
  5. p=a;
  6. for(i=0;i<10;i++){
  7. scanf("%d",p++);
  8. }
  9. p=a;
  10. sort(p,10);
  11. p=a;
  12. for(i=0;i<10;i++){
  13. printf("%d",*p++);
  14. }
  15. }
  16. void sort(int *x,int n){
  17. int i,j,k,t;
  18. for(i=0;i<n-1;i++){
  19. k=i;
  20. for(j=i+1;j<n;j++)
  21. if(*(x+j)>*(x+k)){
  22. k=j;
  23. }
  24. if(k!=i){
  25. t=*(x+i);
  26. *(x+i)=*(x+k);
  27. *(x+k)=t;
  28. }
  29. }
  30. }

8.多维数组和指针

int a[3][4]={ {1,2,3,4},{5,6,7,8},{9,10,11,12}};

知识点巧懂

(1)从二维数组的角度来看,a代表二维数组首元素的地址。例如a[0]在二维数组中代表一维数组a[0]中第0列元素的地址。即&a[0][0]。

(2)考虑1行0列元素的地址如何表示?a[0]为一维数组名,此时”a[0]+1”的地址为&a[0][1]。

(3)用指针变量输出二维数组元素的值。

  1. #include <stdio.h>
  2. void main(){
  3. int a[3][4]={
  4. {1,2,3,4},{5,6,7,8},{9,10,11,12}};
  5. int *p;
  6. for(p=a[0];p<a[0]+12;p++){
  7. if((p-a[0])%4==0)
  8. printf("\n");
  9. printf("%4d",*p);
  10. }
  11. printf("\n");
  12. }

(4)输出二维数组任一行任一列元素的值。

  1. #include <stdio.h>
  2. void main(){
  3. int a[3][4]={
  4. {1,2,3,4},{5,6,7,8},{9,10,11,12}};
  5. int (*p)[4],i,j;
  6. p=a;
  7. scanf("%d%d",&i,&j);
  8. printf("a[%d,%d]=%d\n",i,j,*(*(p+i)+j));
  9. }

(5)用指向数组的指针作函数参数。

  1. #include <stdio.h>
  2. void main(){
  3. void average(float *p,int n);
  4. void search(float(*p)[4],int n);
  5. float score[3][4]={
  6. {65,67,70,60},{80,87,90,81},{90,99,100,98}};
  7. //average(score[0],12);
  8. //*score=score[0]
  9. average(*score,12);
  10. //指定找出某一行
  11. search(score,2);
  12. }
  13. void average(float *p,int n){
  14. float sum=0;
  15. float *p_end;
  16. p_end=p+n;
  17. for(;p<p_end;p++)
  18. sum=sum+(*p);
  19. printf("average=%f\n",sum/n);
  20. }
  21. void search(float(*p)[4],int n){
  22. int i;
  23. for(i=0;i<4;i++){
  24. printf("%5.2f\t",*(*(p+n)+i));
  25. }
  26. printf("\n");
  27. }

9.字符串与指针

(1)定义一个字符数组,对它初始化,然后输出该字符串。

  1. #include <stdio.h>
  2. void main(){
  3. char string[]="I love China!";
  4. printf("%s\n",string);
  5. }

(2)用字符指针指向一个字符串。

  1. #include <stdio.h>
  2. void main(){
  3. char *string="I love China!";
  4. printf("%s\n",string);
  5. }

(3)用指针变量将字符串a复制为字符串b。

  1. #include <stdio.h>
  2. void main(){
  3. char a[]="I am a boy",b[20],*p1,*p2;
  4. int i;
  5. p1=a;
  6. p2=b;
  7. for(;*p1!='\0';p1++,p2++){
  8. *p2=*p1;
  9. }
  10. *p2='\0';
  11. for(i=0;b[i]!='\0';i++){
  12. printf("%c",b[i]);
  13. }
  14. printf("\n");
  15. }

(4)改变指针变量的值。

  1. #include <stdio.h>
  2. void main(){
  3. char *a="I love China!";
  4. a=a+7;
  5. printf("%s\n",a);
  6. }

9.指向函数的指针

(1)用函数指针变量调用函数

数据类型 (* 指针变量名)(函数参数表列)

这是一般方法程序

  1. #include <stdio.h>
  2. void main(){
  3. int max(int,int);
  4. int a,b,c;
  5. scanf("%d%d",&a,&b);
  6. c=max(a,b);
  7. printf("max=%d",c);
  8. }
  9. int max(int x,int y){
  10. int z;
  11. if(x>y)z=x;
  12. else z=y;
  13. return (z);
  14. }

用函数指针变量调用函数

  1. #include <stdio.h>
  2. void main(){
  3. int max(int,int);
  4. int (*p)(int,int);
  5. int a,b,c;
  6. scanf("%d%d",&a,&b);
  7. p=max;
  8. c=(*p)(a,b);
  9. printf("max=%d",c);
  10. }
  11. int max(int x,int y){
  12. int z;
  13. if(x>y)z=x;
  14. else z=y;
  15. return (z);
  16. }

(2)设一个函数process,在调用它的时候,每次实现不同的功能。

  1. #include <stdio.h>
  2. void main(){
  3. int max(int,int);
  4. int min(int,int);
  5. int add(int,int);
  6. int process(int,int,int(*fun)(int,int));
  7. int a,b;
  8. printf("enter a and b:");
  9. scanf("%d%d",&a,&b);
  10. printf("max = %d\n",process(a,b,max));
  11. printf("min = %d\n",process(a,b,min));
  12. printf("add = %d\n",process(a,b,add));
  13. }
  14. int process(int x,int y,int(*fun)(int,int)){
  15. int result;
  16. result=(*fun)(x,y);
  17. return result;
  18. }
  19. int max(int x,int y){
  20. int max;
  21. max=x>y?x:y;
  22. return max;
  23. }
  24. int min(int x,int y){
  25. int min;
  26. min=x<y?x:y;
  27. return min;
  28. }
  29. int add(int x,int y){
  30. int add;
  31. add=x+y;
  32. return add;
  33. }

10.返回指针值的函数

(1)若干个学生的成绩(每个学生有四门课程),输入学生序号可以查询该学生的全部成绩。

  1. #include <stdio.h>
  2. void main(){
  3. float score[][4]={
  4. {20,30,40,50},{1,2,3,4},{5,6,7,8}};
  5. float *search(float (*score_pointer)[4],int n);
  6. float *p;
  7. int i,m;
  8. scanf("%d",&m);
  9. p=search(score,m);
  10. for(i=0;i<4;i++){
  11. printf("%5.2f\t",*(p+i));
  12. }
  13. printf("\n");
  14. }
  15. float *search(float (*score_pointer)[4],int n){
  16. float *pt;
  17. //score_pointer等于score首地址,*(score_pointer+n)意思是得到第n第0列的地址
  18. pt=*(score_pointer+n);
  19. return pt;
  20. }

(2)找出其中不及格课程的学生以及学生号。

  1. #include <stdio.h>
  2. void main(){
  3. float score[][4]={
  4. {60,70,80,90},{56,89,67,88},{34,78,90,66}};
  5. float *search(float(*pointer)[4]);
  6. float *p;
  7. int i,j;
  8. for(i=0;i<3;i++){
  9. p=search(score+i);
  10. if(p==*(score+i)){
  11. printf("No.%d scores:",i);
  12. for(j=0;j<4;j++){
  13. printf("%5.2f",*(p+j));
  14. }
  15. printf("\n");
  16. }
  17. printf("\n");
  18. }
  19. }
  20. float *search(float(*pointer)[4]){
  21. int i;
  22. float *pt;
  23. pt=*(pointer+1);
  24. for(i=0;i<4;i++){
  25. if(*(*pointer+i)<60)
  26. pt=*pointer;
  27. }
  28. return pt;
  29. }

11.指针数组和指向指针的指针

(1)将若干个字符按照字母顺序(从小到大)输出。

  1. #include <stdio.h>
  2. #include <string.h>
  3. void main(){
  4. void sort(char *name[],int n);
  5. void print(char *name[],int n);
  6. char *name[]={"Follow me","BASIC","Great Wall","FORTRAN","Computer design"};
  7. int n=5;
  8. sort(name,n);
  9. print(name,n);
  10. }
  11. void sort(char *name[],int n){
  12. char *temp;
  13. int i,j,k;
  14. for(i=0;i<n-1;i++){
  15. k=i;
  16. for(j=i+1;j<n;j++){
  17. if(strcmp(name[k],name[j])>0)
  18. k=j;
  19. }
  20. if(k!=i){
  21. temp=name[i];
  22. name[i]=name[k];
  23. name[k]=temp;
  24. }
  25. }
  26. }
  27. void print(char * name[],int n){
  28. int i;
  29. for(i=0;i<n;i++){
  30. printf("%s\n",name[i]);
  31. }
  32. }

(2)指向指针的指针

  1. #include <stdio.h>
  2. void main(){
  3. char *name[]={"Follow me","BASIC","Great Wall","FORTRAN","Computer design"};
  4. //printf("%s\n",name[0]);
  5. char **p;
  6. int i;
  7. for(i=0;i<5;i++){
  8. p=name+i;
  9. printf("%s\n",*p);
  10. }
  11. }

(3)指针数组的元素指向整型数据

  1. #include <stdio.h>
  2. void main(){
  3. int a[5]={1,3,5,7,9};
  4. int *num[5]={&a[0],&a[1],&a[2],&a[3],&a[4]};
  5. int **p,i;
  6. //num其实是&a[0]的地址 然后 p=num 所以 *p找到了&a[0],然后**p则*&a[0]=a[0]
  7. p=num;
  8. //printf("%d\n",&a[0]);
  9. //printf("%d\n",num[0]);
  10. for(i=0;i<5;i++){
  11. printf("%d",**p);
  12. p++;
  13. }
  14. printf("\n");
  15. }

发表评论

表情:
评论列表 (有 0 条评论,74人围观)

还没有评论,来说两句吧...

相关阅读

    相关 公交车19路换新车啦,

    19路车是我每天上班必坐的,过去的(昨天为止)19路车 由于使用年限过久,造成车很容易就抛锚了。我们这些乘客只得下车等候后面的车,通常都是挤的不行。早就抱怨希望能换新车,今天竟