一、数组指针  1.指向数组元素的指针

  1、定义:还是那句话通俗的说指针就是地址  

    数组指针     :数组的起始地址

    数组元素指针:数组元素的地址

  2、定义一个指向数组元素的指针变量的方法,与之前介绍的指针变量相同。

    例如: 
         int a[10];   /*定义 a 为包含10 个整型数据的数组*/
         int *p;      /*定义p为指向整型变量的指针*/

  3、指针变量赋值:
    p=&a[0]; //或者:p=a; 原因是p,a,&a[0]均指向同一单元

    把 a[0]元素的地址赋给指针变量 p。也就是说,p指向 a 数组的第 0 号元素。

  4、格式

    类型说明符  *指针变量名;

2. 通过指针引用数组元素

看图识字:

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

  2、*(p+i)或*(a+i)就是p+i或a+i所指向的数组元素, 即a[i]。 例如, *(p+5)或*(a+5)就是a[5]。

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

根据以上叙述,引用一个数组元素可以用:
  1、下标法,即用 a[i]形式访问数组元素。
  2、指针法,即采用*(a+i)或*(p+i)形式,用间接访问的方法来访问数组元素,其中 a是数组名,p是指向数组的指针变量,其处值 p=a。

Eg:

  1、下标法:

  

  2、通过数组名计算元素的地址

    

  3、指针变量指向元素

      

  注意的问题

    1、指针变量可以实现本身的值的改变。如 p++是合法的;而 a++是错误的。因为 a 是数组名,它是数组的首地址,是常量。

    2、要注意指针变量的当前值。请看下面的程序。

int a[10],i,*p;p=a;//p=&a[0]for(i=0;i<10;i++)*p++=i; //a[i++]=ifor(i= 0;i<10;i++)printf("a[%d]=%d\n",i,*p++);

你看看出问题吗?如果可以别忘了告诉我(虽然书上解释了“要注意指针变量的当前值”但是还是有点迷糊)

看看运行结果

    

正确的方法就是把上面注释的部分拿出来即可,看看结果:

  

3.数组名作函数参数

  数组名可以作函数的实参和形参

main()
{int array[10]; …… …… f(array,10);
…… ……
} f(int arr[],int n); {
…… ……
}
array 为实参数组名,arr为形参数组名。

  Eg:将数组 a 中的 n 个整数按相反顺序存放。

    1、形参是数组名

main()
{//将数组 a 中的 n 个整数按相反顺序存放。 int i,a[10]={3,7,9,11,0,6,7,5,4,2};printf("The original array:\n");for(i=0;i<10;i++){printf("%d,",a[i]);}printf("\n");inv(a,10);printf("The array has been inverted:\n");for(i=0;i<10;i++){printf("%d,",a[i]);}printf("\n");
}
/*形参是数组名*/inv(int x[],int n)
{int temp,i,j,m=(n-1)/2;for(i=0;i<m;i++){j=n-1-i;temp=x[i];x[i]=x[j];x[j]=temp; }
}

    2、形参x为指针变量

/*形参x为指针变量*/inv2(int *x,int n){int *p,temp,*i,*j,m=(n-1)/2;i=x ;j=x+n-1;p=x+m;for(;i<=p;i++,j--){temp=*i;*i=*j;*j=temp;}return;}

  归纳总结:如果有一个实参数组,想在函数中改变此数组的元素的值,实参与形参的对应关系有以下4种:

    1、形参和实参都是数组名。

      main()                    f(int x[],int n) { ……}
      {int a[10]; 
        …… 
       f(a,10) 
        ……
      }

    2、实用数组,形参用指针变量

      main()                      f(int *x,int n) {  …… }
      {int a[10];
        ……
       f(a,10) 
        ……
      }

    3、 实参、型参都用指针变量

    4、实参为指针变量,型参为数组名

4.指向多维数组的指针和指针变量

  1.  多维数组的地址 设有整型二维数组 a[3][4]如下:
     0   1   2   3 
         4   5   6   7
     8   9  10  11
  它的定义为:
    int a[3][4]={{0,1,2,3},{4,5,6,7},{8,9,10,11}}

  C语言允许把一个二维数组分解为多个一维数组来处理,因此数组 a 可分解为三个一维数组,即 a[0],a[1],a[2]   

  例如 a[0]数组,含有 a[0][0],a[0][1],a[0][2],a[0][3]四个元素。

  a[0]是第一个一维数组的数组名和首地址,因此a,a[0],*(a+0),*a,&a[0][0]是相等的。

  Eg:

  

    int a[3][4] ={0,1,2,3,4,5,6,7,8,9,10,11}; //0,1,2,3   a[0]行//4,5,6,7   a[1]行//8,9,10,11 a[2]行printf("0\n");printf("%d\n",*(a+0)); printf("%d\n",a); printf("%d\n",*a);  printf("%d\n",a[0]); printf("%d\n",&a[0]);  printf("%d\n",&a[0][0]); printf("………………………………………………\n");printf("1\n");printf("%d\n",a+1);  printf("%d\n",*(a+1));  printf("%d\n",a[1]);  printf("%d\n",&a[1]);  printf("%d\n",&a[1][0]); printf("………………………………………………\n"); printf("2\n");printf("%d\n",a+2);  printf("%d\n",*(a+2));  printf("%d\n",a[2]);  printf("%d\n",&a[2]);  printf("%d\n",&a[2][0]); printf("………………………………………………\n"); printf("3【a[1]行+1=>1244996+4】\n");printf("%d\n",a[1]+1);  printf("%d\n",*(a+1)+1); printf("………………………………………………\n"); printf("取2行值\n");printf("%d,%d\n",*(a[1]+0),*(*(a+1)+0)); printf("%d,%d\n",*(a[1]+1),*(*(a+1)+1)); printf("%d,%d\n",*(a[1]+4),*(*(a+1)+4)); //越界继续向下取值8*/

  结果:

   

  2.指向多维数组的指针变量
  把二维数组 a 分解为一维数组 a[0],a[1],a[2]之后,设 p 为指向二维数组的指针变量。可定义为: 
        int (*p)[4]
  它表示 p 是一个指针变量,它指向包含 4 个元素的一维数组。若指向第一个一维数组a[0],其值等于 a,a[0],或&a[0][0]等。而 p+i 则指向一维数组 a[i]。从前面的分析可得出*(p+i)+j是二维数组 i 行j 列的元素的地址,而*(*(p+i)+j)则是i行 j 列元素的值。

  二维数组指针变量说明的一般形式为:

    类型说明符  (*指针变量名)[长度]

  注意“(*指针变量名)”两边的括号不可少,如缺少括号则表示是指针数组

  eg:

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

二、字符串指针 1、字符串的表示形式

  C 语言中,可以用两种方法访问一个字符串:

    1、用字符数组存放一个字符串,然后输出该字符串

    2、用字符串指针指向一个字符串

  

2、 使用字符串指针变量与字符数组的区别

  1、字符串指针变量本身是一个变量,用于存放字符串的首地址,而字符串本身是存放在以该首地址为首的一块连续的内存空间中并以‘\0’作为串的结束

  2、对字符串指针方式 char *ps="C Language";

    可以写为: 
         char *ps;
      ps="C Language";
    而对数组方式: 
        static char st[]={"C Language"};
    不能写为: 
        char st[20]; 
        st={"C Language"}; 而只能对字符数组的各元素逐个赋值。

三、函数指针    

   在C语言中,一个函数总是占用一段连续的内存区,而函数名就是该函数所占内存区的首地址。我们可以把函数的这个首地址(或称入口地址)赋予一个指针变量,使该指针变量指向该函数。然后通过指针变量就可以找到并调用这个函数。我们把这种指向函数的指针变量称为“函数指针变量”。

   函数指针变量定义的一般形式为:

     类型说明符  (*指针变量名)();

  其中“类型说明符”表示被指函数的返回值的类型。 “(* 指针变量名)”表示“*”后面的变量是定义的指针变量。最后的空括号表示指针变量所指的是一个函数。

  例如: 
      int (*pf)();

  Eg:

    

main()
{int comMax(int a,int b);int (*pmax) ();//定义:类型说明符  (*指针变量名)(); 表示 pmax 是一个指向函数入口的指针变量,该函数的返回值(函数值)是整型。int x,y,z;pmax=comMax;printf("input two numbers:\n");scanf("%d%d",&x,&y);z=(*pmax)(x,y);//调用函数的一般形式为:(*指针变量名) (实参表)  或者 comMax(x,y);printf("max=%d",z);
}int comMax(int a,int b)
{if(a>b) return a; else return b;
}

  结果:

  从上述程序可以看出用,函数指针变量形式调用函数的步骤如下:

    1、先定义函数指针变量,如后一程序中第 9 行 int (*pmax)();定义 pmax 为函数指针变量

    2、把被调函数的入口地址(函数名)赋予该函数指针变量,如程序中第 11 行 pmax=max;

    3、用函数指针变量形式调用函数,如程序第 14 行 z=(*pmax)(x,y);

    4、调用函数的一般形式为:
         (*指针变量名) (实参表)
      使用函数指针变量还应注意以下两点:

        a、函数指针变量不能进行算术运算,这是与数组指针变量不同的。数组指针变量加减一个整数可使指针移动指向后面或前面的数组元素,而函数指针的移动是毫无意义的

        b、函数调用中"(*指针变量名)"的两边的括号不可少,其中的*不应该理解为求值运算,在此处它只是一种表示符号

作者:PEPE
出处:http://pepe.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

C 温故知新 之 指针:数组指针、字符串指针、函数指针相关推荐

  1. c语言指针数组 难点总结,C语言指针与数组的难点分析.pdf

    C语言指针与数组的难点分析,c语言指针数组,c语言二维数组指针,c语言指针数组初始化,c语言函数指针数组,c语言数组与指针,c语言结构体数组指针,c语言指向数组的指针,c语言字符串数组指针,c语言数组 ...

  2. 进阶C语言 - 指针(3):函数指针数组

    目录 6. 函数指针数组 那么函数指针数组有什么用呢? 写一个计算器:实现简单的加减乘除 函数指针和函数指针数组的区别: 用函数指针和函数指针数组来实现计算器的区别: 6. 函数指针数组 函数指针数组 ...

  3. 指针数据类型 java_C/C++ 指针的小结——指针与其它数据类型(数组、字符串、函数、结构体)的关系...

    一.指针与数组和字符串 1.指针与数组 当声明数时,编译器在连续的内存空间分配基本地址和足够的储存空间,以容纳数组的所有元素.基本地址是数组第一个元素(索引为0)的存储位置.编译器还把数组名定义为指向 ...

  4. 【C语言】字符指针数组查找字符串

    字符串常识: 1.以'\0'结尾,用" "括起来,字符是用' '括起来 2.字符串有字符数组和字符指针两种表现形式.字符数组不一定是字符串,有'\0'结束的字符数组才是字符串,但字 ...

  5. 利用指针数组进行字符串排序

    概念: 一个数组的元素均是指针,则该数组称为指针数组. 使用指针数组处理字符串非常适合.由于字符串长度不定,使用二维字符数组处理会大量浪费存储空间. 代码示例: #include<stdio.h ...

  6. c c++ 函数内数组初值_C/C++函数指针与指针函数

    关于指针,前面文章C语言指针详解有过介绍,这里主要讨论函数指针和指针函数. 1 什么是指针? 定义:指针是程序数据在内存中的地址,而指针变量是用来保存这些地址的变量; 上面一个 4GB 的内存可以存放 ...

  7. c语言中结构体类型定义的函数指针,结构体中定义函数指针

    结构体指针变量的定义 定义结构体变量的一般形式如下:形式1:先定义结构体类型,再定义变量struct 结构体标识符{ 成员变量列表;-};struct 结构体标识符 *指针变量名;变量初始化:stru ...

  8. 《C和指针》—— 第13章 函数指针的作用1:回调函数2(与模板结合,简化代码)

    注意:此为原创文章,未经同意,请勿随意转载. 目录 1. 问题与思路 2. 具体实现 3. 结果截图 1. 问题与思路 Q:实现一个与类型无关的比较函数,且考虑模板,精简代码 A:声明一个函数指针,函 ...

  9. 黑马程序员C语言基础(第五天)运算符与表达式、程序流程结构、数组和字符串、函数

    https://www.bilibili.com/video/BV15W411K7k6?p=93&spm_id_from=pageDriver 黑马程序员C语言基础(第五天)运算符与表达式.程 ...

  10. 字符串数组交换c语言,c语言指针数组和字符串数组的区别,高手请进

    要对几个字符串排序后输出. 两个程序,只是对数组的定义不同,第一个定义的是指针数组,是对的:第二个定义的是字符串数组,却是错的.指针数组的v[i]和字符串数组的v[i]不都是表示指向一个字符串的一级指 ...

最新文章

  1. Java中的Split方法不适用于一个句号
  2. bat文件注册为Windows服务与依赖关系设置
  3. js 拼接html 表格,js合并table单元格(拼table的时候并不知道具体几行几列)
  4. 『设计模式』不看就亏了的设计模式总结
  5. 带出7个“师弟”,支付宝BASIC College的辅导员是个伪90后
  6. python 归纳 (四)_运算符重载
  7. C++类的继承与派生
  8. linux ppp拨号 USB,linux下ppp拨号上网
  9. 接口访问超时 504 Gateway Time-out 优化方案
  10. 领域驱动设计系列(2)浅析VO、DTO、DO、PO的概念、区别和用处
  11. 交换机和路由器技术-11-VLAN Trunk
  12. hana数据库导入mysql_在SAP HANA Express Edition里创建数据库表
  13. java jdt_在JDT中使用Java 8 Lambda
  14. Mac删除多余的输入输出设备,删除EasyConnectAudio
  15. Google Play In-app Billing
  16. vue引入重写样式修改Element-UI表格背景色以及悬浮背景色,带操作的表格也可以修改呦~
  17. component: resolve = require(['../pages/home.vue'], resolve),
  18. ubuntu20.04系统安装vmtool工具
  19. 2017年5月5号课堂笔记
  20. 蓝牙相关学习:4.2.BLE空口包结构 - PDU

热门文章

  1. oracle中substrb用法,oracle中substr和instr的用法
  2. 从数据库表中随机获取N条记录的SQL语句
  3. Java线程面试题 Top 53
  4. java获取IP地址:
  5. (九)nodejs循序渐进-Express框架(进阶篇)
  6. Git(12)-stash, reflog
  7. 《Python Cookbook 3rd》笔记(3.3):数字的格式化输出
  8. ubuntu apt报错无法获得锁/var/lib/dpkg/lock 和无法锁定管理目录
  9. 数学建模 匈牙利算法求解整数规划基本原理与编程实现
  10. 3个观念 不再瞎学习!