[解题报告]【第16题】给定 n,打印一个直角边为 n 的等边直角三角形

目录

零、写在前面

一、主要知识点

        1.打印指定的形状的边界判定

        2.信号量

二、课后习题 

1115. 交替打印FooBar

写在最后


零、写在前面

        这个系列不经常更新,今天这个题目因为英雄哥玩超纲课后题0.0,我们一起看一看,主要知识点在

【第16题】给定 n,打印一个直角边为 n 的等边直角三角形https://blog.csdn.net/WhereIsHeroFrom/article/details/118272189icon-default.png?t=LA92https://blog.csdn.net/WhereIsHeroFrom/article/details/118272189


一、主要知识点

        1.打印指定的形状的边界判定

#include<stdio.h>
int main() {
    int n, i, j;
    while(scanf("%d", &n) != EOF) {
        for(i = 1; i <= n; ++i) {       // 打印指定行数
            for(j = 1; j <= i; ++j)     // 打印数量与行数相同
                printf("*");            // 打印字符
            printf("\n");               // 换行
        }
    }
    return 0;
}

        2.信号量

首先我们了解下进程互斥需要遵循的四个原则。

1.空闲让进 2.忙则等待 3.有限等待 4.让权等待

其中空闲让进、忙则等待保证了进程的互斥访问。有限等待保证了程序的可执行性质。

让权等待指的是在等待的时候主动休眠放弃cpu的使用权力。

而最常用保证上面的这些的一个机制就是信号量,c语言里面有几个常用的函数帮助我们来实现这些操作。

    sem_t bar;//创建信号量变量
    sem_init(&(obj->foo),0,1);//初始化 其中第一个参数为信号量地址 第二个是共享范围 0表示在所有进程共享 第三个是初始值 一开始拥有的个数
    sem_wait(&(obj->foo)); //申请信号量 如果能申请到 就减小信号量的个数 往下执行 否则主动睡眠
    sem_post(&(obj->bar)); //释放信号量,给相应的信号量+1,并唤醒相应的进程

二、课后习题 

1115. 交替打印FooBar

1115. 交替打印FooBarhttps://leetcode-cn.com/problems/print-foobar-alternately/

题目描述

两个不同的线程将会共用一个 FooBar 实例。其中一个线程将会调用 foo() 方法,另一个线程将会调用 bar() 方法。

请设计修改程序,以确保 "foobar" 被输出 n 次。

思路

明显的进程同步问题,也就是foo执行一次 far执行一次。一开始就写了一个不遵循让权等待的简单同步模型,你们应该可以看懂-.-

typedef struct {
    int n;
    int x;    //同步用变量
} FooBar;

FooBar* fooBarCreate(int n) {
    FooBar* obj = (FooBar*) malloc(sizeof(FooBar));
    obj->n = n;
    obj->x = 0;//初始化
    return obj;
}

void foo(FooBar* obj) {
  
    for (int i = 0; i < obj->n; i++) {
        while(obj->x);        //等待x为0
        // printFoo() outputs "foo". Do not change or remove this line.
        printFoo();
        obj->x=1;        /将x设置为1
    }
}

void bar(FooBar* obj) {
    
    for (int i = 0; i < obj->n; i++) {
        while(!obj->x);    //等待x为1
        // printBar() outputs "bar". Do not change or remove this line.
        printBar();
        obj->x=0;           //将x设置为0
    }
}

void fooBarFree(FooBar* obj) {
    free(obj);
}

结果

超时!没错 肯定超时 毕竟一直卡在while里

思路2

利用上面说到的给的信号量。

typedef struct {
    int n;
    sem_t foo;//两个信号量
    sem_t bar;
} FooBar;

FooBar* fooBarCreate(int n) {
    FooBar* obj = (FooBar*) malloc(sizeof(FooBar));
    obj->n = n;
    sem_init(&(obj->foo),0,1);//foo先执行所以给1
    sem_init(&(obj->bar),0,0);
    return obj;
}

void foo(FooBar* obj) {
  
    for (int i = 0; i < obj->n; i++) {
        sem_wait(&(obj->foo));//请求foo
        // printFoo() outputs "foo". Do not change or remove this line.
        printFoo();
        sem_post(&(obj->bar));//释放bar
    }
}

void bar(FooBar* obj) {
    
    for (int i = 0; i < obj->n; i++) {
        sem_wait(&(obj->bar));//请求bar
        // printBar() outputs "bar". Do not change or remove this line.
        printBar();
        sem_post(&(obj->foo));//释放foo
    }
}

void fooBarFree(FooBar* obj) {
    sem_destroy(&(obj->bar));    
    sem_destroy(&(obj->foo));
    free(obj);
}

写在最后

我还能肝,肝死。。。。大家要加油,无论你们希望成为什么样的人,都需要不焦虑的一步一步靠近它!

猜你喜欢

转载自blog.csdn.net/qq_17593855/article/details/121375538