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

原创 2015年11月21日 09:45:00

 一.补充关键字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数组名传递

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

C语言 选择排序、折半查找法与二维数组

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ------- 19.选择排序 for (int i = 0; i1; i++) {    ...

黑马程序员———C语言———【二维数组、字符串】

————————————————————————————————————————————————————————————————————————————— 一、二维数组的定义 1、概念:可以看做是一个...

黑马程序员 C语言 - 06 数组、二维数组、字符串

若pai'baC语言 - 06 数组、二维数组、字符串.pdf

c语言寻找二维数组中的鞍点

  • 2015年11月06日 19:34
  • 2KB
  • 下载

C语言动态分配二维数组

  • 2013年04月06日 17:04
  • 6KB
  • 下载

C语言学习笔记:18_数组-二维数组

/* * 18_数组-二维数组.c * * Created on: 2015年7月6日 * Author: zhong */ #include #include /** *...

c语言 二维数组 源码

  • 2013年06月08日 21:12
  • 513B
  • 下载

C语言二维数组的定义和引用

  • 2013年03月18日 11:28
  • 44KB
  • 下载

C语言学习篇-7数组、二维数组、高维数组

说明:本文主要对数组进行阐述,并对二维及高维数组进行举例。数组 数组:用来存储一组同种类型数据的构造数据类型称之为数组。数组属于构造类型; 具有相同数据类型的成员组成的一组数据; 存储不同类型数据的数...

用C语言求二维数组鞍点

  • 2012年10月23日 22:45
  • 709KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:[黑马IOS自学第五篇]C语言二维数组,排序法学习
举报原因:
原因补充:

(最多只允许输入30个字)