12天学好C语言——记录我的C语言学习之路



Day 10:



接着昨天的指针部分学习,有这么一个题目:



//还是四个学生,四门成绩,只要有学生一门功课没及格就输出这个学生的所有成绩



/*//program 10.1

#include "stdio.h"

int main()

{

    void search(float (*p)[4],int n);

    float a[4][4]={{80,70,60,59},{90,75,85,55},{70,90,80,75},{65,95,75,80}};

    search(a,4);

    return 0;

}



void search(float (*p)[4],int n)//这个地方需要注意的是一定要在*p的两边加小括号

{

    int i,j;

    for (i=0; i<n; i++)

    {

        for (j=0; j<4; j++)

        {

            if(*(*(p+i)+j)<60)

            {

                for (j=0; j<4; j++)//这个地方直接用j代表列标进行输出,这个程序也是正确的。可是现在我们或许会发现两个问题:①如果在一行中(指在这同一个同学的成绩里),出现了两次不及格的情况,那么我们不加break跳出循环是不是就要输出两遍结果呢?②输出的时候直接用j,那么跳出for循环的时候j的值发生了改变,会不会影响上层循环呢?    上面这两个问题很有价值,但是关键点在于我们要把两个问题结合起来看。没错,j在输出结束后的值是会发生改变,而且一定影响了上层for循环(也就是影响了第二层j的循环),但是恰恰是每次输出结束,j的值都变成了4,超出了最大值的范围,这样直接就跳出了上层的for循环,一举两得。可谓这个程序的精妙之处。

                {

                    printf("%-6.1f",*(*(p+i)+j));

                }

                printf("\n");

            }

        }

    }

}

*/



接下来,我们要将指针与字符串结合起来看。



//通过指针引用字符串



/*//program 10.2

#include <stdio.h>

int main()

{

    //char *p="I am SB"; 这一行可以用下面两行取代

    char *a;//定义一个指针变量

    a="I am SB";//a接收的是这个字符串的首地址也就是'I'的地址

    printf("%s",a);

    return 0;

}

*/



//将字符串a复制到字符串b,然后输出字符串b。



/*//program 10.3

#include "stdio.h"

int main()

{

    char a[]="i am sb!";

    char b[30];

    char *p1=a,*p2=b;

    while(*p1!='\0'){

        *p2=*p1;

        p1++;

        p2++;

    }

    printf("%s",b);

    return 0;

}

*/



//将字符串a复制到字符串b,然后逆序输出b



/*//program 10.4

#include "stdio.h"

int main()

{

    char a[]="i am a sb!";

    char b[30];

    char *p1=a;

    char *p2=b;

    for (; *p1!='\0'; p1++,p2++) {

        *p2=*p1;

    }

    printf("%s\n",b);

    for (p2=b+strlen(b)-1; p2>=b+0; p2--) {

        printf("%c",*p2);

    }

    

    return 0;

}

*/



//将字符串逆序输出(关键就是将指针变量先指到字符串的最后一个地址,然后从最后一个地址开始,依次往前输出指针变量指向地址的值)



/*//program 10.5

#include "stdio.h"

int main()

{

    char a[]="I love xing'ge!!!";

    char *p1=a+strlen(a)-1;

    for (; p1>=a+0; p1--) {//这个地方表达式2为什么不能写成p1!='\0'呢,因为p1是地址,而不是元素,所以不能用它不为空作为结束标志,应该用地址a+0作为结束标志

        printf("%c",*p1);

    }

    return 0;

}

*/



/*//program 10.6

#include "stdio.h"

int main()

{

    char a[]="as12r5";

    char *p=a;//用指针变量指向一维字符数组的首元素后,下面的两个输出结果是一样的,p就是a,a也就是p,可以就认为p也是数组名。因为他们均表示一维字符数组的首地址

    printf("%s\n",p);

    printf("%s",a);

    return 0;

}

*/



//改变指针变量的地址

/*//program 10.7

#include "stdio.h"

int main()

{

    char a[]="abcdefghijk";

    char *p=a;

    p+=7;//地址向由走,指向p+7这个地址

    printf("%s",p);//所以输出字符串也是从改变地址之后的地方开始输出

    return 0;

}

*/



还记得我们之前做过一个报数的题目吗,今天我们用指针实现一下,不过这里实现其实和之前差不多,读者自行考虑还有没有简单的方法。



//用指针做n个人围成一圈报数123,报到3的出列,问最后剩下几号?



/*//program 10.8

#include <stdio.h>

int main()

{

    int n,num=0,out=0,i;

    printf("please enter n:\n");

    scanf("%d",&n);

    int a[n];

    int *p=a;

    for (i=0; i<n; i++) {

        *(p+i)=i+1;//正好让元素里面的值被赋上元素的编号(1~n),这样输出指针变量指向地址中的值就是其编号了,很好!

    }

    i=0;

    while (out!=n-1) {

        if (*(p+i)!=0) {

            num++;

        }

        if (num==3) {

            *(p+i)=0;

            out++;

            num=0;

        }

        i++;

        if (i==n) {

            i=0;

        }

    }

    i=0;

    while (*(p+i)==0) {//这里用while语句的话,必须是把元素等于0作为判定是否循环的条件。这样跳出循环时的i值就是我们需要输出的元素的下标。  如果用元素不等于0作为判定标准的话,第一个元素就可能等于零,那么直接就不执行while循环了,那么谈何输出不等于0的值。

        i++;

    }

    printf("No.%d is no out!",*(p+i));

    return 0;

}

*/



//指针变量指向max函数



/*//program 10.9

#include "stdio.h"

int main()

{

    int a=5,b=6,c;

    void max(int x,int y);

    int (*p)(int,int);

    p=max;   //将max的地址 赋给指针变量p

    c=(*p)(a,b);   //可以把max函数作为一个元素来看待,指针变量p指向元素 max函数 的首地址,*p就是调用了该“元素”,也就是调用了max函数

    return 0;

}

void max(int x,int y)

{

    if (x<y) {

        x=y;

    }

    printf("max is %d",x);

}

*/



//指针变量指向max函数

/*//program 10.10

#include "stdio.h"

int main()

{

    int a=51,b=10;

    void max(int a,int b);

    void (*p)(int,int);//这个指针变量既然指向max函数,那么格式记住一定要和max函数一致,包括后面的形参,以及形参的类型(int)和函数的类型(void)

    p=max;   //如果要用指针调用该函数,就一定要将 函数入口地址 赋给指针变量(也就是函数名)

    (*p)(a,b);

    return 0;

}

void max(int a,int b)

{

    if (a<b) {

        a=b;

    }

    printf("max is %d",a);

}

*/



//将一个指针变量指向函数,但是区别的是如果输入1,指向max函数,输入2就指向min函数,并输出相应结果。



/*//program 10.11

#include <stdio.h>

int main()

{

    int n,a,b;

    printf("please enter a and b:\n");

    scanf("%d%d",&a,&b);

    void max(int x,int y);

    void min(int x,int y);

    void (*p)(int,int);//这个指向函数类型的指针变量可以指向多个满足这个指针变量格式的函数,调用之前只需将函数的入口地址赋给该指针变量即可~

    printf("please choose '1' or '2':\n");

    scanf("%d",&n);

    if (n==1) {

        p=max;//千万不要忘记调用前把函数入口地址赋给指针变量

        (*p)(a,b);

    }

    else if(n==2)

    {

        p=min;

        (*p)(a,b);

    }

    return 0;

}

void max(int x,int y)

{

    if(x<y)

        x=y;

    printf("max is %d\n",x);

}

void min(int x,int y)

{

    if(x>y)

        x=y;

    printf("min is %d\n",x);

}

*/



//有两个整数a、b,如果输入1,就求max,如果输入2,就求min,如果输出3,就求sum



/*//program 10.12

#include <stdio.h>

int main(){

    int a,b;

    printf("please enter two numbers:\n");

    scanf("%d%d",&a,&b);

    void mms(int x,int y,int (*p)(int,int));//指向函数的指针变量做为参数,相当于大函数套小函数,小函数用指针变量指向表示

    int max(int x,int y);//定义三个小函数

    int min(int x,int y);

    int sum(int x,int y);

    int n;

    printf("please choose 1/2/3:\n");

    scanf("%d",&n);

    if (n==1)

    {

        mms(a,b,max);//调用大函数,然后根据n的值调用相应的小函数。这里不能用(*p)(a,b)替换max,是因为指针变量是在上面函数中声明的,不是全局变量。这里除了将a、b赋给x、y,同时也将max的入口地址赋给了指向函数的指针变量p,下面同理

    }

    else if(n==2)

    {

        mms(a,b,min);

    }

    else

    {

        mms(a,b,sum);

    }

    return 0;

}

void mms(int x,int y,int((*p)(int,int)))//一定不要忘记定义mms函数(大函数),因为我们调用的时候是直接调用mms函数,而间接调用下面三个小函数

{

    int result=(*p)(x,y);//将三个小函数的返回值传给一个新定义的变量

    printf("%d",result);//输出返回值

}

int max(int x,int y)

{

    if(x<y)

        x=y;

    printf("max is ");//小函数得出结果之后,返回结果,然后输出语句是分了两部分,一部分文字是在小函数中输出的,结果是返回给大函数然后在大函数中输出的。所以说输出语句分割成了两部分,这一点可以学习!

    return x;

}

int min(int x,int y)

{

    if(x>y)

       x=y;

    printf("min is ");

    return x;

}

int sum(int x,int y)

{

    printf("sum is ");

    return x+y;

}

*/



今天又深入的学习了指针,都是一些基础的程序,带大家认识指针各种各样的用法,今天掌握这些就够了,还是那句话,多写代码,就能理解的快。

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

12天学好C语言——记录我的C语言学习之路(Day 10)的更多相关文章

  1. 12天学好C语言——记录我的C语言学习之路(Day 12)

    12天学好C语言--记录我的C语言学习之路 Day 12: 进入最后一天的学习,用这样一个程序来综合考量指针和字符串的关系,写完这个程序,你对字符串和指针的理解应该就不错了. //输入一个字符串,内有 ...

  2. 12天学好C语言——记录我的C语言学习之路(Day 11)

    12天学好C语言--记录我的C语言学习之路 Day 11: 因为指针部分比较的难,所以我们花费的时间也是最长的,希望大家耐的住性子,多多理解,多多打代码.好了,废话不多说,来看第11天的学习. //编 ...

  3. 12天学好C语言——记录我的C语言学习之路(Day 9)

    12天学好C语言--记录我的C语言学习之路 Day 9: 函数部分告一段落,但是我们并不是把函数完全放下,因为函数无处不在,我们今后的程序仍然会大量运用到函数 //转入指针部分的学习,了解指针是什么 ...

  4. 12天学好C语言——记录我的C语言学习之路(Day 8)

    12天学好C语言--记录我的C语言学习之路 Day 8: 从今天开始,我们获得了C语言中很有力的一个工具,那就是函数.函数的魅力不仅于此,一个程序到最后都是由众多函数组成的,我们一定要用好函数,用熟练 ...

  5. 12天学好C语言——记录我的C语言学习之路(Day 7)

    12天学好C语言--记录我的C语言学习之路 Day 7: 昨天进行了一天的数组学习,今天大家可以先写几个昨天的程序热热身,回顾回顾,然后今天第一个新程序也是关于数组的,比较难,准备好就开始啦! //输 ...

  6. 12天学好C语言——记录我的C语言学习之路(Day 6)

    12天学好C语言--记录我的C语言学习之路 Day 6: 今天,我们要开始学习数组了. //①数组部分,数组的大小不能够动态定义.如下: //int n;   scanf("%d,& ...

  7. 12天学好C语言——记录我的C语言学习之路(Day 5)

    12天学好C语言--记录我的C语言学习之路 Day 5: 第五天的学习开始了,今天我们主要对几个程序进行编写,让自己充分的熟练编程语言,大量的题目会让自己变的精炼.以一个程序(program 5.1) ...

  8. 12天学好C语言——记录我的C语言学习之路(Day 4)

    12天学好C语言--记录我的C语言学习之路 Day 4: 首先来看一段程序: //输出下面4*5的矩阵 /* 1  2  3   4   5 2  4  6   8   10 3  6  9   12 ...

  9. 12天学好C语言——记录我的C语言学习之路(Day 3)

    12天学好C语言--记录我的C语言学习之路 Day 3: 不知不觉到了第三天的学习,我们前两天学习的东西很杂乱,各个方面都有学习.我觉得这不是不系统,也不是学的不扎实,这种学习对于初学者而言我认为是很 ...

随机推荐

  1. [iOS基础控件 - 2] 按钮的基本使用

    UIButton A.素材准备 1.图片素材放置到Images.xcassets中     B.按钮状态 1.normal:默认状态 Default 对应的枚举常量:UIControlStateNor ...

  2. 笔记- iphone手机音频AAC视频H264推流(一) iphone手机推流最佳方案

    这几个月一直在做iphone手机音视频的东西,由于个人比较懒,所以一直没整理,现在闲的蛋疼,并且以后项目要搁置了,在这里记录一下我做的iphone手机推流的东西. 项目都是个人的调研与实验,可能很多不 ...

  3. DS18B20 for STM32 源代码 【worldsing笔记】

    DS18B20是DALLAS公司生产的一线式数字温度传感器,具有3引脚TO-92小体积封装形式:温度测量范围为-55℃-+125℃,可编程为9位-12位A/D转换精度,测温分辨率可达0.0625℃.主 ...

  4. 文件上传(FileUpload控件)

    asp.net 文件上传,大文件上传.   新建一个asp.net页面,在工具栏里拖入 FileUpload 上传控件.一个按钮 Button  !    !     ! 进入Button事件 //- ...

  5. Idea的Git使用

    在使用Git来pull和push代码的时候会发生冲突的情况,如果处理不当则会出现无法pull和push代码的情况.所以这个是十分有必要注意的. 那么我来说几句自己的总结吧: 1.先看下idea的Git ...

  6. 剑指OFFER之复杂链表的复制(九度OJ1524)

    题目描述: 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点). 输入: 输入可能包含多个测试样例,输入以EOF结束.对于每个测试案例,输入的第一 ...

  7. 从经典问题来看 Copy 方法(转)

    来自:Gua | 瓜地 链接:https://desgard.com/copy/  在初学 iOS 的时候,可能会被灌输这么一个常识,切记 NSString 的 property 的修饰变量要写作 c ...

  8. 用intent打开各种类型文件

    public class MyIntent { //android获取一个用于打开HTML文件的intent public static Intent getHtmlFileIntent( Strin ...

  9. Linux系统常用命令 __转载的

    1.登录linux系统命令:login 用户名   密码: 2.注销linux系统命令:logout ; 3.在linux系统中进入windows系统(图形界面)命令:Start x; 4.关闭lin ...

  10. 项目源码--Android高质量图片浏览器源码

      下载源码   技术要点: 1. 浏览所有格式的图片 2. 图片缓存到数据库 3. Sqlite数据库的高级应用 4. 文件夹缩图显示 5. 多点触控技术 6. 动画技术 7. 支持超高清图片 8. ...