您的位置:首页 > 其它

数组的简单总结

2017-10-19 18:25 120 查看

                                数组

 1.定义
      一组相同类型元素的集合

 2. 创建方式
      
         type_t   arr_name   [const_n];
        
         //type_t 数组的元素类型
        //[const_n] 常量表达式,用来指定数组的大小

 3.数组的类型
 
int b;
   int arr[10];
  
    对比两个声明,变量b的是一个标量,它的类型是整型;arr[10]的类型也是整型,这一声明表示arr是一个整型数组;数组名arr的值是一个指针常量,所指向的是首元素地址,并非数组的类型。int
[10] 才是数组的类型,它是指向 int 的常量指针,如果是 char arr[10],表示数组arr是指向 char 的常量指针。

 4、数组名不用指针常量表示的两种情况
  例:
int main()
{
int arr[]={1,2,3,4,5};
printf("%d\n",sizeof(arr));
printf("%p\n",&arr);
printf("%p\n",&arr+1);
return 0;

}
运行结果:

         


  
    分析: sizeof操作符求的整个数组的长度,共20个字节,可见放在sizeof内部的数组名表示整个数组;&运算符此时取出整个数组的地址,当&arr+1时,取出的地址不再是arr数组中某一元素的地址,而是跳过整个数组,取出arr数组下一个数组的地址。

  5、下标引用和指针
     
    下标引用即对数组的每个元素给相对应的下标序号;对于数组而言,数组名是一个常量指针,故我们可以使用指针进行间接访问数组的每个元素。

例:int arr[10]={1,2,3,4,5,6,7,8,9,10};
    int *p=arr+2;
请计算以下4个表达式:1)*p+6; 2) p+6; 3) *(p+6); 4) p[-1];
 分析:
     1)条件中,p指向的是数组第三个元素 arr[2],“*”与“+”相比,“*”先执行,故而此时的结果为 arr[2]+6=9
     2) p指向arr[2],此时将p所指的元素是 arr[2] 向后移动6个整数位置的元素,即arr[8]或&arr[8];
        
     


     3)括号的优先级高于*,故而先执行(p+6),则此表达式的值为arr[8],和2式结果一样。(见上图)
     4)条件中p指向第3个元素(下标是2),偏移量-1使我们得到前一个元素arr[1];(见下图)
      
          


 6.数组的初始化
   
  6.1 不完整的初始化
    以下这几个定义正确吗?
     int arr1[5]={1,2,3,4,5,6,7};  /(1)
     int arr2[5]={1,2,3,4};        /(2)
     int arr3[5]={1,5};            /(3)
     int arr3[]={1,2,3,4,5};       /(4)

 分析:
  1)第一定义错误;arr1数组中的元素个数为5个整型变量,而给出的却为7个整型数,5个元素的数组显然放不下7个整型值。(见下图)

        


 2)第二个定义正确;arr2数组中的元素个数为5,而给出的为4个整型值,显然没有超过数组元素的个数,并且后面的值自动为0.(见下图)
   
        


  3)第三个定义正确;给出的整型值为1和5,少了2、3、4三个值,此时编译器默认初始值不够,不会知道中间缺少的值,故此后面的值默认为0.
        
            


  4)第四个定义正确;此时未给出数组的长度,编译器默认设置数组长度为刚好能够容纳所有初值的长度
      
                


  6.2 字符数组初始化
    以下这几个定义正确吗?
      char  arr1[]={'h','e','l','l','o','\0'};
      char  arr2[]="hello";
      char  *arr3="hello";
      char  arr4[]="hello";
  分析:
    1)正确;普通的初始化方法,将每个字符放到数组中。
    2)正确;前例的另一种写法,但并不是字符串常量。
    3)正确; 真正的字符串常量。这个指针变量被初始化为指向这个字符串的存储位置
         

  
    4)正确;初始化一个字符数组的元素,不是字符串常量。   
          
           


     6.3 多维数组的初始化
         
        以下这几个定义正确吗?

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

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

                  int arr3 [ ][4] = {{2,3},{4,5}}; 
                  int  arr4[3][ ] = {1,2,3,4 };
       分析:
       1)正确;此定义为一个3行4列的矩阵,其第一行为1,2,3,4,其余每行默认初值为0。

            


      
      2)正确;和上一定义一样,也为3行4列的矩阵,但给出只有两行的数值,并且每行数都不完整,默认为0.

               
        


     3)正确;不同于上一定义的是这里没有给出行数,编译器默认刚好能容纳所有初值的行数为数组的行数。

                


     4)错误;这种定义是错误的,没有给出列数,即没有给出可容纳的长度,故不能确定数组大小。
    
     7.一维数组的计算
   
 第一组:
  
int main()
{
int a[] = {1,2,3,4};
printf("%d\n",sizeof(a));          //16   整个数组的长度
printf("%d\n",sizeof(a+0));        // 4   首元素的地址
printf("%d\n",sizeof(*a));        // 4  首元素
printf("%d\n",sizeof(a+1));       //4  第二个元素的地址
printf("%d\n",sizeof(a[1]));      //4  第二个元素
printf("%d\n",sizeof(&a));       //4  整个数组的地址
printf("%d\n",sizeof(&a+1));     //4  下一个数组的地址
printf("%d\n",sizeof(&a[0]));    //4  首元素的地址
printf("%d\n",sizeof(&a[0]+1));  //4  第二个元素的地址

return 0;}
 
 分析:sizeof操作符计算所占空间大小时,只有当数组名单独放在内部时,表示整个数组,其余表示首元素地址;故此可求的以上各式的大小。(注:地址所占空间为4个字节)
  
第二组:

int main()
{
char arr[] = {'a','b','c','d','e','f'};
printf("%d\n", sizeof(arr));        // 6   整个数组的长度
printf("%d\n", sizeof(arr+0));     //  4   首元素的地址
printf("%d\n", sizeof(*arr));      //  1   第一个元素
printf("%d\n", sizeof(arr[1]));    //  1   第二个元素
printf("%d\n", sizeof(&arr));      //  4   整个数组的地址
printf("%d\n", sizeof(&arr+1));     // 4   下一个数组的地址
printf("%d\n", sizeof(&arr[0]+1));  // 4   第一个元素的地址

return 0;
}

分析:字符所占空间大小是1个字节,此数组中有6个字符,故整个数组所占空间大小为6个字节。

第三组:

int main()
{
char arr[] = {'a','b','c','d','e','f'};
printf("%d\n", strlen(arr));        // 随机值  遇到\0结束,
printf("%d\n", strlen(arr+0));      // 随机值  首元素地址
printf("%d\n", strlen(*arr));       // 错误    第一个元素
printf("%d\n", strlen(arr[1]));     // 错误    第二个元素
printf("%d\n", strlen(&arr));       // 随机值  整个数组的地址
printf("%d\n", strlen(&arr+1));     // 随机值  下一个数组的地址
printf("%d\n", strlen(&arr[0]+1));  // 随机值  第一个元素的地址

return 0;
}



 





  分析:strlen的功能是求得字符数组的大小,故此当遇到‘\0’停止计算,此字符数组中没有‘\0’标志,故整个数组的长度为一随机值。

第四组:

int main()
{
char *p = "abcdef";
printf("%d\n", sizeof(p));         // 4   指针变量的大小是4个字节
printf("%d\n", sizeof(p+1));       // 4   指针变量
printf("%d\n", sizeof(*p));        // 1   指针变量p指向第一个元素a
printf("%d\n", sizeof(p[0]));      // 1   第一个元素
printf("%d\n", sizeof(&p));        // 4   指针变量p的地址
printf("%d\n", sizeof(&p+1));      // 4   p后面空间的地址
printf("%d\n", sizeof(&p[0]+1));   // 4   b的地址

return 0;
}
 分析:这一组为一常量字符串,并有指针变量p指向字符串。需要注意的是&p+1这个所表示的意思,&p所表示的是指针变量p的地址,故&p+1表示p后面空间的地址,而不是字符串常量某一字符的地址。
   


第五组:
int main()
{
char *p = "abcdef";
printf("%d\n", strlen(p));        // 6
printf("%d\n", strlen(p+1));      // 5
printf("%d\n", strlen(*p));      //  错误
printf("%d\n", strlen(p[0]));    //  错误
printf("%d\n", strlen(&p));      //  随机值
printf("%d\n", strlen(&p+1));    //  随机值
printf("%d\n", strlen(&p[0]+1));  // 从b向后数
return 0;
return 0;
}


   分析:常量字符串后面有‘\0’这一标志,故此 strlen(p) 的结果为6,strlen(p+1) 这一计算的是从第一个元素开始计算字符串长度,和strlen(&p[0]+1) 是同一道理。



    8.二维数组的计算

int  main()
{
int a[3][4] = {0};
printf("%d\n",sizeof(a));                // 48   整个二维数组的大小
printf("%d\n",sizeof(a[0][0]));         //  4    第一行第一列的元素
printf("%d\n",sizeof(a[0]));           //   16   第一行的大小
printf("%d\n",sizeof(a[0]+1));        //    4    第一行第二个元素的地址
printf("%d\n",sizeof(a+1));          //     4    第二行地址
printf("%d\n",sizeof(&a[0]+1));     //      4    第二行的地址
printf("%d\n",sizeof(*a));         //      16    第一行的大小
printf("%d\n",sizeof(a[3]));      //       16    第三行的大小

return 0;
}


    分析:二维数组的首元素指第一行,故而 a[0]+1 指第一行第二个元素;sizeof(a[3]) 在这里是正确,sizeof操作符内部的表达式不参与运算,故而这里表示第三行的大小。

注:以上所有结果均在vs环境下测试
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: