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. 低级错误之Oracle客户端添加数据

    本来可以为空的外键,自己非要写一个无意义的值,导致数据保存失败.

  2. ECSHOP在线手册布局参考图--商品分类页 category.dwt

        A.购物车 1,设置方法 程序自动读取购物车的商品数量 2,代码相关 cart.lbi 中 {insert_scripts files='transport.js'} <div clas ...

  3. .NET加密配置文件connectionStrings节点

    具体的可以参考petshop源码程序. 加密前: <connectionStrings> <add name="SQLProfileConnString" con ...

  4. VMware 虚拟机安装 Mac OS X Mountain Lion 苹果系统

    国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...

  5. HDU 2013 蟠桃记

    蟠桃记 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submis ...

  6. 12.1 文档相关 Webbrowser 该文档已被修改,是否保存修改结果

       附件:http://files.cnblogs.com/xe2011/Webbrowser_Document_IsModified.rar   该文档已被修改,是否保存修改结果?是:保存修改结果 ...

  7. 为什么我刚发表的文章变成了“待审核”,csdn有没有官方解释啊

    为什么我刚发表的文章变成了"待审核",csdn有没有官方解释啊,什么样的文章才会变为待审核呢? 并且从草稿箱和回收站里也看不到我的文章了,希望我的文章没有删掉. 文章的字是一个个打 ...

  8. 学习笔记之APACHE ANT

    http://baike.baidu.com/link?url=KkOWkH_nMVJRbd4oj-aIHMVL4HR-s7fqm3i2brUcZzBinwUXjZgzPcYIWz5qFNNvjait ...

  9. 《Maven_孔浩》Maven命令

    maven命令: mvn compile:maven编译 mvn test:测试 mvn clean:删除编译生成的target文件 mvn package:运行编译.测试.package,把项目打包 ...

  10. Tomcat启动报错org.apache.coyote.AbstractProtocol.init Failed to initialize end point associated with ProtocolHandler ["http-apr-8080"]”

    1.使用netstat查看端口8080的使用情况: netstat -ano | findstr 8080 结果为: 最后一列表示使用8080端口的进程PID,如果返回结果为空则说明没有被使用. 2. ...