黑马程序员------C语言程序 指针

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------


一、指针 

   1,指针变量概念机定义方法

        指针变量: 在c语言中,允许用一个变量来存放指针,这种变量称为指针。

     严格意义说,指针式一个地址,是一个常量,指针变量事存放一个地址,事一个变量

   2定义一个指针变量

       指针类型说明,即定义变量为一个指针变量;

        指针变量名

     指针值(指针)

     

     一般形式 类型说明符 *变量名

     int *p 定义了一个指针变量,变量名是p

      int,表示p只能存放一个int 类型的变量的地址

   3指针变量的定义的注意:

        1"*" 必须得有如果没有就相当于定义一个普通变量

        2指针变量 不能 用来存放数值或者名符之类

        3指针变量,归根到底还是变量也有全局变量和局部变量之分

    4指针变量的初始化

        指针变量也是变量 

     指针变量的使用:定义指针变量 》初始化指针变量》使用

            完全初始化

     1)定义的同时初始化

            int *p =&a ;

        2)部分初始化

     int *p=&b,*P4;  

     p4=&c;

     2)定义后初始化

      int *p2;

     p2 =NULL; //是空

     3)定义了一个指针变量,不知道指向谁

     int *P8=NULL;

     int *p6 = 0;  //把一个指针定义为空,就是什么也不指向。

     指针变量的作用:获取指针变量指向的内存空间的内容

                获取指针变量值所对应的存储单元

     ”*“ 的两种用法

       1用来定义一个指针变量

       2获取值 *获取p指向的变量地址的值

     4)指针变量不初始化有什么后果

        如果不初始化 这个指针变量放的就是垃圾值,这个指针就叫野指针。

    5.用函数交换两个变量的值

     void swap(int a,int b){

     int temp0;

        tmp =a

        a=b;

        b=temp; 

     }    在函数中这个只是函数的形参变了

            正确的是用指针

#include <stdio.h>     
void swap1(int*p,int*p1){
     int *temp;
     temp =p;
     p=p1;
     p1=temp;
     }
     
int main(int argc,const char *argv){
        int a=a4,b=5;
     printf("交换前a=%d,b=%d\n",a,b);
     swap1(&a,&b);
     printf("交换后的值 a=%d, b=%d\n",a,b)
       return 0;
     }

  7,指针的应用场景

     1)在被函数中可以修改主函数中的变量之值。

     void changValue(int*p){

            *p =10;

     

     }

      int main( int argc ,const char*argv[]){

     

            int a=10;

            int *P1 =&a //p1指向了a

            printf("%d\n",*p1);//a=10

            change(p1);

            printf("%d\n",*p1);//100

            printf("%d\n",a);//100

     

      returen 0;

     }

     

     2)实现多个返回值

    void caculator(int x, inty,int*add,int*jian,int*cheng,double*chu){

            *add = x+y;

            *jian =x-y;

            *cheng = x*y;

     *chu = x /(double)y;

     }

       int main(int argc,const char*argv[]){

        

            int add;

            int jian;

            int cheng;

            int chu;

        caculator(3,4,&add,&jian,&cheng,&chu);

     printf("add=%d,jian=%d,cheng=%d,chu=%d",add,jian,cheng,chu);

     return 0;

     }

   8 二级指针

        如果一个指针变量存放的是另一个指针变量的地址,则称这个指针变量为指向指针的指针变量,也就是“二级指针”

        定义一个二级指针 int **p =&p

     int a 10;

     int *p =&a; p的值时a的地址

     int**p=&p; **p 就是取出 p里面存储的地址,而p存的是&a的地址,就是a的值

     9 指针为什么要区分类别

        不同类别表示职能存不同的类型的地址

        int *p 便是指针职能存放int类型的地址

     int a=5;

     char *p=&a; a占四个字节,而这里每次只取一个字节。数据会改变

     所以是什么类型的变量 就用什么类型的指针

  

二、指针与数组

     

     1 数组指针;

      指针变量可以指向数组的某个元素(把某一元素点地址放到相应的地址)

     所谓数组元素的指针就是数组与元素的地址

      指针数组的作用使用数组指针间接访问数组的元素

     数组指针的定义:int *p 和定义变量指针一样

     数组指针的初始化

     int a[4]={1,2,3,4};

     int *p=a //数组指针,定义了一个指针变量p赋值数组的首地址(第一个元素到地址),p指向数组的第一元素

     int *p =&a[0]//等价上面一句话。

   

    2.数组指针的用法

       数组指针如何访问数组的元素:

       p+1 表示指向数组的下一个元素

       p1表示指向数组的上一个元素

     也可用*p++ 是个指针变量,是变量所以也可以++

     

      int a[5]={1,2,3,4,5};

     

     int*p =a;//表示p指向数组的第一个元素

       *(p+1) = a[1];

     使用数组指针和使用数组名的区别

     用数组指针遍历数组

     for(int i=0;i<4;i++){

        printf("%d\t",*p++); //p指向数组的首元素

     }

     数组名a是一个常量不能++

     

     总结:

        引用一个数组元素,可以用两种方法

           1下标法 如a[i]形式

            2指针法如*(a+i)*(p+i)

            3a是常量(a++是错误的),p是变量(p++正确)

     3.一维指针数组

      一个数组的元素值为指针则是指针数组。白话存放指针的数组,就是指针数组

     指针数组的一般形式 类型说明符*数组名[数组长度]

     类型说明符为指针说指向的变量的类型

      int *p[3]

     表示p时一个指针数组,它有是三个元素,诶个元素都是一个指针,指向整型变量。

     指针数组的使用 int p*[3]={&a,&b,&c};

      p[0] =&a;  a的地址  p数组的首地址

      p就是指针数组的地址  访问的值  *(p[0])

     4.指针变量之间的运算

        两个指针之间的减法运算,

         1》   0x0006 0x003 3(意义不大)

        2》常见的用法: 两个指针指向同一个数组

            判断两个指针变量指向的元素是否连续

            判断两个指针变量之间相隔几个元素

      int a[5]={2,3,4,5,6};

     int *p=a;//p指向了数组的书元素

     int *p1 =&a[3]; p1指向了数组的第四个元素

     //地址值(p1-p/sizeof(int)

     printf("p1 - p =%d\n",p1-p);

     

     如果两个指针变量指向同一个元素 那么他们相减等结果时0

     判断两个指针变量指向的元素是不是相邻,如果相邻他们相减的结果 绝对值为1

     两个指针之间的运算关系 p1 >p  == 1 表示的是p1在高位值

                        p1 >p  ==0  表示p在高位

     注意:两个指针之间没有加法。

     5用数组名访问二维数组

            int a[3][4]={1,2,3,5,7},{9,11,13,15},{17,19,21,23};

     a代表地0行点首地址 a+1表示第一行首地址 a2表示第二行的首地址,所以a+i代表行号 

     a[0] 表示第0行第0列第一个的地址,a[0]+1表示第0行第1列第一个的地址 a[0][j]表示第0行第j列的第一个的地址

     15 普通指针访问二维数组

     int a[2][3]={1,2,3,4,5,6};

     int *p =a;

     for (int i =1; i< 6;i++){

        printf("%d",*p++);

     }

     这里是应为数组他排列示在内存是这样的。

     1

     2

     3

     4

     。。

     说一可以写成*p++

    6二维数组指针

        行指针 ,用来表示指向二维数组的每一行,存放的是首地址

        定义格式:数据类型 (*行指针变量名)[数组的第二维的长度];

     二维数组指针的初始化

       int a[2][3];

     // a= &a[0] = a[0] == &a[0][0]

     首行第一个元素的地址 ,首行地址 ,首行首列元素地址 都可以表示位二维数组的地址

      int (*p)[3]=a;

     二维指针的使用

        *(*(a+i)+j)//就是获取二维数组的每一个元素

  

    二维数组指针遍历数组
    #include <stdio.h>
   int main(int argc, const char * argv[]) {
     int a[2][3] = {{1,2,3,},{4,5,6}};
     int (*p)[3] = a; //二维数组指指针  p可以代替数组名a来用
     //数组的遍历
     for (int i =0;i<2;i++){
     for (int j=0; j<3; j++) {
     printf("%d\t",*(*(p+i)+j) );//  *(*(a+i)+j)
     }
      return 0;
     }


 7 指针数组和二维数组指针的区别

      两者都可以用来表示二维数组 但是便是方法和意义不同

     int *p[3]={&a,&b,&d};p是一个指针数组

      //表示配饰一个指针数组,有三个下标为p[0];p[1];p[2];均为指针变量

     int *p[2]={a[0];a[1]};

     int (*p)[3];//二维数组指针 表示一个指向二维数组的指针变量

四、 字符串指针

      字符串指针指向 字符窜

     char *变量名=字符串";//”字符串内容“是常量

      char *str="wearefamily" 这个字符串是存储在常量去的

       str只是保存了字符串常量的首地址。 指针变量都是占8个字节的

     str是指针变量 ,str 还可以指向别的字符串常量  当指向"hahha"

这时str保存的是"hahha" 

     读取字符串的某个字符

      prinf("%c\t",*(str+2))

     for (inti =1;i<strlen(str;i++){

        printf("%c\t" *(str+i) );

     }

     *(str+2)='x';错误。应为字符串常量是在常量存储区的,保存在常量区保存的数据都是只读 不能修改。

     char*str2 ;

     scanf("%s",str2);z这样不能写应为str2 没有赋初始值 ,为野指针

     可以这样定义int *str2= NULL; //空的意思 

             str2=malloc(100);者句话作用是先给申请一个100自己度内存str2

 char 型指针数组 和字符数组的区别

     二维字符数组 

     char ch[3][4]+{{},{}<{}};

     或者 char ch3[3][5]={"abc","cdf","sdsa"}

       //可以存储多个字符串

     //第一维存的事字符串的首地址

     //每个字符串的长度,不能超过二维长度。

     

     char 类型的指针数组

     char *name[3]={"asdad","adadsadf","qwqewqeq"};

     遍历

      for (int i=1;i<3,i++){

       printf("%s",name[i])

     }

     

     char ch[]="abc"; 这是存储在栈区

     

     字符指针和字符数组

     字符指针  char *ss ="abc";

      ss 是一个指针变量 ,指向可以改变 

        ss = "helloword";

     字符数组  char s1[3]= "abc";

      s1是个常量,不能被赋值 。

     应用字符串排序。

  应用字符串排序。
     #include <stdio.h>
     #include <string.h>
     void sortString(char*arry[],int length);
     
     int main(int argc, const char * argv[]) {
     //定义char类型的指针 来存储临时的地址
     
     char *name[]={"CHINA","AMERICA","AUSTRALIA","FRANCE","GERMAN"};
     
     sortString(name, 5);
     
     return 0;
     }
     void sortString(char*array[],int length){
     char *temp;
     for(int j=0;j< length-1;j++){
     for (int i=0;i< length-1-i;i++){
     //比较两个字符串的ascii的大小
     
     if (strcmp(array[i],array[i+1]) >0){
     //实现array[i]和array[i+1]地址的交换
     temp = array[i];
     array[i]=array[i+1];
     array[i+1]=temp;
     
     }
     
     }
     }
     for (int i =0; i<length; i++){
     printf("%s\n",arry[i]);
     }
     
     }


五、指针与函数

     1.指针函数

     概念 指针函数就是一个函数返回的事一个指针(即地址)这中国返回指针值的函数就叫指针函数

     2定义  类型说明符 *函数名(形参){

                函数体

           return 地址

     }  

     在函数名前加了一个"*" 表示这是一个指针函数 ,即返回值是一个指针,类型说明符表示返回的指针指向的数据类型

      int *max(int x,int y){

            return x>y ? &x:&y;

     

     }

     int *max1(int *x,int *y){

            return *x > *y?  x : y;

     

     }

     

     

     int main(int argc,const char*arv[]){

        int a =3,b=4;

        printf("a =%p\n",&a);

        printf("b = %P\n",&b);

        int *pmax(a,b); 这里传进去后只是返回到形参的值。形参变量事新分配空间

 

       int *p1=max1(&a,&b);这里才是实参的改变 ,变量没有新分配空间只是形参和实参的地址传递

     }

 应用 通过指针输入1到7 到数字 输出对应的星期名
     #include <stdio.h>
     char * getWeekday(int n);
     int main(int argc, const char * argv[]) {
          printf("%s\n",getWeekday(1));
          return 0;
     }
    
     char * getWeekday(int n){
         char * weekday[]={
     "星期一",
     "星期二",
     "星期三",
     "星期四",
     "星期五",
     "星期六",
     "星期日",
     };
     return n<8&&n>0 ? weekday[n-1]: "输入错误!";
     
     }


  2 函数数的指针

        在c语言中 ,函数名就是该函数所占内存区的首地址, 这个函数点首地址赋给一个指针变量,使该指针变量指向改函数。然后可以找到并调用这个函数,把这种指向函数的指针变量称为“函数指针变量”

     函数指针变量:存放函数的首地址的指针变量就是函数指针变量

     

     函数指针变量的定义 (*变量名)(函数的参数);

     

     函数的声明 :

      int sum(int a,int b);------->函数指针int (*p)(int a,int b); 

     这里定义了一个函数指针p1 p1可以存放返回值是int类型,并且有两个形参 还都是int类型的函数地址

     p1 = sum ;//sum存的就是函数在内存中的首地址

      int sum (int a,int b){

     

        return a+b ;

     }

        int main(){

     int a =4,b=5;

     int (*p)(int,int);//定义函数指针 ,定义指针函数的时候可以不用写行参名

    p =sum ;//初始化 sum 函数的首地址

     

     }

 

  3.  函数指针调用函数

     

     #include <stdio.h>

     int sum (int a,int b){

     

        return a+b;

     }

     

     

     int main(int argc, const char * argv[]) {

     

     指针函数的使用

     //定义一个指针函数

     int (*P)(int,int);

     //给函数指针初始化

     p=sum;

     //用函数指针间接调用函数

         

     int s= p(23,45);

     

     printf("%d",s);

     

     return 0;

     

     }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值