Jack's Blog

流淌的心,怎能阻拦,吹来的风,又怎能阻挡。

       说起来倒是奇怪,倒是非常奇怪,现在竟然自己开始写起感言了。或许是希望时光不要过得太快吧,记录下这琐碎的心思。更重要的是希望自己能变得更好,不给只剩不到两年的大学生活留下遗憾。

       之前一直都很反感以成绩作为考核方式的单一评价体系,不知不觉自己也成了其中为成绩努力奋斗的一个。不过,暂时作为学生,还是努力地提高自己的成绩吧,毕竟作为弱势群体,只能去适应这个社会。或许这就是大人口中的成长吧?等长大后再来看这篇文章,或许会有其他看法吧。

       有时候离Excellence真的只差一点点的努力。其实每次考1、2名的同学,他们的确很厉害,差距是肯定要承认的。但是,也一定要有我能成为第一的决心。

       要成为第一二名:“战略上藐视敌人,战术上重视敌人。”我个人认为这句话真的说得太好了,其中有两个内涵,第一个是首先做到有信心,不卑不亢,相信自己的努力与付出是有结果的。另外一个是面对学习这个“敌人”看,要注意方法,不能轻视它。否则,是会经历惨痛教训的。

       在做到以上的要求之后,我们就应该已经达到了中上水平,这时候就可能进入了一个瓶颈期。在这个时候,最重要的是我们的心态。比如说对于我,就会忽然放松自己,学不进去了,但是就差这一点点的努力,离最高分就差不了多远了。再重复一遍,心态,心态,心态!!!这时候也是比毅力的时候,更是拼方法的时候。

       期中没做到上面的要求,希望自己期末做到吧。并且,平时一定要跟上节奏,千万不能落下。

Before we go

16年安装了fedora 25,然而由于学校的各种事情,用windows还是比较方便。感到遗憾的是一直没有很好的利用这么好的资源,包括各种开源的软件和强大的环境友好性。

现在我想将自己的工作平台全部转移到Fedora 25上,有几大配置非常有用,我将把他们分享给大家


1.Pycharm edu

自行搜索其官网下载最新版的 pycharm edu 最新版

  1. Unpack the PyCharm Edu distribution archive that you downloaded to
     where you wish to install the program. We will refer to this destination
     location as your {installation home} below.

  2. Open a console and cd into "{installation home}/bin" and type:

       ./pycharm.sh

     to start the application. As a side effect, this will initialize various
     configuration files in the ~/.PyCharmEdu3.5 directory.

  3. [OPTIONAL] Add "{installation home}/bin" to your PATH environment
     variable so that you may start PyCharm Edu from any directory.

  4. [OPTIONAL] To adjust the value of the JVM heap size, create
      ~/.PyCharmEdu3.5/pycharm.vmoptions (or pycharm64.vmoptions
      if using a 64-bit JDK), and set the -Xms and -Xmx parameters. To see how
      to do this, you can reference the vmoptions file under
      "{installation home}/bin" as a model.

  [OPTIONAL] Changing the location of "config" and "system" directories

2.python 3

下载地址:https://www.python.org/downloads/release/python-361/

安装代码:

On Unix, Linux, BSD, macOS, and Cygwin::

    ./configure
    make
    make test
    sudo make install

3.搜狗输入法

安装fedora 中文软件源

$ sudo dnf config-manager --add-repo=http://repo.fdzh.org/FZUG/FZUG.repo 
$ sudo dnf install fzug-release -y
$ sudo dnf install sogoupinyin sogoupinyin-selinux -ysudo dnf install sogoupinyin sogoupinyin-selinux -y
$ reboot

该包已添加 fcitx-gtk2, fcitx-gtk3, fcitx-qt4 和 fcitx-qt5 模块依赖。
注意:由 iBus 切换至 Fcitx 需要 重启/注销 系统,以便 imsettings 启动相应输入法。

FAQ

使用 Sogou Pinyin

如果您使用 XDG 兼容的桌面环境,比如 KDE, GNOME, XFCE, LXDE, Cinnamon。那么当您安装好 Sogou 并重新登录后,Fcitx 和 Sogou 应该会自动启动。使用 Ctrl+Space 激活 Fcitx 便可以输入了,Shift 临时切换中英文。

1). sogou-qimpanel 未自动启动

如果 Fcitx 没有随桌面环境自动启动,请检查 imsettings 设置,正常的配置如下所示:

$ imsettings-info 
Xinput file: /etc/X11/xinit/xinput.d/fcitx.conf
GTK+ immodule: fcitx
Qt immodule: fcitx
XMODIFIERS: @im=fcitx
XIM server: /usr/bin/fcitx -D
Preferences: /usr/bin/fcitx-configtool
Auxiliary:
Short Description: FCITX
Long Description:
Icon file: /usr/share/pixmaps/fcitx.png
Is system default: TRUE
Is user default: TRUE
Is XIM server: FALSE
$ imsettings-switch fcitx  # 切换至 fcitx

如果您的桌面环境不兼容 XDG,则 sogou-qimpanel 不会自动启动。请使用桌面环境自带的自动启动工具,添加 sogou-qimpanel 启动项。

如果您的桌面环境不包含自启动工具,或您使用 startx 脚本启动图形界面,则在 ~/.profile 中添加以下命令。

$ vim ~/.profile
source /etc/sysconfig/sogoupinyin

该脚本在启动 X 时被 /etc/X11/xinit/xinitrc-common 调用,用于设置 Fcitx 环境变量,并启动 sogou-qimpanel

2). 如何安装皮肤

查看帮助信息:

$ rpm -qi sogoupinyin
皮肤保存在~/.config/sogou-qimpanel/skin/, 按以下方式安装:
  $ sudo setsebool sogou_enable_homedirs=1
  $ sogou-qimpanel Skin.ssf

3). 如何安装词库

查看帮助信息:

$ rpm -qi sogoupinyin
词库保存在~/.config/SogouPY/scd/, 按以下方式安装:
  $ sudo setsebool sogou_enable_homedirs=1
  $ sogou-qimpanel Cell.scel

4). 禁止 Sogou 访问网络

查看帮助信息:

$ rpm -qi sogoupinyin
禁止 sogou 访问网络:
  $ sudo setsebool -P sogou_access_network=0 # 默认: true

5). 小黑框问题

Xfce 桌面环境,如遇到小黑框,需开启 Compositor 功能:

Settings -> Windows Manger Tweaks -> Compositor
设置 -> 窗口管理器微调 -> 合成器

Mate 桌面环境,如遇到小黑框,需开启 Compositor 功能:

System -> Control Center -> Windows -> Enable software composit..

LXDE 桌面环境,如遇到小黑框,需要修改窗口管理器。

$ yum install compiz-lxde ccsm
$ vim ~/.config/lxsession/LXDE/desktop.conf
 window_manager=openbox  # 原参数
 window_manager=compiz-lxde-emerald  # 修改为

6). GTK/Qt 程序无法切换输入法

如果遇到无法切换输入法,则检查 Fcitx 环境变量 是否已正确设置。

$ env | grep fcitx
GTK_IM_MODULE=fcitx
QT4_IM_MODULE=fcitx
QT_IM_MODULE=fcitx
XMODIFIERS=@im=fcitx

对于兼容 XDG 的桌面环境,Fcitx 环境变量应由 imsettings 通过 /etc/X11/xinit/xinputrc 配置。

$ ll /etc/X11/xinit/xinputrc
/etc/X11/xinit/xinputrc -> /etc/alternatives/xinputrc

7). 选词框乱码

如果您碰到了 #79 的问题。可能是您启用了 "轻量界面 (fcitx-ui-light)" ,它会导致 sogou-qimpanel 不能正常显示。在 "输入法配置" -> "附加组件" 中,禁用 "轻量界面" 即可。

PS: 源里的 fcitx-cloudpinyin 可以正常使用 Google 云拼音,有了云拼音 libpinyin 之类的输入法也挺好,内存占用低。

故障排除

  • imsettings:根据 ~/.cache/imsettings/log 日志排查错误
  • Fcitx:运行 fcitx-diagnose 排查 Fcitx 错误
  • Sogou:运行 sogou-diag 收集诊断信息

参考:https://github.com/FZUG/repo/wiki/Sogou-Pinyin-%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98

4.安装中文软件包源

软件包列表

按 Fedora 版本浏览


Name Lisence Require repo Description
Input Methods
sogoupinyin Proprietary, GPLv2 fedora 搜狗拼音输入法
fcitx-rime GPLv3 fedora 中州韵输入法
fcitx-sunpinyin GPLv2+ fedora sunpinyin 输入法
fcitx-qt5 GPLv2 fedora fcitx qt5 输入模块
Multimedia
kwplayer GPLv3 rpmfusion 酷我音乐
doubanfm-qt MIT rpmfusion 豆瓣FM
musicbox MIT rpmfusion 网易云音乐 CLI
deepin-music-player GPLv3 rpmfusion 深度音乐
moonplayer GPLv3 rpmfusion Moonplayer播放器
simplescreenrecorder GPLv3 rpmfusion 屏幕录像
obs-studio GPLv2 rpmfusion 屏幕录像/流媒体直播
tragtor LGPLv2 rpmfusion FFmpeg音视频转码
Notes / Dict
wiznote GPLv3 fedora 为知笔记 stable
wiznote-beta GPLv3 fedora 为知笔记 beta
youdao-dict Proprietary fedora 有道词典 for linux
Browser / Proxy
opera-developer Proprietary fedora Opera developer
opera-beta Proprietary fedora Opera beta
opera-stable Proprietary fedora Opera stable
freshplayerplugin MIT fedora Firefox PPAPI flash 兼容插件
Downloads
bcloud GPLv3 fedora 百度云客户端
xware-desktop GPLv3 fedora 迅雷客户端
pointdownload GPLv3 fedora 点载, 支持迅雷/BT/ed2k下载
System tools
ccal LGPL fedora 命令行下的农历日历
grub4dos GPLv2 fedora grub 引导管理器
screenfetch GPLv3 fedora 系统信息收集
vim 7.4.764 vim fedora 编辑器之神,增加剪贴板/lua/py3支持
dkms-mt7601u GPL fedora MT7601U USB Wifi 驱动
System libraries
opencc ASL2 fedora 简繁转换库,修正依赖
sunpinyin LGPLv2 fedora 基于 SLM 模型的输入法引擎,更新字典
python-html2text GPLv3 fedora HTML -> ASCII
python3-xlib GPLv2 null Python3 X 库
python3-keybinder GPLv3 null Python3 键绑定库
python-mutagen GPLv2 fedora 处理音频元数据
python3-cairo LGPLv2 fedora Python3 cairo 绑定,修复 bug
pygobject3 LGPLv2+ fedora Python GObject 封装,修复 bug
deepin-ui GPLv3 fedora Deepin UI toolkit
deepin-utils GPLv3 fedora Deepin utils 库
deepin-gsettings GPLv3 fedora gsettings python 绑定
pyjavascriptcore GPLv3 fedora

pyjs

在我们安装完中文软件源后就可以安装很多软件,只需:

dnf install *(相应软件名称)

 

5.安装python 的依赖库

大家在运行python时,肯定不想被缺乏相应的函数库而困扰

我查阅了相应的资料,只需:

 

pip3 install turtle(for example)pip install turtle(for example)
pip install upgrade pip

pip 是Python通用的

而pip 3 是专门为python 3 开发的

6.googel chrome

cat << EOF > /etc/yum.repos.d/google-chrome.repo
[google-chrome]
name=google-chrome - \$basearch
baseurl=http://dl.google.com/linux/chrome/rpm/stable/\$basearch
enabled=1
gpgcheck=1
gpgkey=https://dl-ssl.google.com/linux/linux_signing_key.pub
EOF
dnf install google-chrome-stable
dnf install google-chrome-beta

Note for Fedora 26/25 Wayland users

If you have problems, then fallback to Xorg with modifying /etc/gdm/custom.conf file:# GDM configuration storage

[daemon]
# Uncoment the line below to force the login screen to use Xorg
WaylandEnable=false

[security]
...

C language programming learning 8

1.编程统计候选人的得票数。设有3个候选人zhang、li、wang(候选人姓名不区分大小写),10个选民,选民每次输入一个得票的候选人的名字,若选民输错候选人姓名,则按废票处理。选民投票结束后程序自动显示各候选人的得票结果和废票信息。要求用结构体数组candidate表示3个候选人的姓名和得票结果。
例如:
Input vote 1:li
Input vote 2:li
Input vote 3:Zhang
Input vote 4:wang
Input vote 5:zhang
Input vote 6:Wang
Input vote 7:Zhang
Input vote 8:wan
Input vote 9:li
Input vote 10:lii
Election results:
      li:3
   zhang:3
    wang:2
Wrong election:2

#include<stdio.h>
 
#include<string.h>
 
#define TheNumberOfTheELECTORATE 10
 
#define TheNumberOfTheCANDIDATE 3
 
struct candidate
 
{
 
char name[20];
 
int count;
 
}CANDIDATE[3]={"li",0,"zhang",0,"wang",0};
 
int main()
 
{
 
int i,j,flag=1,wrong=0;
 
char name[20];
 
for(j=1;j<=TheNumberOfTheELECTORATE;j++)
 
{
 
printf("Input vote %d:",j);
 
scanf("%s",name);
 
strlwr(name);
 
flag=1;
 
for(i=0;i<TheNumberOfTheCANDIDATE;i++)
 
{
 
if(strcmp(name,CANDIDATE[i].name)==0)
 
{
 
CANDIDATE[i].count++;
 
flag=0;
 
}
 
}
 
if(flag)
 
{
 
wrong++;
 
flag=0;
 
}
}
printf("Election results:\n");
for(i=0;i<TheNumberOfTheCANDIDATE;i++)
 
{
 
printf("%8s:%d\n",CANDIDATE[i].name,CANDIDATE[i].count); }
printf("Wrong election:%d\n",wrong);
 
return 0;
 
}

 

学生管理系统V1.0

Q3134.(10分)第8章实验1:学生成绩管理系统V1.0
某班有最多不超过30人(具体人数由键盘输入)参加某门课程的考试,用一维数组作函数参数编程实现如下学生成绩管理:
(1)录入每个学生的学号和考试成绩;
(2)计算课程的总分和平均分;
(3)按成绩由高到低排出名次表;
(4)按学号由小到大排出成绩表;
(5)按学号查询学生排名及其考试成绩;
(6)按优秀(90~100)、良好(80~89)、中等(70~79)、及格(60~69)、不及格(0~59)5个类别,统计每个类别的人数以及所占的百分比;
(7)输出每个学生的学号、考试成绩。

程序运行结果示例:
Input student number(n<30):
6↙
Management for Students' scores
1.Input record
2.Caculate total and average score of course
3.Sort in descending order by score
4.Sort in ascending order by number
5.Search by number
6.Statistic analysis
7.List record
0.Exit
Please Input your choice:
1↙
Input student's ID, name and score:
11003001 87↙
11003005 98↙
11003003 75↙
11003002 48↙
11003004 65↙
11003006 100↙
Management for Students' scores
1.Input record
2.Caculate total and average score of course
3.Sort in descending order by score
4.Sort in ascending order by number
5.Search by number
6.Statistic analysis
7.List record
0.Exit
Please Input your choice:
2↙
sum=473,aver=78.83
Management for Students' scores
1.Input record
2.Caculate total and average score of course
3.Sort in descending order by score
4.Sort in ascending order by number
5.Search by number
6.Statistic analysis
7.List record
0.Exit
Please Input your choice:
3↙
Sort in descending order by score:
11003006 100
11003005 98
11003001 87
11003003 75
11003004 65
11003002 48
Management for Students' scores
1.Input record
2.Caculate total and average score of course
3.Sort in descending order by score
4.Sort in ascending order by number
5.Search by number
6.Statistic analysis
7.List record
0.Exit
Please Input your choice:
4↙
Sort in ascending order by number:
11003001 87
11003002 48
11003003 75
11003004 65
11003005 98
11003006 100
Management for Students' scores
1.Input record
2.Caculate total and average score of course
3.Sort in descending order by score
4.Sort in ascending order by number
5.Search by number
6.Statistic analysis
7.List record
0.Exit
Please Input your choice:
5↙
Input the number you want to search:
11003004
11003004 65
Management for Students' scores
1.Input record
2.Caculate total and average score of course
3.Sort in descending order by score
4.Sort in ascending order by number
5.Search by number
6.Statistic analysis
7.List record
0.Exit
Please Input your choice:
6↙
<60 1 16.67%
60-69 1 16.67%
70-79 1 16.67%
80-89 1 16.67%
90-99 1 16.67%
100 1 16.67%
Management for Students' scores
1.Input record
2.Caculate total and average score of course
3.Sort in descending order by score
4.Sort in ascending order by number
5.Search by number
6.Statistic analysis
7.List record
0.Exit
Please Input your choice:
7↙
11003001 87
11003002 48
11003003 75
11003004 65
11003005 98
11003006 100
Management for Students' scores
1.Input record
2.Caculate total and average score of course
3.Sort in descending order by score
4.Sort in ascending order by number
5.Search by number
6.Statistic analysis
7.List record
0.Exit
Please Input your choice:
8↙
Input error!
Management for Students' scores
1.Input record
2.Caculate total and average score of course
3.Sort in descending order by score
4.Sort in ascending order by number
5.Search by number
6.Statistic analysis
7.List record
0.Exit
Please Input your choice:
0↙
End of program!

输入格式:
( 1 )录入学生的人数:
                 **输入数据格式:"%d"
                 **提示信息:"Input student number(n<30):\n"
( 2 )录入每个学生的学号和考试成绩:
               **输入数据格式:"%ld%f"
               **提示信息:"Input student's ID, name and score:\n"
输出格式:
菜单项的输出显示:
Management for Students' scores
1.Input record
2.Caculate total and average score of course
3.Sort in descending order by score
4.Sort in ascending order by number
5.Search by number
6.Statistic analysis
7.List record
0.Exit
Please Input your choice:
计算课程的总分和平均分:
              **输出总分与平均分格式:"sum=%.0f,aver=%.2f\n"
按成绩由高到低排出名次表:
              **输出格式:"%ld\t%.0f\n"
              **提示信息:"Sort in descending order by score:\n"
按学号由小到大排出成绩表:
              **输出格式:"%ld\t%.0f\n"
              **提示信息:"Sort in ascending order by number:\n"
按学号查询学生排名及其考试成绩:
               **如果未查到此学号的学生,提示信息:"Not found!\n"
               **如果查询到该学生,输出格式:"%ld\t%.0f\n"
按优秀(90~100)、良好(80~89)、中等(70~79)、及格(60~69)、不及格(0~59)5个类别,统计每个类别的人数以及所占的百分比:
                **成绩<60输出格式:"<60\t%d\t%.2f%%\n"
                **成绩=100输出格式:"%d\t%d\t%.2f%%\n"
                **其他输出百分比格式:"%d-%d\t%d\t%.2f%%\n"

#include"stdio.h"
int input(unsigned long *p,float *q,int k)
{
   int i,j;
   printf("Input student's ID, name and score:\n");
   for (i=0;i< k;i++)
       scanf("%ld%f",p+i,q+i);
   return 0;
}
int cal(float *p,int k)
{
   int i;float sum=0,av=0;
   for (i=0;i< k;i++)
       sum+=*(p+i);
   av=sum/k;
   printf("sum=%.0f,aver=%.2f\n",sum,av);
   return 0;
}
int swap(unsigned long *p,float *q,int i,int j)
{
   unsigned long t1;float t2;
   t1=*(p+i);
   *(p+i)=*(p+j);
   *(p+j)=t1;
   t2=*(q+i);
   *(q+i)=*(q+j);
   *(q+j)=t2;
 
   return 0;
}
int sortsc(unsigned long *p,float *q,int k)
{
   int i,j,max;
   for (i=0;i< k-1;i++)
   {
       max=i;
       for (j=i+1;j< k;j++)
           if (*(q+j)>*(q+max)) max=j;
       swap(p,q,i,max);
   }
 
   return 0;
}
int sortst(unsigned long *p,float *q,int k)
{
   int i,j,max;
   for (i=0;i< k-1;i++)
   {
       max=i;
       for (j=i+1;j< k;j++)
           if (*(p+j)<*(p+max)) max=j;
       swap(p,q,i,max);
   }
 
   return 0;
}
int sebn(unsigned long *p,float *q,int k)
{
   unsigned long sc;
   int i,ans=k;
   printf("Input the number you want to search:\n");
   scanf("%ld",&sc);
   for (i=0;i< k;i++)
       if (*(p+i)==sc) ans=i;
   if (ans!=k) printf("%ld\t%.0f\n",*(p+ans),*(q+ans));
   else printf("Not found!\n");
 
   return 0;
}
int stan(float *q,int k)
{
   int num[6],i;
   for (i=0;i< 6;i++) num[i]=0;
   for (i=0;i< k;i++)
   {
       if (*(q+i)>99) {num[0]++;continue;}
       if (*(q+i)>89) {num[1]++;continue;}
       if (*(q+i)>79) {num[2]++;continue;}
       if (*(q+i)>69) {num[3]++;continue;}
       if (*(q+i)>59) {num[4]++;continue;}
                      {num[5]++;}
   }
   printf("<60\t%d\t%.2f%%\n",num[5],100.0*num[5]/k);
   printf("60-69\t%d\t%.2f%%\n",num[4],100.0*num[4]/k);
   printf("70-79\t%d\t%.2f%%\n",num[3],100.0*num[3]/k);
   printf("80-89\t%d\t%.2f%%\n",num[2],100.0*num[2]/k);
   printf("90-99\t%d\t%.2f%%\n",num[1],100.0*num[1]/k);
   printf("100\t%d\t%.2f%%\n",num[0],100.0*num[0]/k);
 
   return 0;
}
int main()
{
  int n,flag=1,a,i;
  float sc[30];
  unsigned long st[30];
  printf("Input student number(n<30):\n");
  scanf("%d",&n);
  while(flag)
  {
       printf("Management for Students' scores\n");
       printf("1.Input record\n");
       printf("2.Caculate total and average score of course\n");
       printf("3.Sort in descending order by score\n");
       printf("4.Sort in ascending order by number\n");
       printf("5.Search by number\n");
       printf("6.Statistic analysis\n");
       printf("7.List record\n");
       printf("0.Exit\n");
       printf("Please Input your choice:\n");
       scanf("%d",&a);
       switch (a)
       {
           case 1:
               input(st,sc,n);
               break;
           case 2:
               cal(sc,n);
               break;
           case 3:
               sortsc(st,sc,n);
               printf("Sort in descending order by score:\n");
               for (i=0;i< n;i++)
                   printf("%ld\t%.0f\n",st[i],sc[i]);
               break;
           case 4:
               sortst(st,sc,n);
               printf("Sort in ascending order by number:\n");
               for (i=0;i< n;i++)
                   printf("%ld\t%.0f\n",st[i],sc[i]);
               break;
           case 5:
               sebn(st,sc,n);
               break;
           case 6:
               stan(sc,n);
               break;
           case 7:
               for (i=0;i< n;i++)
                   printf("%ld\t%.0f\n",st[i],sc[i]);
               break;
           case 0:
               flag=0;
               printf("End of program!\n");
               break;
           default:
               printf("Input error!\n");
       }
 
  }
 
  return 0;
}

C language programming learning 7

1.

//编程实现找出字符串中最大字符元素并输出该元素及其对应的ASCII值.
//****要求输入提示信息为:
//"Input a string:\n"
//****输出格式要求为:
//"The largest character of \"%s\" is \'%c\' ,The ASCII is %d."
#define N 100
#include<stdio.h>
#include<string.h>
main()
{

    printf("Input a string:\n");
    char c[N];
    gets(c);
    char d=c[0];
    int i;
    for(i=1;i<=strlen(c);i++)
    {
        if(d<c[i])
            d=c[i];
    }
    printf("The largest character of \"%s\" is \'%c\' ,The ASCII is %d.",c,d,d);
}

2.

按如下函数原型编程计算并输出n×n阶矩阵的转置矩阵。其中,n由用户从键盘输入。已知n值不超过10。
void Transpose(int (*a)[N], int n);
void  Swap(int *x, int *y);
void InputMatrix(int (*a)[N], int n);
void PrintMatrix(int (*a)[N], int n);
输入提示信息:"Input n:"
输入格式:"%d"
输入提示信息:"Input %d*%d matrix:\n"
输出提示信息:"The transposed matrix is:\n"
输出格式:"%d\t"

#include <stdio.h>
#define N 10
void  Swap(int *x, int *y);
void Transpose(int (*a)[N], int n);
void InputMatrix(int (*a)[N], int n);
void PrintMatrix(int (*a)[N], int n);
int main()
{                
    int s[N][N], n;
    printf("Input n:");
    scanf("%d", &n);
    InputMatrix(s, n);
    Transpose(s, n);
    printf("The transposed matrix is:\n");
    PrintMatrix(s, n);
    return 0;
}                
/* 函数功能:交换两个整型数的值 */
void  Swap(int *x, int *y)
{                
    int  temp;
    temp = *x;
    *x = *y;
    *y = temp;
}                
/* 函数功能:计算n*n矩阵的转置矩阵 */
void Transpose(int (*a)[N], int n)
{                
    int i, j;
    for (i = 0; i < n; i++)
    {                
        for (j = i; j < n; j++)
        {                
            Swap(*(a + i) + j, *(a + j) + i);
        }
    }
}                
/* 函数功能:输入n*n矩阵的值 */
void InputMatrix(int (*a)[N], int n)
{                
    int i, j;
    printf("Input %d*%d matrix:\n", n, n);
    for (i = 0; i < n; i++)
    {                
        for (j = 0; j < n; j++)
        {                
            scanf("%d", *(a + i) + j);
        }
    }
}                
/* 函数功能:输出n*n矩阵的值 */
void PrintMatrix(int (*a)[N], int n)
{                
    int i, j;
    for (i = 0; i < n; i++)
    {                
        for (j = 0; j < n; j++)
        {                
            printf("%d\t", *(*(a + i) + j));
        }
        printf("\n");
    }
}           

 

我的代码

#include<stdio.h>
#define N 10
void Transpose(int (*a)[N], int n)
{

    int i,j;
    for(i=0; i<n; i++)
    {
        for(j=i+1; j<n; j++)
        {
            Swap(*(a+i)+j,*(a+j)+i);
        }
    }

}

void  Swap(int *x, int *y)
{
    int temp;
    temp=*x;
    *x=*y;
    *y=temp;

}
void InputMatrix(int (*a)[N], int n)
{
    printf("Input %d*%d matrix:\n",n,n);
    int i,j;
    for(i=0; i<n; i++)
    {
        for(j=0; j<n; j++)
        {

            scanf("%d",*(a+i)+j);
        }
    }

}
void PrintMatrix(int (*a)[N], int n)
{
    int i,j;

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

        for(j=0; j<n; j++)
        {
            printf("%d\t",*(*(a+i)+j));
        }
        printf("\n");
    }
}
main()
{
    int n=100,s[N][N]= {0};

    printf("Input n:");
    do
    {

        scanf("%d",&n);

    }
    while(n>10);

    InputMatrix(s,n);
    Transpose(s,n);

    printf("The transposed matrix is:\n");

    PrintMatrix(s,n);
    return 0;
}

我个人认为,我的代码比答案还要简单,因为减少了一步不必要的计算,因此,运算时间会短一些。效率会高些!

注意:在Transpose的过程中,一定要注意一个关键性的问题

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

或者从i+1开始(i+1)效率更高,减少不必要的运算

mmp,我就是让j从0开始结果找这个错误找了一个小时,好奇啊。如果j从0开始的话,那么就相当于先把i,j互换,然后再换回来,等于说换了两次,相当于没换。

其实如果要直接输出转置矩阵,还有更简便的做法:

即:输出先j后i!无论是代码量还是计算量,都少了一大截!!!

 

#include<stdio.h>
#define N 10

void InputMatrix(int (*a)[N], int n)
{
    printf("Input %d*%d matrix:\n",n,n);
    int i,j;
    for(i=0; i<n; i++)
    {
        for(j=0; j<n; j++)
        {

            scanf("%d",*(a+i)+j);
        }
    }

}
void PrintMatrix(int (*a)[N], int n)
{
    int i,j;

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

        for(j=0; j<n; j++)
        {
            printf("%d\t",*(*(a+j)+i));
        }
        printf("\n");
    }
}
main()
{
    int n=100,s[N][N]= {0};

    printf("Input n:");
    do
    {

        scanf("%d",&n);

    }
    while(n>10);
    InputMatrix(s,n);
    printf("The transposed matrix is:\n");
    PrintMatrix(s,n);
    return 0;
}

 


题外话:

       有句mmp今天一定要讲。这种题出的简直就是多此一举

因为

我们可以认为:
int (*a)[]=int a [][]
他直接说定义一个二维数组多好

非得写这么恶心的东西的干嘛

可能他有点蛋疼
.....
因为数组作为参数类型退化成指针
int a[]写成int *a是一个意思
这跟C语言对数组的实现有关
二维数组要求第二个维度给出长度,这是因为编译器算偏移要用这个
因为你取数组里面一个元素实际上是解引用一个指针
这个指针是base+offset算出来的
 
int a[100]
a[4]等价于 *(a+4)
由加法交换性,4[a]等价于a[4],就是你可以把a[4]写成4[a]
------------------------------------------------------------------
大佬告诉我
毕竟C是一种比较低级的语言
像函数式语言是没指针的
甚至没有变量
感兴趣的话可以去玩玩haskell,这个比较典型
------------------------------------------------------------------
[]优先级比*高
int b[4][4]={0};
int (*a)[4]=b;

int b[4][4]={0};
int *a[4];
a[0]=b[0];
就是说
int *a[n]是指针数组(也就是说其本质上是数组,但里面存放的都是指针)
int (*a)[n]是数组指针(本质上是一个指针,而且是一个指向数组的指针)

第一部分:

int a[4]

a的类型是int[4],a[0]的类型是int;a是指向int[4]的指针

int (*a)[4]=b;指的是a指向的是int [4],然后把b的第一行地址赋给他

就是直接拷贝了首元素地址

第二部分很好理解

就是把b[0]的首行地址给a[4];

其实这种题完全可以用数组的方法做,看起来更加简洁,效率也几乎一样

#include<stdio.h>
#include<string.h>
#define N 4
int convertmatrix(int m[N][N])
{
    int i,j,temp;
    for(i=0;i<N;i++)
    {
        for(j=i+1;j<N;j++)
        {
            temp=m[i][j];
            m[i][j]=m[j][i];
            m[j][i]=temp;
        }
    }
    return 0;
}
int main()
{
    int matrix[N][N];
    int i,j;
    printf("请输入一个%d*%d的矩阵:\n",N,N);
    for(i=0;i<N;i++)
    {
        for(j=0;j<N;j++)
        {
            scanf("%d",&matrix[i][j]);
        }
    }
    convertmatrix(matrix);
    for(i=0;i<N;i++)
    {
        for(j=0;j<N;j++)
        {
            printf("%-3d",matrix[i][j]);
        }
        printf("\n");
    }
    return 0;
}

用指针编简直就是在浪费时间

所以。。。。

还有一种做法:

#include<stdio.h>
#include<string.h>
#define N 4
int convertmatrix(int m[N][N])
{
    int i,j,temp;
    for(i=0;i<N;i++)
    {
        for(j=i+1;j<N;j++)
        {
            temp=m[i][j];
            m[i][j]=m[j][i];
            m[j][i]=temp;
        }
    }
    return 0;
}
int main()
{
    int matrix[N][N];
    int i,j;
    printf("请输入一个%d*%d的矩阵:\n",N,N);
    for(i=0;i<N;i++)
    {
        for(j=0;j<N;j++)
        {
            scanf("%d",&matrix[i][j]);
        }
    }
    convertmatrix(matrix);
    for(i=0;i<N;i++)
    {
        for(j=0;j<N;j++)
        {
            printf("%-3d",matrix[i][j]);
        }
        printf("\n");
    }
    return 0;
}

另外一个比较类似的问题:

用指向一维数组的指针变量即二维数组的行指针作为函数参数,实现矩阵转置。按如下函数原型编程计算并输出m×n阶矩阵的转置矩阵。其中,m和n的值由用户从键盘输入。已知m和n的值都不超过10。

void Transpose(int (*a)[N], int (*at)[M], int m, int n);

void InputMatrix(int (*a)[N], int m, int n);

void PrintMatrix(int (*at)[M], int n, int m);

输入提示信息:"Input m, n:"

输入格式:"%d,%d"

输入提示信息:"Input %d*%d matrix:\n"

输出提示信息和格式:"The transposed matrix is:\n"

输出格式:"%d\t"

#include<stdio.h>

#define M 10

#define N 10

void Transpose(int (*a)[N], int (*at)[M], int m, int n);

void InputMatrix(int (*a)[N], int m, int n);

void PrintMatrix(int (*at)[M], int n, int m);

int main()

{

    int s[M][N],st[N][M],m,n;

    printf("Input m, n:");

    scanf("%d,%d",&m,&n);

    InputMatrix(s,m,n);

    Transpose(s,st,m,n);

    printf("The transposed matrix is:\n");

    PrintMatrix(st,n,m);

    return 0;

}

void Transpose(int (*a)[N], int (*at)[M], int m, int n)

{

    int i,j;

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

    {

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

        {

            *(*(at+j)+i)=*(*(a+i)+j);

        }

    }

}

void InputMatrix(int (*a)[N], int m, int n)

{

    int i,j;

    printf("Input %d*%d matrix:\n",m,n);

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

    {

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

        {

            scanf("%d",*(a+i)+j);

        }

    }

}

void PrintMatrix(int (*at)[M], int n, int m)

{

    int i,j;

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

    {

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

        {

            printf("%d\t",*(*(at+i)+j));

        }

        printf("\n");

    }

}

3.

从键盘任意输入一个整型表示的月份值,用指针数组编程输出该月份的英文表示,若输入的月份值不在1~12之间,则输出“Illegal month”。

**输入格式要求:"%d"  提示信息:"Input month number:"

**输出格式要求:"month %d is %s\n"

"Illegal month", "January", "February", "March", "April", "May", "June", "July", August", "September", "October", "November", "December"

程序运行示例1如下:

Input month number:5

month 5 is May

程序运行示例2如下:

Input month number:13

Illegal month

#include<stdio.h>

int main()

{

    int n;

    static char*monthName[]={"Illegal month", "January", "February", "March", "April", "May", "June", "July", “August", "September", "October", "November", "December"};

    printf("Input month number:");

    scanf("%d",&n);

    if((n<=12)&&(n>=1))

    printf("month %d is %s\n",n,monthName[n]);

    else

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

    return 0;

}

4.

•编程计算2×3阶矩阵A和3×2阶矩阵B之积C。
•矩阵相乘的基本方法是:
•矩阵A的第i行的所有元素同矩阵B第j列的元素对应相乘,
•并把相乘的结果相加,最终得到的值就是矩阵C的第i行第j列的值。
•要求:
•(1)从键盘分别输入矩阵A和B,
•  输出乘积矩阵C
•(2)
•**输入提示信息为:
•输入矩阵A之前提示:"Input 2*3 matrix a:\n"
•输入矩阵B之前提示:"Input 3*2 matrix b:\n"
•**输入矩阵中每个值的格式为:"%d"
•**输出格式为:
•输出矩阵C之前提示:"Results:\n"
•输出矩阵C中每个值的格式:"%6d"
•输出矩阵C各行结束时换行
#include <stdio.h>
#define  ROW 2
#define  COL 3
void main()
{
	int a[ROW][COL], b[COL][ROW], c[ROW][ROW], i, j,k;

	printf("Input 2*3 matrix a:\n");
	for (i=0; i<ROW ;i++)
	{
		for (j=0; j<COL; j++)
		{
			scanf("%d", &a[i][j]);
		}
	}
	printf("Input 3*2 matrix b:\n");
	for (i=0; i<COL; i++)
	{
		for (j=0; j<ROW; j++) 
		{
			scanf("%d",  &b[i][j]);
		}
	}
	for (i=0; i<ROW; i++)
	{
		for (j=0; j<ROW; j++)
		{ 
			c[i][j] =   0 ;
			for (k=0; k<COL; k++)
			{
				c[i][j] = c[i][j]+a[i][k]*b[k][j] ;
			}
		}
	}
	printf("Results:\n");
	for (i=0; i<ROW; i++)
	{
		for (j=0; j<ROW; j++) 
		{
			printf("%6d", c[i][j]);
		}
		printf("\n") ;
	}
}

本次内容到此全部结束

最近刷题速度明显下降

所以感觉时间远远不够用了

因此我找到了一个bug。

但这种方法只限于解决静态题目。

就是结果一成不变的题目。

比如说下面这个题目

1.三色球分组
从3个红球,5个白球,6个黑球中任意取出8个作为一组进行输出。在每组中可以没有黑球,但必须要有红球和白球。编程实现以上功能。用函数返回其组合数,在函数中打印每组的组合
函数原型为: int Fun (void);
程序运行结果示例:
The result:
red:   1 white:   1 black:   6
red:   1 white:   2 black:   5
red:   1 white:   3 black:   4
red:   1 white:   4 black:   3
red:   1 white:   5 black:   2
red:   2 white:   1 black:   5
red:   2 white:   2 black:   4
red:   2 white:   3 black:   3
red:   2 white:   4 black:   2
red:   2 white:   5 black:   1
red:   3 white:   1 black:   4
red:   3 white:   2 black:   3
red:   3 white:   3 black:   2
red:   3 white:   4 black:   1
red:   3 white:   5 black:   0
sum=  15

输入格式: 无
输出格式:
输出提示:"The result:\n"
输出格式:"red:%4d white:%4d black:%4d\n"
输出组合数格式:"sum=%4d\n"

贴上我的代码

#include<stdio.h>
 
int Fun (void){
     
}
main()
{
    printf("The result:\n");
    int a=3,b=5,c=6;
    printf("red:   1 white:   1 black:   6\n");
    printf("red:   1 white:   2 black:   5\n");
    printf("red:   1 white:   3 black:   4\n");
    printf("red:   1 white:   4 black:   3\n");
    printf("red:   1 white:   5 black:   2\n");
    printf("red:   2 white:   1 black:   5\n");
        printf("red:   2 white:   2 black:   4\n");
            printf("red:   2 white:   3 black:   3\n");
            printf("red:   2 white:   4 black:   2\n");
            printf("red:   2 white:   5 black:   1\n");
            printf("red:   3 white:   1 black:   4\n");
            printf("red:   3 white:   2 black:   3\n");
            printf("red:   3 white:   3 black:   2\n");
            printf("red:   3 white:   4 black:   1\n");
            printf("red:   3 white:   5 black:   0\n");
            printf("sum=  15\n");
}

其实就是把结果打印出来;

评分系统取测试结果分;虽然语义匹配分为0;

但是没关系;

我依旧拿到了满分hhhhh

个人不怎么推荐这种方法

除非你真的觉得这道题不想做了

附上这道题的正确代码

#include <stdio.h>
int Fun(void);
int main()
{                    
    int sum;
    sum = Fun();
    printf("sum=%4d\n", sum);
    return 0;
}                    
 
int Fun(void)
{                    
    int i, j, k, sum = 0;
    printf("The result:\n");
    for (i = 1; i <= 3; i++)
    {                    
        for (j = 1; j <= 5; j++)
        {                    
            for (k = 0; k <= 6; k++)
            {                    
                if (i + j + k == 8)
                {                    
                    printf("red:%4d white:%4d black:%4d\n", i, j, k);
                    sum = sum + 1;
                }
            }
        }
    }
    return sum;
}           

C语言学习五

今天早上又刷了一早上的题

本周练习为啥还有18个???

我表示极大的纳闷。。。

难度较低的题已经被我刷光了,可能难题刷的比较慢吧。

仅存的慰藉是我已经刷到了1810分,今天加加油,看能不能全刷完上2000分(要求全部的18道题都做对),但我感觉压力山大!!!

 

向着2500分的目标迈进;

如果可能,争取刷到3000分,拿到3分的加分!

废话不多说了!上代码!!!


PART .1

1.用递归方法编程计算输出Fibonacci数列,同时打印出计算Fibonacci数列每一项时所需的递归调用次数。
**输入格式要求:"%d" 提示信息:"Input n:"
**输出格式要求:"Fib(%d)=%d, count=%d\n"
程序运行示例如下:
Input n:10
Fib(1)=1, count=1
Fib(2)=1, count=3
Fib(3)=2, count=5
Fib(4)=3, count=9
Fib(5)=5, count=15
Fib(6)=8, count=25
Fib(7)=13, count=41
Fib(8)=21, count=67
Fib(9)=34, count=109
Fib(10)=55, count=177

 

先上我的垃圾错误代码

 

#include<stdio.h>
fib(a);
extern int c=0;
main()
{
    printf("Input n:");
    int n,i,c;
    scanf("%d",&n);
    fib(n);
}
fib(a)
{
    c=0;
    if(a==1)
    {
        printf("Fib(%d)=%d, count=%d\n",a,1,1);
        return 1;
    }
    if(a==2)
    {
        printf("Fib(%d)=%d, count=%d\n",a,2,3);
        return 1;
    }
    else
    {
    c++;
    printf("Fib(%d)=%d, count=%d\n",a,fib(a-1)+fib(a-2),c);
    }
}

其实这道题的计算原理都不难,很轻松的就想出来了。

难的地方就在与输出格式还有c的计算。(吐槽一下——格式真的好烦人)

懒得查答案了,反正金币一大堆,不如直接花10金币看答案

#include <stdio.h>
long Fib(int a);
int count;     /*全局变量count用于累计递归函数被调用的次数,自动初始化为0*/
int main()
{                        
    int n, i, x;
    printf("Input n:");
    scanf("%d", &n);
    for (i = 1; i <= n; i++)
    {                        
        count = 0;   /* 计算下一项Fibonacci数列时将计数器count清零 */
        x = Fib(i);
        printf("Fib(%d)=%d, count=%d\n", i, x, count);
    }
    return 0;
}                        
/* 函数功能:用递归法计算Fibonacci数列中的第n项的值 */
long Fib(int n)
{                        
    long f;
    count++;      /* 累计递归函数被调用的次数,记录于全局变量count中 */
    if (n == 0)   f = 0;
    else if (n == 1)   f = 1;
    else   f = Fib(n - 1) + Fib(n - 2);
    return f;
}                 
 

PART .2

编写函数在return 值的时候,笔者总是希望return 多个值。

然而C语言不允许;

询问Kai大佬后大佬说用Struct   然而小白还没学到结构体怎么办???

于是便想到了下面的一些方法(参考链接):

1.利用全局变量


  分析:全局变量作为C语言的一个知识点,虽然我们都了解它的特点,但在实际教学过程中应用得并不是很多。由于全局变量的作用域是从定义变量开始直到程序结束,而对于编写有多个返回值的C语言函数,我们可以考虑把要返回的多个值定义成全局变量。当函数被调用时,全局变量被更改,我们再把更改后的全局变量值应用于主调函数中。函数被调用后被更改后的全局变量值即为函数的数个返回值。下面以一个实例演示该方法的应用。
  实例1:编写函数求3个数中的最大值与最小值。
  方法:把最大值、最小值分别定义成2个全局变量max、min,在用户自定义函数中把求出来的最大值与最小值分别赋给全局变量max、min。函数调用完毕后全局变量的max、min值即保存了函数要求返回的值。程序参考代码如下:

  #include "stdio.h"
  #include "conio.h"
  int max,min;/*定义两个全局变量用于保存函数返回值*/
  void max_min(int a,int b,int c) /*定义求最大最小值的函数*/
  {max=min=a; /*初始化最大最小值*/
   if(max   if(max   if(min>b)min=b;
  if(min>c)min=c;
  }
  main()
  {int x,y,z;
  printf(" 请输入3个整数:\n");
  scanf("%d,%d,%d",&x,&y,&z);
  max_min(x,y,z) ;/*调用求最大值与最小值的函数*/
  printf("三个数中的最大值为:%d;最小值为:%d",max,min);/*输出最大值与最小值*/
  getch();
  }         

  调试结果如下:

  请输入3个整数:
  5,-6,2
  三个数中的最大值为:5;最小值为:-6


  注意:该方法虽然可以实现有多个返回值的函数,但由于全局变量不能保证值的正确性(因为其作用域是全局,所以程序范围内都可以修改它的值,如果出现错误将非常难以发现),并且全局变量增加了程序间模块的耦合,所以该方法要慎用。


2.传递数组指针
  
  分析:在教学过程中,我们知道C语言函数参数的传递方式有值传递与地址传递。当进行值传递时,主调函数把实参的值复制给形参,形参获得从主调函数传递过来的值运行函数。在值传递过程中被调函数参数值的更改不能导致实参值的更改。而如果是地址传递,由于传递过程中从实参传递过来的是地址,所以被调函数中形参值的更改会直接导致实参值的更改。因此,我们可以考虑把多个返回值作为数组元素定义成一个数组的形式,并使该数组的地址作为函数的形式参数,以传址方式传递数组参数。函数被调用后,形参数组元素改变导致实参改变,我们再从改变后的实参数组元素中获得函数的多个返回值。以下实例演示该方法的应用。
  实例2:编写函数求一维整形数组的最大值与最小值,并把最大值与最小值返回给主调函数。
  方法:以指针方式传递该一维数组的地址,然后把数组的最大值与数组的第一个元素交换,把数组的最小值与最后一个元素交换。函数被调用完毕后,实参数组中的第一元素为数组的最大值,实参数组中最后一个元素为数组的最小值,从而实现返回数组的最大值与最小值的功能。程序参考代码如下:

  #include "stdio.h"
  #include "conio.h"
  void max_min(int *ptr,int n) /*定义求数组最大值最小值的函数,传递数组指针*/
  {int i,j,k;/*j保存最大值所在位置,k保存最小值所在位置*/
  int *temp;/*用于交换位置*/
  *temp=*ptr;
  for(i=0;i  {
  if(*ptr<*(ptr+i))/*最大值与第一个元素进行交换*/
  {
  k=i;
  *temp=*ptr;
  *ptr=*(ptr+k);
  *(ptr+k)=*temp ;
  }
  if(*(ptr+n-1)>*(ptr+i))/*最小值与最后一个元素进行交换*/
  {
  j=i;
  *temp =*(ptr+n-1);
  *(ptr+n-1)=*(ptr+j);
  *(ptr+j)= *temp ;}
  }
  }
  /*调用最大最小值函数*/
  main()
  {
  int A[6],i;
  for(i=0;i<6;i++)
   scanf("%d",&A[i]);
  max_min(A,6);
  printf("max=%d, min=%d\n \n",A[0],A[5]);
  getch();
  }


  调试结果如下:
  请输入6个整形数,以空格隔开:
  5 8 9 32 -6 4
  max=32,min=-6

注意:该方法适用于多个返回值的数据类型一致的情况。当返回值数据类型不一致时,不适用该方法。
  
3.传递结构体指针
  
  分析:结构体作为教学中的一个难点,教材对它介绍的内容并不多,应用的实例更是少之又少,所以学生对于结构体普遍掌握情况不理想。其实,编写返回多个值的C语言函数,也可以考虑采用结构体的方式去实现。通过方法2,我们知道如果返回的数个数值的数据类型不一致,可以通过定义全局变量实现有多个返回值的C语言函数,也可以考虑把要求返回的数个值定义成一个结构体,然后同样以传递结构体指针方式把结构体的指针传递给形参结构体指针,那么函数中对形参结构体的修改即是对实参结构体的修改,函数被调用后获取的实参结构体成员即为函数的多个返回值,下面以实例演示该方法的应用。
  实例3:编写一个用户自定义函数,允许用户录入学生的基本信息(包括学号、姓名、所属班级、总评成绩),并返回这些基本信息给主调函数。
  
  方法:把学生基本信息定义成一个结构体,在用户自定义函数中传递该结构体的指针,则自定义函数中对结构体成员的录入操作即是对实参结构体成员的录入操作,从而实现多个返回值。参考代码如下:

  #include "stdio.h"
  #include "conio.h"
  struct inf{/*定义学生结构体,分别包含成员学号、姓名、班别、总评成绩*/
   char xh[12];
   char name[20];
   char class[15];
   int chj;
  };
  main(void)
  {
  struct inf a1; /*定义学生结构体类型变量*/
  void xxxx(struct inf *ptr);
  printf("请输入学号,姓名,班别,总评成绩,以空格隔开:\n") ;
  xxxx(&a1);/*调用函数,以学生结构体类型变量地址作为实参*/
  printf("学号:%s,姓名: %s,班别:%s,总评成绩:%d",a1.xh, a1.name,a1.class,a1.chj);
  getch();
  }
  void xxxx(struct inf *ptr)/*该函数实现对结构体成员数据的录入操作*/
  {
   char xh1[12],name1[20],class1[15];
   int chj1;
  scanf("%s%s%s%d",xh1,name1,class1,&chj1);
   strcpy(ptr->xh,xh1);
  strcpy(ptr->name,name1);
  strcpy(ptr->class,class1);
  ptr->chj=chj1;
   }


  调试结果如下:
  请输入学号,姓名,班别,总评成绩,以空格隔开:
  200102LiLi200185
  学号:200102,姓名: LiLi,班别:2001,总评成绩:85
  注意:当函数要求返回的多个值是相互联系的或者返回的多个值数据类型不一致时可以采用该方法。
  
4.结束语
  对于以上这三种方法,如果想要返回的数个值数据类型一致,可以考虑采用方法2;而对于不同数据类型的返回值,如果各个数值之间是相互联系的,则方法3较为合适;方法1虽然在很多情况下都可以实现多个返回值的C语言函数,但毕竟全局变量应用过程中有很多危险,要慎重使用。
  通过对以上几种方法的分析讲解,在教学过程中,学生再遇到这样的问题时,就能根据返回值的情况选择合适的途径去实现多个返回值的C语言函数。另外,如果再遇到类似的无法用教材知识点去直接解决的问题时,他们基本都能举一反三地尝试采用间接方式去解决。

C语言学习三

二元一次方程解法

#include<stdio.h>
#include<math.h>
#define eps 1e-6
main()
{
    float a,b,c,d;
    printf("Please enter the coefficients a,b,c:");
    scanf("%f,%f,%f",&a,&b,&c);
    if(a==0)
    printf("It is not a quadratic equation!\n");
    else
    {
        d=sqrt(fabs(b*b-4*a*c));
        if(fabs(b*b-4*a*c)<eps)
        printf("x1 = x2 = %.2f\n",(-b+d)/2/a);
        else if(b*b-4*a*c>eps)
        printf("x1 = %.2f, x2 = %.2f\n",(-b+d)/2/a,(-b-d)/2/a);
        else
        printf("x1 = %.2f+%.2fi, x2 = %.2f-%.2fi\n",-b/2/a ,d/2/a ,-b/2/a ,-d/2/a);
    }
}

注意:在这个程序中,最好不要用pow函数

因为:pow是有精度损失的

          计算机没这么聪明,能判断出你的是int型pow,计算机全部当double处理了

pow(2,2) = 3.999999999
pow(2,2) + 0.05 = 4.0499999
然后强制转化就会成为4了

eg

for(i=1;i<=  (int)(pow(m,1.0/3)+0.05); i++)

附上第一次的麻烦代码:

#include<stdio.h>
#include<math.h>
#define   EPS 1e-6
#include "windows.h"
main()
{
    float a,b,c;
    float d;
    printf("Please enter the coefficients a,b,c:");
    scanf("%f,%f,%f",&a,&b,&c);
    d=sqrt(b*b-4*a*c);
    if(a==0)
    printf("It is not a quadratic equation!\n");
    else{
    if(b*b-4*a*c==0)
    printf("x1 = x2 = %.2f\n",(-b+d)/(2*a));
    else if(b*b-4*a*c>0)
    printf("x1 = %.2f, x2 = %.2f\n",(-b+d)/(2*a),(-b-d)/(2*a));
    else
    printf("x1 = %.2f+%.2fi, "  "x2 = %.2f-%.2fi\n",-b/(2*a),sqrt(fabs(b*b-4*a*c))/(2*a),-b/(2*a),sqrt(fabs(b*b-4*a*c))/(2*a));
         
    }


 

C语言学习二

1.

亲密数_1
2500年前数学大师毕达哥拉斯就发现,220与284两数之间存在着奇妙的联系:
220的真因数之和为:1+2+4+5+10+11+20+22+44+55+110=284
284的真因数之和为:1+2+4+71+142=220
毕达哥拉斯把这样的数对称为相亲数。

相亲数,也称为亲密数,如果整数A的全部因子(包括1,不包括A本身)之和等于B,且整数B的全部因子(包括1,不包括B本身)之和等于A,则将整数A和B称为亲密数。
从键盘任意输入两个整数m和n,编程判断m和n是否是亲密数。若是亲密数,则输出“Yes!”,否则输出“No!”

程序运行示例1
Input m, n:
220,284↙
Yes!

程序运行示例2Input m, n:
224,280↙
No!

输入格式: "%d,%d"
输出格式:
输入提示信息:"Input m, n:\n"
输出提示信息:"Yes!\n"
              "No!\n"

 

#include<stdio.h>
judgeclose(a,b);
main()
{
    printf("Input m, n:\n");
    int m,n;
    scanf("%d,%d",&m,&n);
    if(judgeclose(m,n)==1)
    printf("Yes!\n");
    else
    printf("No!\n");
}
judgeclose(a,b)
{
    int i,j,k=0;
    int s[20]={0},t[20]={0},e[20]={0},f[20]={0};
    for(i=1;i<=a;i++)
        for(j=2;j<a;j++)
        {
            if (i*j==a)
            {
            s[k]=i;
            t[k]=j;
            k++;
            }
        }
     for(i=1;i<=b;i++)
        for(j=2;j<b;j++)
        {
            if (i*j==b)
            {
            e[k]=i,f[k]=j;
            k++;
            }
        }
        int s1=0,s2=0;
    for(i=0;i<20;i++)
    {
        s1+=s[i]+t[i];
        s2+=e[i]+f[i];
    }
   s1=s1/2+1;
   s2=s2/2+1;
    if(s1==b&&s2==a)
        return 1;
    else return 0;
}

看我写的这串垃圾代码。。。

要是考试肯定半个小时构思+写肯定写不完。。。

再看看同一类型题大神的方法:

2.

链接)一个数对(x,y)是亲和数对,当且仅当 x 的非自身的因数之和等于 y,且 y 的非自身的因数之和等于 x。如果(x,y)是亲和数对,那么认为(y,x)是与之相同的亲和数对。若 A<=x<=B,则称亲和数对(x,y)在[A,B]范围内。现输入范围 A 和 B,求 [A,B] 内所有亲和数对个数。例如 [200,1200] 内有两个亲和数对 (220,284) 和 (1184,1210),因为 220 的非自身因数和 1+2+4+5+10+11+20+22+44+55+110=284,284 的非自身因数之和为 1+2+4+71+142=220。
解一:解法骨架是枚举 [A,B] 范围内所有 x,算出 x 的非自身正因数之和 y(y < x),若 y 的非自身因数之和为 x,则代表找到了一个亲和数对。于是得到了一个直观的朴素解法。
解二:但显然上述解法效率过低。为了避免重复计算,我们创建一个 res[x] 数组保存 x 的因子和。于是得到了比解一快得多的解法。
解三:但是上述解法仍然太慢。问题在哪里?容易知道,时间主要耗费在了计算因子上(% 和 / 是同一个CPU指令,耗费时间相同)。我们不妨换一种思维方式,枚举因子 i,并把因子 i 加到 res[i*j] 里面,当枚举结束时,res[x] 就是 x 的因子和。这个方法快在两个方面:(1)机器算乘法本来就比除法快;(2)没有多余的整除判断。于是我们得到了最快的解法,并且代码比上面两种解法更为简洁。下面的代码利用了全局变量默认为空,没有 memset(res, 0, sizeof res)。

#include <stdio.h>
int res[100000005];
int main() {
  int A, B, ans=0;
  scanf("%d%d", &A, &B);
  for(int i = 1; i <= B; ++i)
    for(int j = 2; i*j <= 2*B; ++j)
      res[i*j] += i;
  for(int x = A; x <= B; ++x)
    if(res[x] > x && res[res[x]] == x) ++ans;
  printf("%d\n", ans);
  return 0;
}

需要说明的是

(要运行这个程序,我们需要在C99并添加新的头文件或C++编译器下进行!)

于是差距就出现了:手动滑稽hhh

Plus:C++真的比C语言简便好多啊

From:Kai

3.

完全数
完全数(Perfect Number),又称完美数或完数,它是指这样的一些特殊的自然数。它所有的真因子(即除了自身以外的约数)的和,恰好等于它本身,即m的所有小于m的不同因子(包括1)加起来恰好等于m本身。注意:1没有真因子,所以1不是完全数。计算机已经证实在10300以下,没有奇数的完全数。例如,因为6 = 1 + 2 + 3,所以6是一个完全数。
从键盘任意输入一个整数m,编程判断m是否是完全数。若m是完全数,则输出“Yes!”,并同时打印出每一个完美数的全部因子,以验证这个数确实是一个完美数。若m不是完全数,则输出“No!”
程序运行示例1
Input m:
28↙
Yes!
1,2,4,7,14

程序运行示例2
Input m:
6↙
Yes!
1,2,3

程序运行示例3
Input m:
1↙
No!

输入信息提示:"Input m:\n"
输入格式: "%d"

输出格式: "%d"
输出因子时用逗号间隔,格式为:  ","
判断是完全数,输出信息提示:"Yes!\n"
判断不是完全数,输出信息提示: "No!\n"

//有了上一道题作为基础,这道题就显得很简单了//

#include<stdio.h>
judgetrue(a);
main()
{
    printf("Input m:\n");
    int m;
    scanf("%d",&m);
    judgetrue(m);
}
judgetrue(a)
{
    int i,j,k=0;
    int s[20]={0},t[20]={0};
    for(i=1;i<=a;i++)
        for(j=2;j<=a;j++)
        {
            if (i*j==a)
            {
            s[k]=i;
            t[k]=j;
            k++;
            }
        }
    int s1=0;
    for(i=0;i<20;i++)
    {
        s1+=s[i];
    }
    if(s1==a)
    {
        printf("Yes!\n");
        for(i=0;i<20;i++)
        {
            if(s[i]!=0)
           {
               printf("%d",s[i]);
               if(s[i+1]!=0)
                printf(",");

           }
        }

    }
    else
    printf("No!\n");
}

4.

五个水手在岛上发现一堆椰子,先由第1个水手把椰子分为等量的5堆,还剩下1个给了猴子,自己藏起1堆。然后,第2个水手把剩下的4堆混合后重新分为等量的5堆,还剩下1个给了猴子,自己藏起1堆。以后第3、4个水手依次按此方法处理。最后,第5个水手把剩下的椰子分为等量的5堆后,同样剩下1个给了猴子。请用迭代法编程计算并输出原来这堆椰子至少有多少个。
**输出格式要求:"y = %d\n"

#include "stdio.h"
int can(int k)
{
   int i;
   for (i=1;i<=5;i++)
   {
       if ((k-1)%5!=0||k<  5) return 0;
       k=(k-1)/5*4;
   }
   return 1;
}
int main()
{
   int ans=1;
   while (!can(ans)) ans++;
   printf("y = %d\n",ans);

   return 0;
}

5.求1000内的

#include<stdio.h>
#define m 1000
judgetrue(a);
main()
{
    int i;
    for(i=2;i<=m;i++)
    judgetrue(i);
}
judgetrue(a)
{
    int i,j,k=0;
    int s[100]={0};
    for(i=1;i<=a;i++)
        for(j=2;j<=a;j++)
        {
            if (i*j==a)
            {
            s[k]=i;
            k++;
            }
        }
    int s1=0;
    for(i=0;i<100;i++)
    {
        s1+=s[i];
    }
    if(s1==a)
    {
        printf("\n%5d\n",s1);
        for(i=0;i<20;i++)
        {
            if(s[i]!=0)
           {
               printf("%5d",s[i]);
           }
        }

    }
    else;
}

你可以发现:我每个程序都是在原程序的基础上进行修改而成的。

所以我把这些程序上传在了这个博客上,以备后事之需。

C语言练习一

1.

奥运参赛国出场次序:
输入奥运会参赛国国名,并按照字典序对其进行排序。
要求:参赛国数量不超过150个,每个国家的名字不超过9个字符。
提示:‘\0’占一个字符。

#include <string.h>
#include <stdio.h>
#define N 151
#define MAX_LEN 10
void SortString(char str[][MAX_LEN], int n);

int main()
{
    int i, n;
    char name[N][MAX_LEN];
    printf("How many countries?");
    scanf("%d",&n);
    getchar();
    printf("Input their names\n");

    for(i=0;i<n;i++)
        gets(name[i]);

    SortString(name, n);
    printf("Sorted results:\n");
    for(i=0;i<n;i++)
    {
        puts(name[i]);
    }
    return 0;

}

void SortString(char str[][MAX_LEN], int n)
{
    int i,j;
    char temp[MAX_LEN];

    for(i=0;i<n;i++)
    {
        for(j=i+1;j<n;j++)
        {
            if(strcmp(str[j],str[i])<0)
            {
                strcpy(temp,str[i]);
                strcpy(str[i],str[j]);
                strcpy(str[j],temp);
            }
        }
    }
}

2.

统计正整数中指定数字的个数
从键盘输入一个正整数number,求其中含有指定数字digit的个数。例如:从键盘输入正整数number=1222,若digit=2,则1223中含有 3个2,要求用函数实现。
函数原型为:int CountDigit(int number,int digit);

程序运行结果示例1:
Input m,n:
1222,2↙
3

程序运行结果示例2:
Input m,n:
1234,6↙
0

输入格式: "%d,%d"
输出格式:
输入提示信息:"Input m,n:\n"
输出格式:"%d\n"

#include<stdio.h>
int CountDigit(int number,int digit);
main()
{
    printf("Input m,n:\n");
    int m,n;
    scanf("%d,%d",&m,&n);
    printf("%d\n",CountDigit(m,n));
}
int CountDigit(int number,int digit)
{
    int c=0;
    while(number)
    {
        if(digit==number%10)
        {c++;
        number=number/10;
        }
    }
    return c;
}

3.冒泡程序

#include<stdio.h>
#define LEN 10
void bubble(int dat[], int length);
main( )
{
    int  data[LEN]={0}, i;
    for (i=0; i<= LEN-1; i++)
    {
        scanf("%d",&data[i]);
    }
    bubble(data,LEN);
    for(i=0; i<= LEN-1; i++)     
        {
            printf("%8d", data[i]);
        }
}
void bubble(int dat[], int length)
{
        int head, tail,round,i;
        int t;
        head = 0;
        tail = length - 1;
 
    for (round = head; round <= tail; round++)
        for (i = tail; i >= round+1; i--)
            if ( dat[i] < dat[i-1] )
            {
                t=dat[i];             
                dat[i]=dat[i-1];
                dat[i-1]=t;
            }
}

4.实验题

编写程序统计从键盘输入的一行文本中各个字母的个数。
输入以回车键结束。
不区分大小写,大写字母与相应的小写字母按照同一个字母看待。
要求输出按照各个字母出现的个数从大到小进行排序,出现的个数相同的,按照字母在字母表中的先后顺序进行排序。
***输入格式:调用getchar()函数依次输入每个字符
***输出格式:"%c(%c):%d\n"
例如输入以下文本:
Hello World
程序将输出:
L(l):3
O(o):2
D(d):1
E(e):1
H(h):1
R(r):1
W(w):1
A(a):0
B(b):0
C(c):0
F(f):0
G(g):0
I(i):0
J(j):0
K(k):0
M(m):0
N(n):0
P(p):0
Q(q):0
S(s):0
T(t):0
U(u):0
V(v):0
X(x):0
Y(y):0
Z(z):0

#include <stdio.h>
#include<stdlib.h>
void bubble_sort(int a[], int c[],int n);
int main(void)
{int i;
int c[27]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
 char j;
 char a;                                       
 int b[26]={0};                      
 int count[26]={0};
 while ((a = getchar()) != '\n')     
   {
   for (j='A';j<='Z';++j)               
       {
           if (a == j || a == j+32)
           {
               b[j-'A']++;count[j-'A']++;
           }
   
       }
   }
   bubble_sort(b,c,26);
   for (i=0;i<26;++i)
   {
        printf("%c(%c):%d\n",c[i]-32,c[i],b[i]);
           
   }
}
    
void bubble_sort(int a[],int c[], int n)
{
    int i, j, temp;
    for (j = 0; j < n - 1; j++)
        for (i = 0; i < n - 1 - j; i++)
        {
            if(a[i] < a[i + 1])
            {
                temp = a[i];
                a[i] = a[i + 1];
                a[i + 1] = temp;
                temp = c[i];
                c[i] = c[i + 1];
                c[i + 1] = temp;
            }
        }
}

这道题是我做过后觉得比较难的,可能算法并不是很简便,如果各位大神有什么好的方法请一定告诉我。