黑马程序员-----C语言学习之数组与指针

讲他们之间的关系之前先了解下面几个名词的概念,通过实例分析他们之间到底存在什么联系

数组指针

 
          指向数组元素的指针

 

数组指针的作用

 
      使用数组指针间接访问数组的元素
 
数组指针的定义
 
      int *p;

 

数组指针的初始化

 
      int a[4]={1,2,3,4};
 
      int *p = a;  //数组指针,定义了一个指针变量p赋值数组的首地址(第一个元素的地址),p指向数组的第一个元素
 
      int *p = &a[0]; //等价上面一句话

 

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

 
      1)p+1   表示指向数组的下一个元素
      2)p-1   指向数组的上一个元素
 
总结


  
      对于一个一维数组来说
        
        int a[5];
 
      1)获取 a[i]的地址有几种方法?
 
          (1)&a[i]
 
          (2)a+i
 
          (3) int *p = a;
              p+i
 
      2) 获取 a[i]的值有几种方法?
 
         (1)a[i]
         
         (2)*(a+i)
         
         (3) int *p = a;
            *(p+i)
 
         (4)*(&a[i])


应用:逆序数组:


void nixuArray(int a[],int len){
    
    //定义数组指针
    int *p = a;
    
    //定义下标
    int i = 0,j = len-1;
    
    int temp;
    while (i
   
   


指针数组

 
       存放指针的数组,就是指针数组

 

指针数组的定义

 
       数据类型  * 数组名[数组长度];
 
 
       int *pa[3];
 
       //定义了一个指针数组,数组名是pa,可以用来存放3个指针(必须是int类型变量的指针)
 
指针数组的使用
   
 int a=3,b=4,c=5;
    int *pa[3]={&a,&b,&c};
    //打印的是指针数组的第一个元素得值
    printf("  &a    = %p\n",&a);
    printf("  pa[0] = %p\n",pa[0]);
    
    //打印指针数组的首地址
    printf("  pa    = %p\n",pa);
    printf("  &pa[0]= %p\n",&pa[0]);
    
    //访问a的值 a = 3
    printf("  *(&a)    = %d\n",*(&a));
    printf("  *(pa[0]) = %d\n",*(pa[0]));
    
    //使用数组名来访问 a的值
    //*pa  == pa[0] (a的地址)
    //**pa
    printf("%d\n",**pa);
    
    int a1[2][2]={1,2,3,4};
    //定义了一个指针数组 ,赋值为a1[0] 是第一行的地址
    int *pa1[2]={a1[0],a1[1]};
    printf("**pa1 = %d\n",**pa1);
    //pa1+1   &pa1[1]
    //*(pa1+1)  pa1[1]
    printf("**(pa1+1) = %d\n",**(pa1+1));


两个指针变量之间的运算
 
    1)两个指针之间的减法运算
 
       (1)0x0006  - 0x0003   =  3  (意义不大)
 
       (2)常见的用法:两个指针都指向同一个数组
 
            i.判断两个指针变量指向的元素是否连续
            ii.判断两个指针变量之间相隔几个元素
 
            int a[5]={1,2,3,4,5};
            int *p = a; //p指向了数组的第一个元素
            int *p1 = &a[3]; //p指向了数组的第四个元素
 
  
注意:两个指针变量之间没有加法运算
如果两个指针变量指向同一个元素 那么他们相减的结果是 0
判断两个指针变量指向的元素是否相邻(连续),他们相减的结果是 1的绝对值




    //2、两个指针变量之间的关系运算
    // p1 > p  //使用大于或者小于来比较的 不是相减;
    //1    表示p1在高位(这里就是p1>p)
    //0    p在高位或者他们指向了同一个位置(这里可能是p1<p或者是p1=p)
    printf("p1 > p = %d\n",p1 > p);



数组名访问二维数组之指针在二维数组中的应用
   
int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};
    
    //列指针
    //a[0] == &[0][0]  a[0]+1==&a[0][1]   a[0]+2==&a[0][2]
    printf("&a[0][1] = %p\n",&a[0][1]);
    printf("a[0]+1   = %p\n",a[0]+1);
    printf("*(a[0]+1)   = %d\n",*(a[0]+1));  //3
    
    
    printf("&a[0][2] = %p\n",&a[0][2]);
    printf("a[0]+2   = %p\n",a[0]+2);
    
    //行指针  a[0]  a[1]  a[2]
    //a+1    //第二行的首地址
    //a+2    //第三行的首地址
     printf("a[1]   = %p\n",a[1]);
     printf("a+1   = %p\n",a+1);
    
     printf("a[2]   = %p\n",a[2]);
     printf("a+2   = %p\n",a+2);
    
     // a+1 第二行第一个元素的地址
     //*(a+1)  == &a[1][0]
    
    printf("*(a+1) = %p\n",*(a+1));
    printf("&a[1][0] = %p\n",&a[1][0]);
    
    
    //a[i]+j     获取的 &a[i][j]
    //*(a[i]+j)  获取 a[i][j]
    //a[i]      *(a+i)
    //*(*(a+i)+j); ----->  a[i][j]
    for (int i=0; i<3; i++) {
        for (int j=0; j<4; j++) {
            //a[i]    *(a+i)
            //printf("%d\t",*(a[i]+j));
            printf("%d\t",*(*(a+i)+j));
        }
        
        printf("\n");
    }




 数组指针
 
    定义一个指针变量,让这个指针变量指向一维数组的元素
 
 
 二维数组指针
 
     行指针,用来指向二维数组的每一行,存放的是行的首地址
    
     定义格式:  数据类型  (*行指针变量名)[数组第二维的长度];
    
 二维数组指针的初始化
 
   int a[2][3];
   int b[2][2];
   float f1[4][4];
 
   //假设我要定义一个指向数组a的一个行指针
   // a  = &a[0]  = &a[0][0]  = a[0]
   int (*p)[3] = a;

 

二维数组指针的使用

 
    *(*(p+i)+j)  //就是获取二维数组的每个元素
 
实际操作:


int main(int argc, const char * argv[]) {
    int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};
    
    //二维数组指针
    //二维数组指针可以替代数组名去使用
    int (*p)[4] = a;
    
    for (int i=0; i<3; i++) {
        for (int j=0; j<4; j++) {
            //遍历数组
            printf("%d\t",*(*(p+i)+j));
        }
        printf("\n");
    }
    
    return 0;
}



指针数组喝二维数组指针的区别:
1.int *p[3]={&a,&b,&c};pa是一个指针数组;
2.int (*p)[3];这是一个二维数组指针;
前者表示一个指针数组,有三个下标变量p[0],p[1],p[2];
后者表示一个纸箱二维数组的指针变量。表示长度为3的一维数组或者说它的烈说为3;




字符串指针:
 
       定义: char *字符串指针变量名 = "字符串内容";
 
       用作:用来保存一个字符串


实际操作如下


#include 
    
    
     
     
#include 
     
     
      
      
#include 
      
      
       
       


int main(int argc, const char * argv[]) {
   
    //"zfbanzhang zaiyiqi" 这个字符串存储在常量去
    //str 只保存了字符串常量的首地址
    char *str = "zfbanzhang zaiyiqi";
    //指针变量都是占用8个字节
    printf("sizeof(str) = %ld\n",sizeof(str));
    printf("str len = %ld\n",strlen(str));
    
    //str是指针变量
    //str重新指向另外一个字符串常量 "I LOVE YOU"
    //保存的是 "I LOVE YOU" 字符串常量的首地址
    str = "I LOVE YOU";
    printf("%s\n",str);
    
    char ch[]="abc";  //存在栈区
    ch[2]='Z';
    printf("%s\n",ch);
    
    //读取字符串常量的某个字符
    printf("%c\n",*(str+2));  //L
    for (int i=0; i
       
       
        
        %s\n",str3);
    
    return 0;
}



       
       
      
      
     
     
    
    


一维字符数组
 
       char  ch[10]={'a','b'};
 
       char ch1[]="abc";
 
 
二维字符数组
 
       char ch2[3][10]={{'a','b'},{'b'},{'c'}};
 
    用二维数组来保存多个字符串
 
       //用二维的字符数组可以存储多个字符串
       //第一维存的是每个字符串的首地址
       //每个字符串的长度,不能超过第二维长度
       char ch3[3][5]={"abc","def","kkkk"}
  
 
           a  b  c  \0  \0
           d  e  f  \0  \0
           k  k  k  k   \0
 
 
           ch[1][3] = 'Z';




实例操作如下:



#include 
    
    
     
     


int main(int argc, const char * argv[]) {
    
    char ch3[3][5]={"abc","def","kkkk"};
    //存放的是一个二维数组
    ch3[1][3] = ‘Z’;//将第二行第四列的值改为z 也成为赋值;
    
    for (int i=0; i<3; i++) {
        printf("%s\n",ch3[i]);
    }
    
    return 0;
}
    
    



 
char型指针数组和字符数组区别:
    //char 类型的指针数组
    char *name[3]={"abcdasfadsfasdfasdfasdf","def","kkk"};
    
    for (int i=0; i<3; i++) {
        //name[i]
        printf("%s\n",*(name+i));//这里打印的值可以直接谢伟name[i];


    }

    
字符串指针和字符数组的区别
    
    //字符串指针:
                      char *ss = "abc";
    
    //指向可以改变
    //ss是一个指针变量
                      ss = "helloWorld!";
    
    //字符数组:
    
                      char s1[]="abc";
    //s1是数组名,是一个常量,不能被赋值,是不能改变的;
                      //s1 = "helloworld!";




字符串排序应用:
#include 
    
    
     
     
#include 
     
     
      
      


/**
 *  实现字符串的排序
 *
 *  @param arr <#arr description#>
 *  @param len <#len description#>
 */
void sortString(char *arr[],int len){


     //冒泡排序
     //临时存放地址
    char *temp;
    for (int i=0; i
      
      
       
       0) {
                //实现arr[j]  arr[j+1]交换
                temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
                
            }
            
        }
    }
    


}


int main(int argc, const char * argv[]) {
    
    //输入5个国名并按字母顺序排列后输出。
    char *name[]={ "CHINA","AMERICA","AUSTRALIA","FRANCE","GERMAN"};
    
    for (int i=0; i<5; i++) {
        printf("%s\n",name[i]);
    }
    
    //字符串排序
    sortString(name, 5);
    
    printf("\n\n");
    for (int i=0; i<5; i++) {
        printf("%s\n",name[i]);
    }
    return 0;
}


      
      
     
     
    
    



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值