关闭

[黑马IOS自学第五篇]C语言二维数组,排序法学习

标签: c语言iosios学习苹果黑马
277人阅读 评论(0) 收藏 举报

     一.补充关键字char,short关键字

            

      /*

       1.改变整型变量占用的存储空间

       int short long long long

       

       改变一个数的符号

       signed unsigned

       */

       


     
    <span style="font-size:24px;">1).代码举例</span>
    #include<stdio.h>
     
    int main(int argc,const char * argv[]) {
       
        shortint a = 1 ;//short占用两个字节 16位
        //10000000 00000000 2字节最小负数
        //01111111 11111111 2字节最大正数
        
        short int a1 =a<<15 ;
        printf("%d\n",a1);//-32768
        
        a1 = (a << 15)-1;
        printf("%d\n",a1);//32767
        
        
        int b = 1 ;
        int b1 = b<<31;//-2147483648
        printf("%d\n",b1);//左移直接得到原码
        
        b1 = (b<<31)-1;//2147483647
        printf("%d\n",b1);
        
        
        
        long int c =1;
        long int c1 = c<<63;//-9223372036854775808
        printf("%ld\n",c1);//左移直接得到原码
        
        c1 = (c<<63)-1;//922337203685477587
        printf("%ld\n",c1);
        
        
        //改变一个数的符号
        //计算机默认为有符号数
        unsigned short d = 0 -1  ;
        printf("%u\n",d);//65535
        
        unsigned int e = 0-1 ;
        printf("%u\n",e);//4294967295
        
        //char 类型常量的存储问题
        int len = sizeof('a');//4
        printf("%d\n",len);
        char ch = 'a' ;
        len =sizeof(ch);//1
        printf("%d\n",len);


    二.数组学习

    按有序形式组织,同类型数据元素的集合,数组属于构造数据类型

    1.下标

    2.维数

    数值数组字符数组指针数组结构数组 


     

     

    注意:区别两种写法,上面的Xcode下bian'yi编译器优化可以


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

    1.a[0] a[2] a[1] a[3]是变量


    数组初始化

    1.int a[]={……}; //不表明数组长度

    2,int a[2]={….};

     

    int a[10]={[2]=12,[6]=9,23};

           

    先定义长度,后初始化

    1.int  a[10];

    2.a[0]=1;

    3.a[1]=2;

    ……….


    2).字符数组 

     int a[10]={[2]=12,[6]=9,23};
        for (int i = 0 ; i < 10 ; i++) {
            printf("%d\t",a[i]);
        }
        
        int num= 9;
        int b[num];
        b[0]=1;
        
       // int arr[num]={12,33,444,3};
        
        /*
        输出结果:
         1 0 1606416344 32767 0 1 0 0 1606416360 32767
        值为不确定的垃圾数
         */
        printf("\n");
        int b1[10];
        for (int i = 0; i<10; i++)
            printf("%d\t",b1[i]);
        
        //\300 \367 \277 _ \377
        char ch[10];
        printf("\n");
        for (int i = 0; i<10; i++)
            printf("%c\t",ch[i]);
     
        
        //部分初始化
        int c2[10]={12};
        printf("\n");
        for (int i = 0; i<10; i++)
            printf("%d\t",c2[i]);
        //12 0 0 0 0 0 0 0 0 0
        
        /**///a v 没显示的不是空子符
       
     char ch2[10]={'a','v'};
        printf("\n");
        for (int i = 0; i<10; i++)
            printf("%c\t",ch2[i]);
        for (int i = 0; i<10; i++)
            printf("%d\t",ch2[i]);
     
     
     

    3).数组引用

    a[1]=2;

    1.如果是先定义,后初始化,对于没有被初始化的数组元素,系统不会对没有初始化的那部分元素进行初始化0的操作。


    4).数组的存储形式

    1.从首地址开始存第一个数组元素,依次类推

    2.先定义的数组存在高地址

     

    int a[2]={12,23};
        char ch[3]={'a','d','s'};
        
        printf("a[0]地址 : %p\n",a);//低地址
        printf("a[0]地址 : %p\n",&a);//低地址
        printf("a[0]地址 : %p\n",&a[0]);//低地址
        printf("a[1]地址 : %p\n",&a[1]);//高地址
        printf("ch[0]地址 : %p\n",&ch[0]);//低地址
        printf("ch[1]地址 : %p\n",&ch[1]);//高地址
        printf("ch[2]地址 : %p\n",&ch[2]);//高地址
     
        
        /*
         
         a[0]地址 : 0x7fff5fbff7b0
         a[0]地址 : 0x7fff5fbff7b0
         a[0]地址 : 0x7fff5fbff7b0
         a[1]地址 : 0x7fff5fbff7b4
         ch[0]地址 : 0x7fff5fbff79d
         ch[1]地址 : 0x7fff5fbff79e
         ch[2]地址 : 0x7fff5fbff79f
         */15/10/23
     

    数组名和第一个数组元素地址相同,数组名即是地址

     

     int a[ ]={12,23};
        char ch[3]={'a','d','s'};
     
        //计算整型和char型数组占用的字节数
        int len = sizeof(a);
        
        int len2 = sizeof(ch);
        
        printf("a = %d , ch = %d\n",len,len2);
        
        
        //数组的长度
        len = sizeof(a)/sizeof(int);
        len2 = sizeof(ch)/sizeof(char);
        printf("a = %d , ch = %d\n",len,len2);

    函数名作为函数参数时,是地址传递而不是值传递


     5).数组名传递

       
      //
      //  Created by CHINGWEI_MACPC on 15/10/23.
      //  Copyright © 2015年 itcast. All rights reserved.
      //
       
      #include<stdio.h>
      int transArry(int arr[]){
          for (int i = 0; i< 2; i++) {
              
              arr[i]=arr[i]+1;
              printf("%d ",arr[i]);
          }
          printf("\n");
          return 0;
      }
      int main(int argc,const char * argv[]) {
          
          int a[ ]={12,23};
          //printf("%p\n",a);
          for (int i = 0; i<2; i++) {
              printf("%d ",a[i]);
          }
           printf("\n");
          //transArry(0x7fff5fbff7b0);//数祖名A存储的是地址
          transArry(a);
          
          return 0;
      }

    注意点

    1.形参和实参长度可以不相同,只传送首地址而不改变数组长度

    虽然不会报错,尽量保持形参长度和类型一致

    2.形参长度可以不写

    3.数祖名作为参数后,长度信息丢失的问题

    4.C语言所有的地址都占8个字节

     
    int transArry(int arr[]){
        //C语言中规定,不管什么类型的数据,数据的内存地址
        //在内存中占用8个字节
        //此时函数名为一个地址所以sizeof计算出来的都是8字节
        int len = sizeof(arr);
        //int len = sizeof(&arr);
        return len;
    }
    int main(int argc,const char * argv[]) {
        
        int a[ ]={12,23,12,32};
        float b[]={2.3f,23.2f,9.f,23.33f,23.344f};
        int len = sizeof(a);
        printf("%d \n",len);//16
        printf("%p\n",a);
        printf("%d \n",transArry(0x7fff5fbff780));
        printf("%d \n",transArry(a));//函数名做参数传递后为 8
        printf("%d \n",transArry(b));//8
    }
     
     
     
     
    //排序方法
    //大数下沉,小数上浮
     
    #include<stdio.h>
    void bubble(int arr[] ,int len){
        
      
        for(int i = 0 ;i < len - 1 ;i++ ){
            for (int j = 0 ; j < len - 1 -i; j++) {
                //没有必要和已经有序的数据进行比较
                if (arr[j]>arr[j+1]) {
                    int temp = arr[j];
                    arr[j]=arr[j+1];
                    arr[j+1]=temp;
                }
            }
        }
       
    }
    int main(int argc,const char * argv[]) {
      
        
        int a[]={99,20,39,3,12,30,76,34,1,2,32};
        int len = sizeof(a)/sizeof(int);
        bubble(a,len);
        for (int i = 0 ; i < len ; i++) {
            printf("%d ",a[i]);
        }
        printf("\n");
        
        return 0;
    }

    6).选择排序

     

    //  C9选择排序
    //
    // Created by CHINGWEI_MACPC on 15/10/23.
    //  Copyright © 2015年 itcast. All rights reserved.
    //
     
    #include<stdio.h>
    void selectSort(intarr[] ,int len){
        //每走一趟找到一个最小的数
        for(int i = 0;i < len-1 ;i++ ){
           for (intj = i+1 ; j < len; j++) {
               if (arr[i]>arr[j]) {
                   int temp= arr[i];
                   arr[i]=arr[j];
                   arr[j]=temp;
               }
           }
        }
    }
     
    int main(intargc,const char* argv[]) {
        int a[]={99,20,39,3,12,30,76,34,1,2,32};
        int len = sizeof(a)/sizeof(int);
        selectSort(a,len);
        for (int i = 0; i < len ; i++) {
           printf("%d",a[i]);
        }
        printf("\n");
        
        return 0;
    }

    7).折半查找思想

    #include<stdio.h>
    int searchItem(intkey ,int arr[] ,intlen){
        
        int low =0 ,high = len -1 , mid ;
        
        while (low <= high ) {
           mid =(low+high)/2;
           if (key > arr[mid]) {
               low = mid+1;
                       }
           else if(key<arr[mid]){
               high = mid -1;
           
           }
           else
           {
               return mid;
           }
           
        }
        return -1 ;
    }
     
    int main(intargc,const char* argv[]) {
        int a[]={1, 2 ,3 ,12 ,20 ,30 ,32, 34, 39, 76 ,99};
        int len = sizeof(a)/sizeof(int);
        int result = searchItem(32,a,len);
        
        if (result != -1) {
           printf("a[%d]= %d  \n",result,a[result]);
        }
        else {
           printf("未找到! \n");
        }
        printf("\n");
        
        return 0;
     
           
     
     
    #include<stdio.h>
    int insertItem(intkey ,int arr[] ,intlen){
        
        int low =0 ,high = len -1 , mid ;
        
        while (low <= high ) {
           mid =(low+high)/2;
           if (key > arr[mid]) {
               low = mid+1;
           }
           else if(key<arr[mid]){
               high = mid -1;
               
           }
           else
           {
               return mid+1;
           }
           
        }
        return low ;
    }
     
    int main(intargc,const char* argv[]) {
        int a[]={1, 2 ,3 ,12 ,20 ,30 ,32, 34, 39, 76 ,99};
        int len = sizeof(a)/sizeof(int);
        int result = insertItem(18,a,len);
        
        printf("在第[%d]个位置插入 = %d  \n",result,18);
        
        printf("\n");
        
        return 0;
    }<span style="font-family: Calibri; font-size: 13.5pt; background-color: rgb(255, 255, 255);"> </span><span style="font-size: 13.5pt; font-family: Menlo;"> </span>

    折半插入值

      

    三.二维数组的定义

    1).int arr[][]; 


     

    2).数组定义初始化

        

    int arr[][3]={1,2,3,4,5};
        int arr2[2][8];
        
        //地址值
        printf("%p\n",&arr);
        printf("%p\n",&arr[0]);
        printf("%p\n",&arr[0][0]);
        /*
        0x7fff5fbff74c
        0x7fff5fbff74c
        0x7fff5fbff74c
        */
        
        //计算占用的总字节数
        int len = sizeof(arr2);
        printf("%d\n",len);
        
        int len2 = sizeof(arr[1])*2;
        printf("%d\n",len2);
        
        //计算有多少列数
        //列数=行的总字节数 /每个元素占用的字节(数组类型)
        len2 = sizeof(arr2[1])/sizeof(int);
       printf("列数 = %d\n",len2);
        
        //计算行数
        //粽子结束
        len = sizeof(arr2)/sizeof(arr2[0]);
       printf("行数 = %d\n",len);


    3).二维数组中元素之间的地址是连续的


     

     N*M矩阵:

    二维数组名做参数

    注意事项:

    地址传递

    字符串以"\0"结束

    再内存中所占字节比实际多一个

     

    int main(intargc,const char* argv[]) {
        
        
        char ch[5]={'a','a','s','n','x'};
        
        char ch2[4];
        ch2[1] ='s';
        ch2[2] ='1';
        
        
        
        char ch3[2][17];
        //ch3[0] ="asdsdsdsdssad";
        //ch3[1] ="sxxsdwwewewew";
       // ch3[0] ={'a','a','s','n','x'};
       ch3[0][0] = 'a';
        
        
        char str[] = "helloworld";
        for (int i = 0; i <sizeof(str); i++) {
           printf("%c ",str[i]);
        }
        return 0;
    }
     


       

     四.多维数组和指针

    一维数组名即是一个指针常量,它代表数组第一个元素的地址,我们知道一维数组的长度,那么可以通过数组名输出一维数组的所有元素:

    #include <stdio.h>
    int main(void)
    {
        int i;
        int a[5] = {1, 2, 3, 4, 5};
        int *p = a;
        for( i = 0; i < 5; i++ )
            printf( "%d\n", *(p + i) );
        return 0;
    }


    但是在多维数组中,数组名却是第一个数组的地址,怎么理解呢?比如说定义一个二维数组:

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

                  6, 7, 8, 9, 10};

    那么数组名a就是二维数组的第一行一维数组的地址,而不要错误的认为它代表的是第一行第一个元素的地址噢,那我们应该怎么正确的申明一个指向整形数组的指针呢?

    int(*p)[5] = a;

    它使p 指向二维数组的第一行的一维数组(注意是指向的第一行一维数组)。

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


    上面的程序也是依次输出了1~5,这里p 是指向二维数组的第一行地址的指针,那么 *p 即是代表第一行数组,那么也就是第一行数组的地址,我们可以再通过 *(*p + i)输出第一行数组的各个元素。有点乱?呵呵,再仔细想想,或者直接说 a 是指向的第一行,那么 *a 就代表第一行的那个一维数组,但 *a 仍然是一个指针常量,而**a 才是这个一维数组的第一个元素的值。

     

    如果我们要定义一个指针可以逐个访问元素呢?下面两种方法都是正确的声明和赋值:

    int*p = &a[0][0];

    int*p = a[0];

    第一种方法,就干脆把数组的第一行第一个元素取地址给指针变量p,这可能是最直观的方法。

    第二种方法,其实原理一样,前面刚说了a 是指向的第一行,第一行是一个一维数组,那么a[0]就是这个一维数组的第一个元素的地址。特别注意这里的 a[0] 不是一个值,而是一个地址。

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


    上面的代码就输出了二维数组中的所有元素。

    附:这里的a[0]却输出了hello

    int main(void)
    {
        char a[2][10] = {"hello", "hi"};
        printf( "%s\n", a[0] );
        //printf( "%s\n", *a );
        //printf( "%s\n", *a + 1 ); 输出 "ello"
        //printf( "%s\n", *(a + 1) ); 输出 "hi"
        return 0;
    }


    而这又是为什么呢?这里的a[0] 仍然是一个地址,它指向的是一个字符串常量,%s 是可以打印地址的,这里跟 %d 输出值是不一样的,a[0]指向了字符串的第一个字母的地址,一直输出到 NUL 为止。

     

     

    //  C8数组名传递

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:8838次
    • 积分:264
    • 等级:
    • 排名:千里之外
    • 原创:18篇
    • 转载:0篇
    • 译文:0篇
    • 评论:1条