• 深入理解C语言


     

    1、关于scanf函数输入双精度实型数据时的问题

     1 //关于double类型的变量的一些小问题
     2 #include<stdio.h>
     3 int main(){
     4     double m,n;
     5     printf("enter m and n:");
     6     //用scanf函数输入双精度实型数据时,不能用"%f"格式声明,而应当用"%lf"格式声明
     7     scanf("%f%lf",&m,&n);
     8     //用printf函数输出双精度实型数据时,"%f"与"%lf"两种格式声明均可
     9     printf("m=%lf
    n=%lf
    ",m,n);
    10     printf("m=%f
    n=%f
    ",m,n);
    11     return 0;
    12 }

    代码运行结果

     

    2、因循环变量引起的运算结果错误,此错误特别隐蔽。

         当循环变量赋初值时,有多个变量设置初值时,最前面一个变量第一次定义时,后面的变量也默认定义为第一次定义,全部为局部变量。

     1 //用数组输入三个数,用函数来计算其中最大值,并输出这个数是第几个数
     2 #include<stdio.h>
     3 int main(){
     4     int max(int x,int y);
     5     int a[3],m,n;
     6     printf("enter 3 numbers:");
     7     for(i=0;i<3;i++){
     8         scanf("%d",&a[i]);
     9     }
    10 
    11     //在此处将循环变量定义为局部变量引起后面的m与n也变为局部变量,引起运算结果错误
    12     //在此处应特别注意,此错误特别隐蔽
    13   //如果在此处初始化变量,m与n也默认为新的局部变量,循环结束后的第20行打印语句中的m与n不是for循环中的数值
    14     for(int i=1,m=a[0],n=0;i<3;i++){
    15         if(max(m,a[i])>m){
    16             m=max(m,a[i]);
    17             n=i;
    18         }
    19     }
    20     printf("The largest numberr is %d
    it is the %dth number.
    ",m,n+1);
    21 }
    22 int max(int x,int y){
    23     return (x>y?x:y);
    24 }

    代码运行结果

     

    3、数组名作函数参数时,只需在实参位置写上数组名即可。

     1 //有一个一维数组score,内放10个学生成绩,求平均成绩
     2 #include<stdio.h>
     3 int main(){
     4     double average(double array[10],int n);
     5     double score[10],ave;
     6     printf("enter 10 student socre:");
     7     for(int i=0;i<10;i++){
     8         scanf("%lf",&score[i]);
     9     }
    10     //将数组名作为函数参数时,只需将数组名放在相对应的位置即可
    11     //若写成"score[10]",引用的将不是score数组,而是数组元素socore[10]
    12     ave=average(score[10],10);
    13     printf("10个学生的平均成绩是%f",ave);
    14 }
    15 double average(double array[10],int n){
    16     double ave,sum=0;
    17     for(int i=0;i<n;i++){
    18         sum+=array[i];
    19     }    
    20     ave=sum/n;
    21     return ave;
    22 }    

    代码运行结果

     

    4、多维数组作函数参数时,第1维的大小可以省略,第2维的大小不可以省略,并且实参与形参的维数要相同。

     1 //有一个3*4的矩阵,求所有元素中的最大值
     2 #include<stdio.h>
     3 int main(){
     4     //把二维数组名作函数参数时,第二维的大小不能省略,调用函数时不加函数的维数,只写函数名
     5     int max(int array[][4],int x,int y);
     6     int a[3][4]={{3,2,4,7},{12,8,9,20},{21,28,31,87}};
     7     printf("The max=%d",max(a,3,4));
     8 }
     9 int max(int array[][4],int x,int y){
    10     int i,j,max=array[0][0];
    11     for(i=0;i<x;i++)
    12         for(j=0;j<y;j++)
    13             max=array[i][j]>max?array[i][j]:max;
    14     return max;
    15                 
    16 }

     

     5、循环条件表达式用指针来进行判断,造成地址无限越界,无法跳出循环

     1 //用指针来实现选择排序
     2 #include<stdio.h>
     3 int main(){
     4     void sort(int *x,int n);
     5     int a[10]={2,4,9,5,8,1,0,3,7,6};
     6     int *pa=a;
     7     int n=10;
     8     sort(pa,n);
     9     //用指针输出数组时一定要先执行"pa=a",此程序中不执行此句也可以正确输出,在有的程序中执行到此句时指针pa已经指向了其他位置,需要对指针复位
    10     //此句中的循环条件表达式不能使用"pa<pa+10"来判断,这是因为步长表达式执行"pa++"操作,每一次执行完步长表达式之后再执行循环条件表达式时pa的值都会改变,"pa<pa+10"将一直满足条件,无法跳出循环,这一点一定要注意,千万要小心使用
    11     for(pa=a;pa<pa+n;pa++)
    12         printf("%d  ",*pa);    
    13 }
    14 void sort(int *x,int n){
    15     int temp;
    16     int *pi,*pj,*pn;
    17     pi=x;
    18     pn=x+n;
    19     for(pi;pi<pn-1;pi++){
    20         for(pj=pi+1;pj<pn;pj++){
    21             if(*pi>*pj){
    22                 temp=*pi;*pi=*pj;*pj=temp;
    23             }
    24         }
    25     }
    26 }

    代码运行结果

    说明:在gcc编辑器里会自动停止不再访问后续的地址,在VS里程序是无法自动停止的,在逻辑上程序是不会自动停止。

    6、用函数调用实现字符串的复制,误用指针来存放字符型数组

     1 //用函数调用实现字符串的复制,误用指针来存放字符型数组
     2 #include<stdio.h>
     3 int main(){
     4     void copy_string(char *from,char *to);
     5     //字符指针a、b分别指向两个字符串常量
     6     char *a="I am a teacher!";
     7     char *b="You are a student!";
     8     printf("%s
    %s
    ",a,b);//此句可以正常输出
     9     //在此处不可以这样使用函数copy_string将指针指向的内容复制到另一个指向字符串常量的字符指针
    10     //这是因为指针只是一个变量,其下一个指向的内容是不确定,不是"i+1".只有数组开辟了一段连续的内存空间,用指针才可以指向其下一个地址.
    11     //字符型指针只是一个单位的指针变量,所以就不能用来存放一个字符型数组的内容了.其实最根本的原因是因为字符型指针变量不能存放字符型的变量.
    12     copy_string(a,b);//在此处还有一个风险,因为下一个指针是随机的,如果函数中形参*from++若不是'',则无法结束for循环语句.
    13     printf("%s
    %s
    ",a,b);//此句不能正常输出.
    14 }
    15 //将两个数组名的地址(实参)传给指针指针(形参)
    16 void copy_string(char *from,char *to){
    17     for(;*to++=*from++;);
    18 }

     运行结果:

  • 相关阅读:
    初学C#和MVC的一些心得,弯路,总结,还有教训(3)--Dapper
    初学C#和MVC的一些心得,弯路,总结,还有教训(2)--关于Entity Framework
    windows下安装nodejs和express
    web前端自动化测试工具phantomjs的使用笔记
    jquery插件的模板
    jsonp跨域时如何解决xss漏洞
    js 判断web页面关闭、刷新、跳转
    各种排序算法的js实现
    zepto的getScript函数扩展
    js的面向对象和设计模式
  • 原文地址:https://www.cnblogs.com/zytomcat/p/9308952.html
Copyright © 2020-2023  润新知