c语言操作一维数组-3

C语言选择题
#include
main()
{double a[15],k;
k=fun(a);
}

则以下选项中错误的fun函数首部是 ( D)
A.double fun(double a[15]) B.double fun(double *a)
C.double fun(double a[]) D.double fun(double a)
------------------------------------------------

http://blog.csdn.net/jin13277480598/article/details/51891816

a[n]时等价于*(a+n),即寻址到内存的a,然后移动n个单元,再取出数组。故p[0]等价于*(p+0),该值的类型为int型。

   num1=sizeof(p)/sizeof(p[0]) 等价于 num1=sizeof(p)/sizeof(int );

该语句在语法上面没有任何错误,但是在32机器和64位机器运行结果不同,在32机器出现正常结果,64位机器出现错误结果,原因见本文最后。

3、声明数组参量

前提:实际参数是一个数组名。C对于int a  [ ] 和 int * a作了同样解释,即a是指向int的指针。 
由于原型允许省略名称,因此下列4种原型都是等价的。
[cpp] view plain copy
 
  1. /**   函数原型声明4中等价形式  
  2. int sum (int *a , int n) 
  3. int sum (int * , int ) 
  4. int sum (int a[] , int n) 
  5. int sum (int [] , int )   //可能略微不熟悉的一种  
  6. */   
       定义函数时,名称是不可以省略的,以下两种形式是等价的。

[cpp] view plain copy
 
  1. /**   函数原型声明4中等价形式  
  2. int sum (int *a , int n) 
  3. {} 
  4. int sum (int a[] , int n) 
  5. {} 
  6. */   

4、a与&a的区别

[cpp] view plain copy
 
  1. int num =0 ;                       //在32机器中告诉C编译器分配4个字节的内存   
  2. int a [] = {1,3,5,12,6,7,54,32};   //告诉C编译器分配32个字节的内存   
  3.   
  4. printf("a:%d ,a+1:%d,&a:%d,&a+1:%d ",a,a+1,&a,&a+1) ;  
  5.   
  6. //a+1 和 &a+1 结果不一样    
  7. //虽然输出结果上面,a和&a一样 。 但是a 和 &a所代表的数据类型不一样  
  8.   
  9. /*重要*/   
  10. //a 代表的数据首元素的地址 (首元素),同时与整个数组地址重合,但其不能代表整个数组,只能代表起始个体的地址   
  11. //&a代表的是整个数组的地址   (特别特别的注意) 它的加1是以整块数组所占字节数总数为单位1  
输出结果:a:1638176 ,a+1:1638180,&a:1638176,&a+1:1638208

5、指针所占字节数

              指针所占用的字节数和操作系统和编译器有关。
[cpp] view plain copy
 
  1. /** 
  2. 2016-7-12 Jason Gel  
  3. **/  
  4. #include<stdio.h>  
  5. #include<stdlib.h>  
  6. #include<string.h>  
  7.   
  8. //void printArray(int * a ,int num ) 和  void printArray(int a[] ,int num )是等价的  
  9.   
  10. //函数定义时候,名称是不可以省略的。函数原型容许省略名称。  
  11. /**   函数原型声明4中等价形式  
  12. int sum (int *a , int n) 
  13. int sum (int * , int ) 
  14. int sum (int a[] , int n) 
  15. int sum (int [] , int )   //可能略微不熟悉的一种  
  16. */   
  17.    
  18. void printArray(int * a ,int num )  
  19. {  
  20.     int i ;  
  21.     for(i = 0; i< num; i++)  
  22.     {  
  23.         printf("%3d",a[i]);  
  24.     }  
  25.     printf(" ");  
  26. }  
  27. //这里用的是冒泡排序(起泡排序)   
  28. void sortArray(int *a ,int num )  
  29. {  
  30.     int i ,j ,temp;  
  31.     for(i =0 ;i <num;i++)              //外层:每次选定出需要排序的一个元素,依次向后  
  32.     {  
  33.         for( j=i+1; j<num; j++ )  //内层:外层选定的一个元素与其后所有元素依次比较,找出最小的元素  
  34.         {  
  35.             if(a[i]>a[j])     //交换类代码  
  36.             {  
  37.                 temp = a[i];  
  38.                 a[i]=a[j];  
  39.                 a[j]=temp;                
  40.             }  
  41.         }  
  42.     }  
  43.       
  44. }                           
  45.   
  46. int main ()  
  47. {  
  48.     int num =0 ;                       //在32机器中告诉C编译器分配4个字节的内存   
  49.     int a [] = {1,3,5,12,6,7,54,32};   //告诉C编译器分配32个字节的内存   
  50.       
  51.     int test =5;  
  52.     int *p = &test;  
  53.     int num1 = 0;  
  54.       
  55.     num1 = sizeof(p)/sizeof(p[0]);  
  56.       
  57.     printf("num1:%d, sizeof(p):%d,sizeof(p[0]):%d  ",num1,sizeof(p),sizeof(p[0]));  
  58.     sortArray(p,num1);   
  59.     printf("单一元素排序之后:");  
  60.     printArray(p,num1);  
  61.       
  62.     printf("a:%d ,a+1:%d,&a:%d,&a+1:%d ",a,a+1,&a,&a+1) ;  
  63.     printf("sizeof(num1):%d ",sizeof(num1));   
  64.     printf("sizeof(a):%d ",sizeof(a));   
  65.     printf("sizeof(int):%d sizeof(double):%d sizeof(char):%d  ",sizeof(int),sizeof(double),sizeof(char)) ;  
  66.       
  67.     printf("sizeof(int *):%d sizeof(double*):%d sizeof(char*):%d  ",sizeof(int *),sizeof(double*),sizeof(char*)) ;  
  68.       
  69.     //a+1 和 &a+1 结果不一样    
  70.     //虽然输出结果上面,a和&a一样 。 但是a 和 &a所代表的数据类型不一样  
  71.       
  72.     /*重要*/   
  73.     //a 代表的数据首元素的地址 (首元素),同时与整个数组地址重合,但其不能代表整个数组,只能代表起始个体的地址   
  74.     //&a代表的是整个数组的地址   (特别特别的注意) 它的加1是以整块数组所占字节数总数为单位1  
  75.       
  76.       
  77. //  num =sizeof(a);//这个是获取的整个数组的字节数,为32个字节  
  78.     printf("实参a的数据类型为整个数组,所占字节为:%d  ",sizeof(a)) ;  
  79. //    num = sizeof(a)/sizeof(int);    
  80.     num = sizeof(a)/sizeof(a[0]); //注意规范  
  81.     printf("排序之前:");  
  82.     printArray(a,num);  
  83.     sortArray(a,num);   
  84.     printf("排序之后:");  
  85.     printArray(a,num);  
  86.     return 0;  
  87. }  

VC 32位编译器 运行截图:

64位编译器运行截图:



核心:

可以看出在64位机器中,int*的指针为8个字节,在32位中int*为 4个字节,由于:

[cpp] view plain copy
 
  1. sizeof(p)/sizeof(p[0]) //等价于sizeof(int * ) /sizeof( int )  

所以在64位机器上面原本应该为1的现在变成了2,导致程序出现错误。

      从程序输出结果我们可以看出:实参a的数据类型为整个数组,所占字节为32。虽然实参a表示的是数组名,但是它实际的数据类型不是int *,而是表示的整个数组所占字节数。这里不要与前文的a与&a表示地址时候弄混淆。

-----------------------------------------------

 1 #include <stdio.h>
 2 void printArray(double *p,int n);
 3 void printArray2(double a[], int n);
 4 void printArray3(double (*p)[5], int n);
 5 int main(int argc, char *argv[])
 6 {
 7     double a[] = { 1.0, 2.0, 3.0, 5.0, 6.0 };
 8     double b[][3] = { { 1, 2, 3 }, { 4, 5, 6 }, {7,8,9} };
 9     printArray(a, sizeof(a) / sizeof(double));//a 传递的是a数组首元素的首地址
10     printArray2(a, sizeof(a) / sizeof(double));
11     printArray3(&a, sizeof(a) / sizeof(double));//&a 传递的是整个数组的首地址
12     //虽然传递a和&a时传过去的值是相同的,但是意义不同,接受他的形参也要不同,
13     //数组名a传过去的就是首元素首地址,可以用一个double类型指针接受
14     printf("a的地址:%d", a);//正确
15     printf("&a的地址:%d", &a);//正确
16 
17         /*char s1[] = "hello rupeng.com";
18         char *p = s1;
19         p = p + 2;//char是一个字节,向后移动2*1 个字节
20         printf("%s
", s1);
21         printf("%s
", p);
22 
23         char *p2 = s1;
24         p2 += 5;
25         int i = p2 - p;
26         printf("%d
", i);
27 
28         int nums[] = { 11, 22, 33, 44, 55 };
29         int *iP1 = nums;
30         int *iP2 = nums;
31         iP2 = iP2 + 3;
32         printf("%d
", *iP2);
33         printf("%d
", iP2 - iP1);
34         //同类型指针相减,得出的是相距的数据类型的长度
35 
36         //int aaa = iP2-p2;
37         */
38         getchar();
39     return 0;
40 }
41 void printArray(double *p, int n)//一维数组首元素首地址传过来后指针p和数组名可以同样使用
42 {
43     printf("printArray_a:
");//正确
44     for (int i = 0; i < n; i++)
45     {
46         printf("%lf ", *(p + i));
47     }
48     printf("
");
49     printf("printArray_b:
");//正确
50     for (int i = 0; i < n; i++)
51     {
52         printf("%lf ", p[i]);
53     }
54     printf("
");
55 }
56 
57 void printArray2(double a[], int n)
58 {
59     printf("printArray2_a:
");//正确
60     for (int i = 0; i < n; i++)
61     {
62         printf("%lf ", a[i]);
63     }
64     printf("
");
65     printf("printArray2_b:
");
66     for (int i = 0; i < n; i++)
67     {
68         printf("%lf ", *(a+i));// a+i不正确
69     }
70     printf("
");
71 }
72 
73 void printArray3(double(*p)[5], int n)//传过来整个数组的首地址&a,接受指针为(*p)[5],*p相当于数组名
74 {
75 
76     printf("printArray3_a:
");//正确
77     printf("(*p)[5]的地址:%d
", (*p)[5]);//
78     printf("(*p)的地址:%d
", (*p));
79     for (int i = 0; i < n; i++)
80     {
81         printf("%lf ", (*p)[i]);
82     }
83     printf("
");
84     printf("printArray3_b:
");//错误
85     for (int i = 0; i < n; i++)
86     {
87         printf("%lf ", (*p)+i);//(*p)[5]、*p[i]、*(p+i)、(*p)+i不正确
88     }
89     printf("
");
90 }
91 //给一维数组传指针时通常使用a而不是&a,接受的指针可以为同类型的指针*p,p和a的使用方法相同,可以p[i]和*(p + i)
原文地址:https://www.cnblogs.com/zhubinglong/p/5984209.html