您的位置:首页 > 移动开发 > IOS开发

iOS基础(c)—数组

2015-07-10 15:51 369 查看
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
一 数组的概念

    在程序设计中,为了处理方便,把具有相同类型的若干变量按有序的形式组织起来,这些按序排列的同类数据元素的集合称为数组。

    在c语言中,数组属于构造数组类型,一个数组可以分解为多个数组元素,这些数组可以是基本数据类型或是构造类型。

    简而言之:数组就是一组具有相同数据类型的数据的有序的集合。

二 数组的分类

    按照数组元素的类型不同,数组可分为:数值数组、字符数组、指针数组、结构数组。

    按照纬度分类可以分为:一维数组、二维数组、多维数组。

三 一维数组

    1、概念:如果一个数组的所有元素都不是数组,那么该数组称为一维数组

    2、定义方式:类型说明符 数组名 [常量表达式];

      例如:       int a[3];                         //定义了一个数组,数组名是a ,数组的长度是3

                                            //这个数组只能存放3个 int类型的数值

                                              int   //表示的是数组用来存放int类型的数据

 

       float f1[4];                     //定义了一个长度为4的数组,数组名是f1,数组中存放的一定要是float类型的数据

                                              float   表示数组的每个元素都应该是float类型的

      

       注意事项
        1) 数组的长度是可以是一个常量
也可以是常量表达式
            int a1[3+3];                                 //3+3是常量表达式
    
        2)
数组名的命名规则:严格按照标识符的命名规范
    
        3)
数组名不能和其他变量同名
             int a4;                      //这是一个整型变量
             int a4[5];                  //定义了一个整型数组
    
        4)
数组的长度不可以为一个变量(C99标准要求的)
            int len =4;
            int a5[len];                     //这是我们xcode编译器做的优化
                                                 //放到c++编译器就报错
    
        5)
数组的长度可以使用 宏定义
             int a6[M];                          //M是一个宏定义
    
        6)定义数组的时候,还可以定义普通变量
             int x,y,a7[4];                     //定义两个整形变量 x y
                                                     //又定义了一个长度为4 数组名为a7的数组

   3、一维数组的初始化

        什么是初始化?

        给数组的每一个元素赋一个初始值

 

        数组的初始化方法:

 

        1)定义的同时进行初始化

       

         格式:

         数据类型 数组名 [长度] = { 值1,值2,...} ;

 

          (1)定义的同时完全初始化

            //定义了一个长度为3的数组,数组名是a,给数组的每一个元素进行赋值

            int a[3]={1,2,3};             //第1个元素 1,第2个元素 2,第3个元素 3

 

            //定义个一个数组,数组名是a2,数组的长度根据后面大括号中赋值的个数来决定的(此处大括号中有3个值,所以数组长度是3)

            int a2[]={233,45,6};       //第1个元素 233,第2个元素 45,第3个元素 6

 

          (2)定义的同时进行部分初始化

           //定义了一个长度为3的数组,数组名是a1,给数组的元素进行赋值

           //第1个元素 1

           //第2个元素 23

           //第3个元素 0?

           int a1[3]={1,23};     //第一种方法

 

           //定义一个长度为10的数组,数组名是a4,

           //[3] 表示下标为3的元素赋初值23

           //[8] 表示下标为8的元素赋初值34

           int a4[10]={[3]=23,[8]=34};

 

         2)先定义数组,然后在初始化

 

            int a5[4];  //定义了一个数组

 

            //通过下标法进行初始化

            //数组长度是4   下标是数组的元素的编号

            // 0  1  2  3

 

            a5[0] = 12;  //给第一个元素赋值12

            a5[1] = 34;  //给数组的第二个元素赋值34

            a5[2] = 1;

            a5[3] = 20;

 

          探讨,如果数组没有初始化,到底有没有值?

              1)如果没有进行初始化,这时候,数组的元素是有值得

              如果有,到底是什么值?

              2)垃圾值

           *如果数组进行了部分初始化 数组没有被初始化的那些元素有没有值?

              1)如果进行了部分初始化,数组中的其他元素也都有值了

               如果有,到底是什么值?

              2)如果进行了部分初始化,没初始化那部分的元素也自动被系统初始化为0了

              例如:

#include <stdio.h>
int main(int argc, const char * argv[]) {
char ch[10]={'a','b','c'};
// 0 1 2 3 4 5 6 7 8 9
for(int i=0;i<10;i++) {
printf("%d\t",ch[i]);
}
return 0;
}
              运行结果为:      
97  98  99  0  0	0  0  0  0  0
    4. 一维数组的引用方式

        数组元素是组成数组的基本单元。数组元素也是一种变量,其标识方法为数组名后跟一个下标。下标表示了元素在数组中的顺序号。

        数组元素访问一般形式:

        数组名 [下标]

        其中下标只能为整型常量或整型表达式。如为小数时,C编译将自动取整。例如:

        a[5]

        a[i+j]

        a[i++]

        都是合法的数组元素。

        数组元素通常也称为下标变量。必须先定义数组,才能使用下标变量。在C语言中只能逐个地使用下标变量,而不能一次引用整个数组。例如,输出有10个元素的数组必须使用循环语句逐个输出各下标变量: 

for(i=0; i<10; i++){
printf("%d",a[i]);
}
       而不能用一个语句输出整个数组。因此,下面的写法是错误的:
printf("%d",a);
   

      例如:使用for循环为一个数组输出。

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

//假设有数组int a[10]={1,2,3,4,5,6,7,8,9,10};
//下标的范围:0 ~ 9
int a[10]={1,2,3,4,5,6,7,8,9,10};

//1、正序输出 1 2 3 4 5 6 7 8 9 10
for (int i=0; i<10; i++) {
printf("%d\t",a[i]);
}
printf("\n");

//2、逆序输出数组的元素
for(int i=9;i>=0;i--){
printf("%d\t",a[i]);
}

return 0;
}
   

    5. 数组的存储方式

        存储方式:

       1)计算机会给数组分配一块连续的存库空间

        2)数组名代表数组的首地址,从首地址位置,依次存入数组的第1个、第2个...、第n个元素

        3)每个元素占用相同的字节数(取决于数组类型)

        4)并且元素之间的地址是连续

        例如:

#include <stdio.h>
int main(int argc, const char * argv[]) {
//定义两个数组
int x[]={1,2};
char ca[5]={'a','B','C','D','E'};
printf("x = %p\n",x);
printf("ca= %p\n",ca);
printf("数组名x=%p\n",x);         //观察x的值和 &x[0]的地址是否相同
printf(" &x[0] = %p\n",&x[0]);     //低
printf(" &x[1] = %p\n",&x[1]);     //高
//ca[0]  低
//ca[4]  高
printf("ca = %p\n",ca); //ca是数组名 == &ca[0]
for (int i=0; i<5; i++) {
printf("&ca[%d] = %p\n",i,&ca[i]);
}
return 0;
}
        运行结果为:

x = 0x7fff5fbff7a0
ca= 0x7fff5fbff78b
数组名x=0x7fff5fbff7a0
&x[0] = 0x7fff5fbff7a0
&x[1] = 0x7fff5fbff7a4
ca = 0x7fff5fbff78b
&ca[0] = 0x7fff5fbff78b
&ca[1] = 0x7fff5fbff78c
&ca[2] = 0x7fff5fbff78d
&ca[3] = 0x7fff5fbff78e
&ca[4] = 0x7fff5fbff78f
       

         *探索  1、数组x和数组ca他们的地址一定连续吗? 可以不连续的

                           数组名代表了数组的首地址

                           通过打印两个数组的地址,证明:先定义的数组分配在高地址

                      2、数组各元素的地址是连续的么?

                           两个元素相差4个字节,是

                           查看ca数组的每一个元素的地址,观察是否连续

                      3、数组名代表了数组的首地址 == 数组的第一个元素的地址

                            x == &x[0]

                           ca == &ca[0]

    

                           数组名是一个常量 存储的就是数组的首地址

                           ca = 1;

    6. 冒泡排序(经典)

        基本思路:对尚未排序的各元素从头到尾依次比较相邻的两个元素是否逆序(与欲排顺序相反),若逆序就交换这两元素,经过第一轮比较排序后便可把最大(或最小)的元素排好,然后再用同样的方法把剩下的元素逐个进行比较,就得到了你所要的顺序。可以看出如果有 n 个元素,那么一共要进行 n-1 轮比较,第 i 轮要进行 j=n-1-i 次比较。

        代码如下:

#include <stdio.h>
void maoPao(int arr[],int len){
int temp;
//双重循环
for(int i=0;i<len-1;i++){
//因为i的值每变化一次,跑了一趟,按照冒泡的思想
//有一个数已经下沉了
//没有必要和已经有序的数据进行比较了
//j<len-1-i;
for (int j=0; j<len-1-i; j++) {

if (arr[j]>arr[j+1]) {
//交换 a[j] 和 a[j+1]的值
// 加减法   异或   temp
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}

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

int a[10]={1,200,23,45,12,34,19,4,388,63};
//a[0] 1
//&a[0]  地址
//排序前
for (int i=0; i<10; i++) {
printf("%d\t",a[i]);
}

printf("\n");
//进行排序
maoPao(a, 10); //把数已经排玩序了
//遍历数组
for (int i=0; i<10; i++) {
printf("%d\t",a[i]);
}

int a1=3;
a1 = a1+3;

return 0;
}
        最坏的情况:n个数的时候,需要比较n(n-1)/2次比较。

        原理:n个数,第一轮,比较n-1次,得到最大(或最小)数,余下的n-1个数,比较n-2次,得到排第二位的数,以此此类推,最后比较1次,确定最后两个数的大小,故共比次数:1+2+...+n-1=(1+n-1)(n-1)/2=n(n-1)/2。

        冒泡排序是一个非常重要的算法,也是面试中最容易涉及到的知识点之一。

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息