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



Day 11:



因为指针部分比较的难,所以我们花费的时间也是最长的,希望大家耐的住性子,多多理解,多多打代码。好了,废话不多说,来看第11天的学习。



//编写一个求定积分的通用函数,分别求出x+1,2*x+3,x*x*x的定积分



/*program 11.1

#include <stdio.h>

int main()

{

    void djf(int x,int y,double (*p)(int,int));//大的函数也要有上下限做形参,因为我们调用的是大的函数,小函数是取大函数传入的值

    double h1(int x,int y);

    double h2(int x,int y);

    double h3(int x,int y);

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

    int q,a,b;

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

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

    scanf("%d",&q);

    if (q==1) {

        djf(a,b,h1);

    }

    else if (q==2){

        djf(a,b,h2);

    }

    else if(q==3)

    {

        djf(a,b,h3);

    }

    else{

        printf("error!!!");

    }

    return 0;

}

void djf(int x,int y,double (*p)(int,int))

{

    double result=(*p)(x,y);

    printf("%5.3lf",result);

}

double h1(int x,int y)

{

    double res=0.5*x*x+x-0.5*y*y-y;

    printf("x+1 在 %d~%d 间的定积分等于:\n",y,x);

    return res;

}

double h2(int x,int y)

{

    double res=x*x+3*x-y*y-3*y;

    printf("2*x+3 在 %d~%d 间的定积分等于:\n",y,x);

    return res;

}

double h3(int x,int y)

{

    double res=0.25*x*x*x*x-0.25*y*y*y*y;

    printf("x*x*x 在 %d~%d 间的定积分等于:\n",y,x);

    return res;

}

*/



一个小插曲,今天用Xcode写代码发现了一点需要注意的地方。(program 11.2)



//小数是不会有错的,分数就会出错(一般来说,用小数去写代码比较稳妥)



/*//program 11.2

#include <stdio.h>

int main()

{

    float x=1,y=2;

    float c=0.5*y*y+y-0.5*x*x-x;//c=2.50

    float d=1/2*y*y+y-1/2*x*x-x;//c=1.00

    printf("%-5.2f   %-5.2f",c,d);

    return 0;

}

*/



再来看这个程序,这



//有a个学生,每个学生有4门成绩,输入学生的学号,输出该学生的各科成绩(要建立一个返回指针值的函数,返回的指针值正好就是你要输出的那个学生的成绩的首地址,然后依次输出后面的3门成绩,这就是思路)



/*//program 11.3

#include "stdio.h"

int main()

{

    int a[][4]={{80,85,75,70},{65,70,75,80},{90,85,80,100},{50,66,12,67}};

    int *search(int (*p)[4],int n);//search是一个返回指针值的函数

    printf("please enter one number for a student:\n");

    int m;

    scanf("%d",&m);

    int *f;

    f=search(a,m);//返回的是地址,也就是要用指针变量去接收返回值

    for(int i=0;i<4;i++)

    {

        printf("%d  ",*(f+i));//依次输出地址中的值,这里得加上空格输出啊,不然一串数字,我还以为是一串地址呢!!没错的程序愣说成有错了

    }

    return 0;

}

int *search(int (*p)[4],int n)

{

    int *q=*(p+n-1);//将该行的首元素地址赋给指针变量q

    return q;//返回要输出的行的首地址

}

*/



//用返回指针值的函数search找出有不及格学科成绩的学生号码



/*//program 11.4

 #include <stdio.h>

 int main()

 {

 float score[3][4]={{56,66,69,68},{68,66,76,66},{55,77,77,60}};

 float *p;

 float *search(float (*p2)[4]);//这里的参数是一维数组的地址,所以必须把*p2用括号括起来

 for (int i=0; i<3; i++) {

 p=search(score+i);//因为定义的参数是一维数组的地址,所以说这个地方调用也应该调用一维数组的地址,用定义的指针变量p接收这个一维数组的地址,然后在函数中遍历这个一维数组。

 if(p==*(score+i))//score是二维数组的数组名,所以要取一维数组的地址,就要加*,但是我们不一定是取这个二维数组的第一行一维数组,所以后面跟上+i,表示到底是第几行

 {

 printf("No.%d is bad!\n",i+1);

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

 printf("%-3.2f ",*(p+j));//这里还是要括起来,因为p就是指的该行的首地址了,所以要在该行的基础上+j才是对列的变化,如果是*p+j,那么指针便会指到下一行。

 }

 printf("\n");

 }

 }

 //printf("%f\n",score[4]);

 //printf("%f",score[3]);

 return 0;

 }

 float *search(float (*p2)[4])

 {

 float *q;

 q=NULL;

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

 if (*(*p2+j)<60) {//这个地方*p2就是传进来的一维数组的首地址,这里就可以看作该一维数组的首元素的地址了,然后j是表示是该行的哪个元素(列)的地址,然后括起来再加*,就表示的该元素的值,而不是地址了。

 q=*p2;

 }

 }

 return q;

 }

 */





//定义一个指针数组name,然后将各字符串进行初始化,对他们进行排序(由小到大),然后输出。



/*//program 11.5

 #include "stdio.h"

 #include "string.h"

 int main()

 {

 char *name[]={"Follow me","BASIC","Great Wall","FORTRAN","Computer design"};//数组name中有五个元素,然后这个数组的初始值不是这五个元素,二十这五个元素的首地址,也就是这个数组存的是五个字符串的首地址。

 void sort(char *s[],int n);//字符串排序函数

 void point(char *s[],int n);//输出字符串函数

 sort(name,5);

 point(name,5);

 return 0;

 }

 void sort(char *s[],int n)

 {

 char *temp;

 int i,j,k;

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

 k=i;

 for (j=i+1; j<n; j++) {//找出从i+1个开始到最后一个里面最大的一个来

 if (strcmp(s[k],s[j])>0) {//这里不能改成if(*s[k]>*s[j]) k=j; 因为这样比较只能比较这两个地址所指向的字符串中的第一个字符,字符串的比较应该遵循strcmp函数(用strcmp函数的时候可以传入字符串的初始地址,也就是字符串中首字符的地址)

 k=j;//不断把当前一趟循环的较小值赋给k,因为这是由小到大排序的

 }

 }

 if(k!=i)

 {

 temp=s[k];//与s[k]交换其实就是和当前一趟最大的s[j]交换

 s[k]=s[i];//这里的s[k]和s[i]都是对地址的操作

 s[i]=temp;

 }

 }

 }

 void point(char *s[],int n)

 {

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

 {

 printf("%s\n",s[i]);

 }

 }

 */



指向指针数据的指针



/*//program 11.6

//指向指针数据的指针 char **p; (由于*是从右至左结合,所以相当于char *(*p); )

#include "stdio.h"

int main()

{

    char **p;

    char *s[]={"BASIC","Computer games","Wangzhongyao","MaXingze","Tianhao Yue"};

    p=s+2;

    printf("%d\n",*p);//以%d输出的是  3943

    printf("%s\n",*p);//以%s输出的是  Wangzhongyao

    //*p就是引用的字符指针变量的值(因为p指向的是一个字符指针变量),所以上面两次输出,输出的都是和这个 字符指针变量(s[2]) 有关,一次输出的是地址,第二次输出的是以s[2]为首地址的字符串

    return 0;

}

*/



动态数组与指针



/*//program 11.7

//建立动态数组,输入5个学生的成绩,另外用一个函数检查有没有不及格成绩,输出不及格成绩

#include "stdio.h"

#include "stdlib.h"//malloc函数存在于这个头文件中

int main()

{

    void check(int *);

    int *p1,i;

    p1=(int *)malloc(5*sizeof(int));//开辟动态内存区,然后将地址转换成 int * 型,存放在p1中。

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

        scanf("%d",p1+i);

    }

    check(p1);

    return 0;

}

void check(int *p)

{

    int j;

    for (j=0; j<5; j++) {

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

            printf("%d\n",*(p+j));//这里也可以将*(p+j)换成p[j]输出

        }

    }

}

*/



一个小整合。



//输入10个整数,将最小的数和第一个数对换,将最大的数和最后一个数对换。(写三个函数:①输入数据,②操作对换,③输出函数。用指针方法实现)

/*program 11.8

#include "stdio.h"

int main()

{

    int a[10];

    void scanf1(int *);//都是传进来地址参数,当然数组的首地址也能传进来咯

    void sort(int *);//声明时可以这样声明,但是在下面函数定义的时候必须在类型(int *)后面加上参数名。

    void print(int *);

    scanf1(a);

    sort(a);

    print(a);

    return 0;

}

void scanf1(int *b)

{

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

    for (int i=0; i<10; i++) {

        scanf("%d",&b[i]);

    }

}

void sort(int *b)

{

    

    int *p=b;

    int *max=b+9;

    int *min=b;

    int temp;

    int i=0;

    for (; p<b+9; p++) {

        if (*max<p[i]) {//因为b接收的是数组的受地址,而p又指向b,所以自然可以写成p[i]这种形式。(这里比较均是比较的地址中的 值。)

            max=&p[i];//max=p; 可否? 答案当然是肯定的。因为max接收的就是一个地址,这个地址是满足上面if语句条件的临时地址,满足即存入。(这里均是对地址进行操作)

        }

        if (*min>p[i]) {

            min=&p[i];

        }

    }

    if (max!=b+9)//上面的操作完毕后,将合适地址中的值在下面进行交换

    {

        temp=*max;

        *max=*(b+9);

        *(b+9)=temp;

    }

    if (min!=b) {

        temp=*min;

        *min=*b;

        *b=temp;

    }

}

void print(int *b)

{

    int *q=b;

    for (; q<b+10; q++) {

        printf("%d  ",*q);

    }

}

*/



第11天的学习结束了,大家还对指针这个东西迷惑么。我觉得头脑发热是肯定的,不过大家肯定也尝到的解决问题的快乐了吧!

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

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

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

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

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

    12天学好C语言--记录我的C语言学习之路 Day 10: 接着昨天的指针部分学习,有这么一个题目: //还是四个学生,四门成绩,只要有学生一门功课没及格就输出这个学生的所有成绩 /*//progra ...

  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. Extjs4---Cannot read property 'addCls' of null

    用MVC做后台管理系统时遇到的问题,关于tab关闭后再打开不显示,或者报错 我在新的tabpanel中加入了一个grid,当我关闭再次打开就会报错Cannot read property 'addCl ...

  2. 【Stage3D学习笔记续】真正的3D世界(五):粒子特效

    先看效果,按下空格键添加粒子特效: 一般而言粒子特效的实现都是比较复杂的,且不说实现粒子特效的编码和设计,光是编写一个粒子编辑器就不是简单的一件事,但是作者使用了很取巧的方式来完成,我们接下来深入代码 ...

  3. Winodws安装系统时,通过安装磁盘进行分区

    今天使用一个系统盘安装的时候,很奇怪,分区总是分出来一个系统磁盘,一个MBR,剩下的只能分主分区. 这样就导致我在进行windows激活时,激活工具都找不到启动磁盘的盘符(因为自动分出来的系统磁盘和M ...

  4. Android内存中的图片

    图片在内存中的大小 Android.graphics.Bitmap类里有一个内部类Bitmap.Config类,在Bitmap类里createBitmap(intwidth, int height, ...

  5. HDU 5071 Chat(2014鞍山B,模拟)

    http://acm.hdu.edu.cn/showproblem.php?pid=5071 Chat Time Limit: 2000/1000 MS (Java/Others)    Memory ...

  6. android自动化测试中hierarchyviewer和uiautomatorviewer获取控件信息的方式比对

    http://blog.csdn.net/itfootball/article/details/21777835 http://blog.csdn.net/chenbang110/article/de ...

  7. Ubuntu下配置 keepalived+nginx+tomcat 负载均衡

    本文力图阐述在 Ubuntu Server 环境下使用 Keepalived + Nginx + Tomcat 搭建高可用负载均衡环境的操作步骤和简约配置,这里不涉及性能调优.先说一下他们各自扮演的角 ...

  8. dialog统一标准调用方法(内部记录)

    更新base-config.js 对话框统一为三种形式(如后期需要再添加其他方式) //对话框--确定取消 //dialogOkFun:确定函数 dialogCancelFun:取消函数 functi ...

  9. 【转】 如何利用Cocos2d-x开发一个游戏

    原文:http://blog.csdn.net/honghaier/article/details/7888592 这个问题的结果应该是一个流程.我将从一些长期的PC端游戏开发经验结合Cocos2d- ...

  10. Android中Touch事件分析--解决HorizontalScrollView滑动和按钮事件触发问题

    之前写过关于HorizontalScrollView滑动和按钮事件触发问题,但是不能所有的情况,最近几天一直在想这个问题,今天有一个比较好的解决思路,最终应用在项目里面效果也很好,首先说明一下功能: ...