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

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(" ");
            }
        }
    }
}
*/

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

//通过指针引用字符串

/*//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!=''){
        *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!=''; p1++,p2++) {
        *p2=*p1;
    }
    printf("%s ",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!=''呢,因为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 ",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: ");
    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: ");
    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': ");
    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 ",x);
}
void min(int x,int y)
{
    if(x>y)
        x=y;
    printf("min is %d ",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: ");
    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: ");
    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;
}
*/

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

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

原文地址:https://www.cnblogs.com/wzy294250051/p/4787905.html