上一周的一些笔记

来源:互联网 发布:linux 启动apache服务 编辑:程序博客网 时间:2024/05/16 06:24

 2009-11-8:
看了尚观的10.avi和11.avi
安装了Ubuntu 9.10
看了shell的前两章!
2009-11-9:
看了尚观的12.avi和13.avi
2009-11-10:
7:10~8:10看了尚观的14.avi
vim的使用
编辑模式:
i在当前位置插入
a在当前位置的下一个字符处插入
I在行开始出插入
A在行末开始插入
o在当前行的下一行插入
O在当前行的上一行插入
u:undo
r:replace
s:删除一个字符插入
S:删除本行的内容在本行出开始插入
$:到本行末尾
G:到文章最末尾
10G:到第十行
dd:删除一行
3dd:删除三行
yy:复制一行
3yy:复制三行
p:粘贴
命令模式:
set nu:显示行号
:20  到第二十行
想每次启动vim是自动显示行号,可以vi ~/.vimrc这个文件的末尾加上set nu命令
:w aaa.txt 是把当前文件中另存为aaa.txt
如果想把当前内容追加到aaa.txt中,用  :w >> aaa.txt
把1到5行追加到aaa.txt中,则是 :1,5 w >> aaa.txt
读一个文件到当前位置,是 :r aaa.txt
想把文件恢复到最初状态,则是:e!
:1,$s/nologin/bash/g不询问把文件中的nologin改成bash
:1,$s/nologin/bash/c询问把文件中的nologin改成bash
vim -o a.txt b.txt 在一屏幕中垂直显示这两个文件
vim -o a.txt b.txt 在一屏幕中水平显示这两个文件
:sh 在vi文件时返回命令行,用完后esc回到编辑中
:!ls执行ls命令
8:45~9:20 15.avi和shell第五章
输入输出重定向是针对过滤器的
> 把目标文件清空,然后把内容写入此文件,若没有此文件,则新建一个。
>> 追加到文件末尾
标准输入是文件描述符0、标准输出是文件描述符1、标准错误是文件描述符2
command 1> test.txt 把标准输出重定向到test.txt
command > test.txt 2>&1 把标准输出和标准错误重定向到test.txt
command 2 > test.txt 把标准错误重定向到test.txt
command >> test.txt 2>&2 把标准输出和标准错误追加到test.txt末尾

9:30~ 10:00shell的第三四章:后台执行命令
分< >时< >日< >月< >星期< >要运行的命令
其中< >表示空格。
C r o n t a b文件的一个条目是从左边读起的,第一列是分,最后一列是要运行的命令,它位
于星期的后面。
在这些域中,可以用横杠-来表示一个时间范围,例如你希望星期一至星期五运行某个作
业,那么可以在星期域使用1 - 5来表示。还可以在这些域中使用逗号“,”,例如你希望星期一
和星期四运行某个作业,只需要使用1 , 4来表示。可以用星号*来表示连续的时间段。如果你
对某个表示时间的域没有特别的限定,也应该在该域填入*。该文件的每一个条目必须含有5
个时间域,而且每个域之间要用空格分隔。该文件中所有的注释行要在行首用#来表示
比如我想在每个月的5,15,25的21:35分执行/apps/bin/cleanup.sh
35 21 5,15,25 * * /apps/bin/cleanup.sh
又如表示每周六、周日的1 : 1 0运行一个f i n d命令
10 1 * * 6,0 /bin/find -name "core" -exec rm {} /;
在每天1 8 : 0 0至2 3 : 0 0之间每隔3 0分钟运行/ a p p s / b i n目录下的d b c h e c k . s h
0,30 18-23 * * * /apps/bin/dbcheck.sh
又如每星期六的11 : 0 0 p m运行/ a p p s / b i n目录下的q t r e n d . s h。
0 23 * * 6 /apps/bin/qurend.sh
要由用户来给出脚本的绝对路径,设置相应的环境变量
11:00~12:00 看零基础学C的1~10章
do
{

}while(express);//要注意这后面有个分号
break在循环中试破茧而出,而continue是baby once more,那goto则是随心所欲
函数是先定义在调用
函数定义是列表中的参数称为形参,是剧本角色,而函数调用时传递进来的参数称为实参,是演员,函数执行的过程就是演戏的过程。
模块化编程的基本思想:通过自顶向下,逐步求精,单入口,单出口,高内聚,低耦合

2009-11-11 19:00~20:30
16.avi:linux系统状态检测及进程控制
眼睛是心灵的窗户,/proc是内核的窗户。
cat /etc/hosts 或者hostname 得到主机名
想永久更改主机名:vi /etc/sysconfig/network的文件
uname -a 显示当前平台信息
last 显示谁登录过 就是去/etc/log/wtmp
lastlog 看每个人登录系统的信息
du -sh /目录 看此目录的大小
系统日志 /var/log
/var/log/messages 所有信息
安全日志 /etc/log/sceure 还有/etc/log/wtmp是安全的加密日志,记录用户登录事件
/var/log/maillog 邮件日志
/var/log/xferlog ftp日志
/var/log/cron 记录守护进程派生子进程
/var/log/bootlog boot日志
/var/log/dmesg 内核相关日志
/var/log/syslog 记录警告信息
进程间通过IPC通信
top查看所有的进程信息,每个进程都占有独立的空间
kill -l 显示各个信号的意义。15号信号和9号信号都是杀死进程。15号是的,9号是强制杀死。
kill 1234他发送的是15号信号,pid为1234的进程自己去相应然后自杀。如果他屏蔽掉了15号信号不想死,那就用/
kill -9 1234用这把大刀过去哐的一刀直接砍死
进程间通信的一种方式:信号
ps -ef
ps ef
ps auxf 。a是显示all,u是显示userid,x是现实后台进程,f是显示父进程
skill -9 prs/2
pkill -u sherk
pkill比skill更加精确
20:30~20:55
数据结构1
数据结构:个体 + 个体间的关系
算法:对存储数据的操作
21:17~10:10
17.avi了解进程
top 当此指令列出所有进程后的相关参数和操作意义
?或者 h 是寻求帮助的意思
M 内存信息
k 杀死进程
n 设置显示的最大任务数目
< 下一页 > 上一页
q退出,反正不知道的命令就去help
ps tree以树形的方式显示进程
-20~+19.-20的优先级是最高的。在top的命令中可以使用r命令来调整相应pid的优先级
killall pname
killall -9 pname
skill shrek
skill -9 shrek
skill -9 tty1
pkill -u shrek
renice -n pid 这里的n就是多少优先级,比如renice -1 1234就是把pid为1234的进程的优先级改为1
系统通过进程来完成工作
每一个进程都有一个独立的进程号,系统通过调用进程号来调度操控进程
系统的原始进程为init,init的pid总是1
一个进程可以创建另一个进程,出来init以外,所有的进程都有父进程
控制台的前台后台
vi & 一启动就在后台运行
jobs 查看后台任务
bg %1 把第一个任务丢到后台
fg %1  把地一个任务丢到前台
ctrl + z 把当前任务丢到后台并暂停此任务
场景:

如果只是临时有一个命令需要长时间运行,什么方法能最简便的保证它在后台稳定运行呢?

解决方法:

我们知道,当用户注销(logout)或者网络断开时,终端会收到 HUP(hangup)信号从而关闭其所有子进程。因此,我们的解决办法就有两种途径:要么让进程忽略 HUP 信号,要么让进程运行在新的会话里从而成为不属于此终端的子进程。

1. nohup
nohup 无疑是我们首先想到的办法。顾名思义,nohup 的用途就是让提交的命令忽略 hangup 信号。
nohup 的使用是十分方便的,只需在要处理的命令前加上 nohup 即可,标准输出和标准错误缺省会被重定向到 nohup.out 文件中。一般我们可在结尾加上"&"来将命令同时放入后台运行.
nohup 示例
[root@pvcent107 ~]# nohup ping
www.ibm.com &
[1] 3059
nohup: appending output to `nohup.out'
[root@pvcent107 ~]# ps -ef |grep 3059
root      3059   984  0 21:06 pts/3    00:00:00 ping
www.ibm.com
root      3067   984  0 21:06 pts/3    00:00:00 grep 3059
[root@pvcent107 ~]# 

2。setsid
nohup 无疑能通过忽略 HUP 信号来使我们的进程避免中途被中断,但如果我们换个角度思考,如果我们的进程不属于接受 HUP 信号的终端的子进程,那么自然也就不会受到 HUP 信号的影响了。setsid 就能帮助我们做到这一点。
setsid 示例           
[root@pvcent107 ~]# setsid ping
www.ibm.com
[root@pvcent107 ~]# ps -ef |grep www.ibm.com
root     31094     1  0 07:28 ?        00:00:00 ping www.ibm.com
root     31102 29217  0 07:29 pts/4    00:00:00 grep www.ibm.com
[root@pvcent107 ~]#  
值得注意的是,上例中我们的进程 ID(PID)为31094,而它的父 ID(PPID)为1(即为 init 进程 ID),并不是当前终端的进程 ID。

3。&
这里还有一个关于 subshell 的小技巧。我们知道,将一个或多个命名包含在“()”中就能让这些命令在子 shell 中运行中,从而扩展出很多有趣的功能,
当我们将"&"也放入“()”内之后,我们就会发现所提交的作业并不在作业列表中,也就是说,是无法通过jobs来查看的。让我们来看看为什么这样就能躲过 HUP 信号的影响吧。
subshell 示例             
[root@pvcent107 ~]# (ping
www.ibm.com &)
[root@pvcent107 ~]# ps -ef |grep
www.ibm.com
root     16270     1  0 14:13 pts/4    00:00:00 ping www.ibm.com
root     16278 15362  0 14:13 pts/4    00:00:00 grep www.ibm.com
[root@pvcent107 ~]#  
从上例中可以看出,新提交的进程的父 ID(PPID)为1(init 进程的 PID),并不是当前终端的进程 ID。因此并不属于当前终端的子进程,从而也就不会受到当前终端的 HUP 信号的影响了。

disown
场景:
我们已经知道,如果事先在命令前加上 nohup 或者 setsid 就可以避免 HUP 信号的影响。但是如果我们未加任何处理就已经提交了命令,该如何补救才能让它避免 HUP 信号的影响呢?

解决方法:
这时想加 nohup 或者 setsid 已经为时已晚,只能通过作业调度和 disown 来解决这个问题了。
我们可以用如下方式来达成我们的目的。
用disown -h jobspec 来使某个作业忽略HUP信号。
用disown -ah 来使所有的作业都忽略HUP信号。
用disown -rh 来使正在运行的作业忽略HUP信号。

需要注意的是,当使用过 disown 之后,会将把目标作业从作业列表中移除,我们将不能再使用jobs来查看它,但是依然能够用ps -ef查找到它。

disown 示例1(如果提交命令时已经用“&”将命令放入后台运行,则可以直接使用“disown”)             
[root@pvcent107 build]# cp -r testLargeFile largeFile &
[1] 4825
[root@pvcent107 build]# jobs
[1]+  Running                 cp -i -r testLargeFile largeFile &
[root@pvcent107 build]# disown -h %1
[root@pvcent107 build]# ps -ef |grep largeFile
root      4825   968  1 09:46 pts/4    00:00:00 cp -i -r testLargeFile largeFile
root      4853   968  0 09:46 pts/4    00:00:00 grep largeFile
[root@pvcent107 build]# logout  
disown 示例2(如果提交命令时未使用“&”将命令放入后台运行,可使用 CTRL-z 和“bg”将其放入后台,再使用“disown”)
               
[root@pvcent107 build]# cp -r testLargeFile largeFile2

[1]+  Stopped                 cp -i -r testLargeFile largeFile2
[root@pvcent107 build]# bg %1
[1]+ cp -i -r testLargeFile largeFile2 &
[root@pvcent107 build]# jobs
[1]+  Running                 cp -i -r testLargeFile largeFile2 &
[root@pvcent107 build]# disown -h %1
[root@pvcent107 build]# ps -ef |grep largeFile2
root      5790  5577  1 10:04 pts/3    00:00:00 cp -i -r testLargeFile largeFile2
root      5824  5577  0 10:05 pts/3    00:00:00 grep largeFile2
[root@pvcent107 build]#  
 
总结
现在几种方法已经介绍完毕,我们可以根据不同的场景来选择不同的方案。nohup/setsid 无疑是临时需要时最方便的方法,disown 能帮助我们来事后补救当前已经在运行了的作业.
11:10~12:20
郝斌C语言1~6.swf
机器语言直接和硬件接触操作
汇编语言
C语言是高级语言中执行速度最快的
UNIX是真正意义上的第一个操作系统,是用B语言写的
C语言优点:代码量小,执行速度快,功能强大。缺点:危险性高,开发周期长,可移植性差(针对java而言)====>>>>>>>>最猛的指针用好了是好利器,用不好就挂了
C语言的用途:(1)写操作系统:windows、linux、Unix(2)驱动程序开发(3)数据库(4)嵌入式开发(5)游戏开发
内存泄露:就是不听的吃光内存
int main()
{
 while(1)
 {
  int *p = (int *) malloc(10000);
 }
 return 0;
}

2009-11-12 19:00~20:00
18.avi
shell 脚本编程详解
脚本语言有很多,比如shell、php、python
shell脚本就是shell script
ls -l | grep ^d | wc -l 列出文件夹的个数
UNIX Like系统的原则有一条:UNIX系统的程序都比较短小,避免交互
在完成复杂任务是需要把短小命令组合起来使用,如何组合?用shell组合
系统是有shell脚本串起来的
#!/bin/sh 这是shell脚本的标志,告诉系统是什么类型的shell
第一个字符时#,表示这是一个bash脚本
第一个字符是#,第二个字符不是!,表示这是一个Cshell脚本
第一个字符是#,第二个字符是!,表示这是一个shell脚本
shell中正则表达式
和shell脚本进行交互
$1 ,$2表示第一,第二个参数
$?上次命令执行的结果
$#所输入的总参数个数
$$进程ID
查找文件在哪儿?which filename
可以用printf来代替echo命令
编辑完shell脚本后,用chmod a+x filename.sh来使得该文件能被执行,也可以用bash filename.sh这样来执行此shell脚本

20:40~21:40
19.avi
'' 把里面的特殊字符给取消掉, “”只是忽略空格
(1) true or false的判断 [ abc ] 返回的结果用$?来查看前一个命令的结果
[ "$USER" = "yangxiao" ]  如果当前用户是yangxiao,则返回0,表示真
[ "$USER" = root ] && echo hello root
[ -x /etc/passwd ] && echo "you can execute"
-x表示此文件是否可执行。-r 表示可读 -w表示可写 -f表示是否普通文件 -d 是否目录 -L 是否是连接文件 -b 是否是块设备 -c 是否是字符设备
[ -f /usr/sbin/httpd ] && echo please install httpd with --force option && exit
一个if的例子
#!/bin/sh
read yourname
if [ $yourname = yangxiao ]
 then echo hello yangxiao
 elif [ $yourname = root ]
 then echo hello root
 else echo 'get out here'
fi
调试技术:调试脚本的命令 bash -vx filename.sh,这样话,他会把当中的变量都替换过来。并输出给你看,这非常有用

又如
#!/bin/bash
read yourname
case $yourname in
 yangxiao)
  echo hello yangxiao
  echo nice to meet you
  ;;
 root)
  echo hello root
  echo I miss you so much
  ;;
 *)
  echo get out here
  ;;
esac

21:40~22:20
下面是for循环的例子
#!/bin/sh

name = "`pgrep httpd`"
[ -z "$name" ] && echo 'httpd is not running!' && exit
for i in $name
 do
  kill -9 $i
  done

echo httpd is killed
这个脚本时杀死apache 进程

再来一个每隔一秒打印一个数字
#!/bin/sh
for i in `seq 1 100`
do
 echo -n "$i "
 sleep 1
done

while循环的
count = 0
while [ $count -lt 100 ] //这个条件为true是循环
 do
  count=$[$count+1]
  echo -n "$count "
 done

until循环
count=0
until [ $count -gt 100 ]  //这个条件为false是循环

 do
  count=$[$count+1]
  echo -n "$count "
 done

while循环的运用
#!/bin/sh
while true
do
 read val
 if [ "$val" = "ddd" ]
 then break
 fi
done

下面是函数,
unset function_name。就是取消此函数
unset varible_name。就是取消此变量名

sed awk的内容很高级和进阶

23:18~12:10
郝斌C语言 7.swf~11.swf
怎样学C语言?
途径:多思考,和多上机
目标:能看懂程序,能调试程序。
读什么样的书?
(1)谭浩强《C语言程序设计》
(2)《C Primer Plus》人民邮电-->系统的学语法
(3)《C和指针》-->专门的讲指针
(4)《C专家编程》--->高手的必看
(5)《C缺陷与陷阱》--->高手的必看
学习目标:
掌握简单算法、能看懂程序,能调试程序。
C语言有32个关键字
写一个求一元二次方程ax^2 + bx + c =0的解
(1)获得a、b、c的值
(2)通过公式(-b +- sqrt(B*b -4*a*c)
源代码:
#include <stdio.h>
#include <math.h>

int main()
{
 //把三个系数保存到计算机中
 int a = 1;
 int b = 6;
 int c = 3;
 
 //定义delta存放的是b * b-4 * a * c
 double delta ;
 
 //定义一元二次方程的解
 double x1;
 double x2;
 
 delta = b * b - 4 * a * c;
 
 if(delta > 0)
 {
   x1 = (sqrt(delta) - b) / (2 * a);
   x2 = (-sqrt(delta) - b) / (2 * a);
   printf("该一元二次方程有两个解,x1 = %f,x2 = %f",x1,x2);
 }
 else if (delta == 0 )
 {
  x1 = x2 = (-b) / (2 * a);
  printf("该一元二次方程有唯一解,x1 = x2 = %f",x1);
 }
 else
 {
  printf("该一元二次方程无解");
 }
 return 0;
}

20091114 21:00~23:43
郝斌C语言12.swf~22.swf
C语言编程预备知识
1.cpu 内存条 硬盘 显卡 主板 显示器之间的关系
 比如现在我想播放一个电影,而这个电影是存放在硬盘上的。那我们双击这个电影(双击这是操作系统提供的程序)。这是cpu就会把这个硬盘上的数据给读入内存中,因为CPU不能直接访问内存。读进去之后CPU就会对这些数据进行处理:那么如果是图像的,就把这些图像给输送到显示器上;如果是声音就会把这些数据送到声卡然后发出声来。主板是把cpu、内存条、硬盘、显卡等串接起来的器件。
2.HelloWorld程序如何运行起来的
 (1)首先是编译其次是链接然后生成.exe文件
 (2)点击运行此.exe文件请求操作系统来执行此.exe文件,然后是操作系统来调用CPU来运行此程序
3.什么是数据类型
 (1)基本数据类型
  整数
   整型 --> int 占4个字节
   短整型 --> short int 占2个字节
   长整型 --> long int 占8个字节
  浮点数(实数)
   单精度浮点数 --> float 占4个字节
   双精度浮点数 --> double 占8个字节
  字符 --> 占用1个字节
 (2)复合数据类型
  结构体
  枚举
  共用体
4.什么是变量
 int i;//把i和内存中的某个空闲单元(没有被其他程序所占用)的地址关联起来,以后用i的时候,就是用内存中那个空闲的单元
 i = 3;//3最终是放在内存中了,程序终止后3所占用的空间给释放掉了
 变量的本质就是内存中一段存储空间
5.cpu 内存条 Vc++6.0 操作系统之间的关系
 VC发出请求,操作系统给其分派内存空间,VC把各个变量和操作系统里面对应的内存空间的地址产生关联。最终整个程序就能运行起来。
6.变量为什么必须初始化(非常非常的重要)
 内存条是硬件设备,其里面的数据要么是0要么是1要么是0、1的组合。而我们的这个变量所关联的空间也许之前被其他程序使用过,如果之前没有被释放,没有被reset的话。如果VC发现这个空间是垃圾数据。就给其放一个很大很大的负数,提醒你这个变量未初始化。
 所谓初始化就是赋值的意思
 软件运行与内存关系:
  (1)软件运行前需要向操作系统申请存储空间,在内存空间足够时,操作系统将分配一段内存空间并将外存中软件拷贝一根存入该内存空间中。并启动该软       件运行!
  (2)在软件运行期间,该软件所占内存空间不再分配给其他软件
  (3)当软件运行完毕后,操作系统将回收该内存空间(注意:操作系统并不清空该内存中遗留下来的数据)。一边再次分配给其他软件使用
  综上所述:
   一个软件所分配到的空间中极可能存在着以前其他软件使用过的残留数据,这些数据被称为垃圾数据。所以通常情况下我们为一个变量,为一个数   组,分配好存储空间之后都要对该内存空间初始化
7.如何定义变量
 数据类型 变量名 要赋的值
 等价于:
 数据类型 变量名
 变量名 = 要赋的值
 举例子:
  int i = 3; ---> int ;   i = 3;
  int i , j; ---> int i; int j;
  int i , j = 3 ; ---> int i; int j; j = 3;
8.什么是进制
 进制就是逢几进一
 基数的概念:十进制 ,基数为 --> 0,1,2,3,4,5,6,7,8,9
 其实各个进制之间只是表现形式不一样,其实这些数据在内存中的存储都是二进制的
 一般有二进制、八进制、十进制、十六进制
 还有一个很重要的知识点事进制之间的转换

20091115 19:30~20:00
郝斌C语言23.swf~25.swf
9.常量在C语言中是如何表示的
 整数:
  十进制就是传统的写法
  十六进制前用0x作为前缀
  八进制用0作为前缀
 浮点数:
  传统的写法
   float x = 3.2 //传统
  科学计数法
   float x = 3.2e3 //x的值是3200
   double x = 123.45e-2; //x的值是1.2345.所以e表示的就是10
  字符
   单个字符用单引号括起来-->'A'
   字符串用双引号括起来 --> "abc"
    "a"正确。因为"a"代表了'a' '/0'的组合 
10.常量是以什么样的二进制代码存储的
 编码、补码很重要
 所有的数据都是以二进制的方式存储的
 整数是以补码的形式转化为二进制代码存储在计数机中的
 实数是以IEEE754标准转化为二进制代码存储在计数机中的
 字符的本质也是与整数的存储形式相同
 'A'--->(找到其对应的ASCII码)65-->再把65对应的补码的二进制代码给存储到计算机中。
 什么是ASCII码?就是把字符和其对应的数值对应起来的一种规则

20091115 20:00~22:30
郝斌C语言26.swf~25.swf
11.代码规范化
 写注释的一个例子
  /*
  * 时间:2009年11月15日
  * 功能:要实现的什么功能
  *--------输出结果是-----------------
  *--------输出结果结束---------------
  * 目的:是
  * 总结:
  */
 林瑞 《高质量C/C++编程》
 规范化只是一个准则,你可以不遵守,但是这是一种规范。遵守了可以很好的使用代码和让别人很清楚的看懂代码
 注释部分最终占整个项目代码的1/3
  成对法则
   if (abc(cc))
   {
    xxx;
   }
  缩进的使用
  换行的使用
  空格的使用:这一点很重要。比如if (expression) 这个表达式的if和括号之间有空格
12.什么是字节
 字节就是存储数据的单位(1个字节 = 8 bit)。并且方式硬件所能访问的最小单位。
 硬盘上的数据是要想到内存中才能被CPU说处理,cpu只能处理内存中的数据
 1字节 =  1024字节
 1K = 1024字节
 1M = 1024k
 1G = 1024M
 比如数据1.5G=1.5 * 1024 * 1024 * 1024 * 8 bit
13.不同类型数据之间相互复制的问题
 int i = 45;
 long j = 102345;
 i = j;//可能会丢失精度(i刚好能装下时,就不会丢失精度。如果存储不下就会丢失)
 printf("%ld %d/n",i,j);//ld就是long double类型的
 C中最牛的就是补码和指针
14.什么是ASCII
 这块的知识点是非常的重要
 # include <stdio.h>
 int main()
 {
  char ch = 'b';
  pritnf("%d/n",ch);//b是以98的二进制方式存储的,所以可以以数字方式输出
  return 0;
 }
 ASCII码不是一个值,而是一种规定,ASCII规定了不同的字符使用哪个整数值去表示
 例如ASCII吗规定了 :
  'A' --> 65
  'B' --> 66
  'a' --> 97
  'b' --> 98
  '0' --> 48//这是字符0的ASCII码
 所以引出了15字符的本质上与整数的存储方式相同
15.字符的本质上与整数的存储方式相同

基本的输入和输出函数的用法
 printf()-->将变量的内容输出到显示器上
 四种用法:
  (1).printf("字符串/n");
  (2).pritnf("输出控制符",输出参数);--> int i = 10;pritnf("%d", i );//为什么需要控制符?答:i的值在内存中放的是二进制代码,所以要用控制       符来控制以什么样的方式输出。
  (3).printf("输出控制符1 输出控制符2",输出参数1,输出参数2); --> int i = 3 ; int j = 4; pritnf("%d %d/n", i ,j);
  (4).printf("输出控制符 非输出控制符", 输出参数);
   输出控制符包含如下
    %d -->十进制 int
    %ld long int
    %c  -->字符形式 char
    %f float
    %lf  double
    %x  --> 以十六进制  int 或者long int或者short int -->int x = 47; printf("%x/n",x);  -->2f
    %X  --> 字符以大写形式输出 -->int x = 47; printf("%X/n",x);  -->2F
    %#X  --> 前面有0x的标志,且后面的字符是以大写形式输出的。这种形式激励推荐
      -->int x = 47; printf("%#X/n",x);  -->0x2F
    %#x --> 前面有0x的标志,且后面的字符是以小写形式输出的
      -->int x = 47; printf("%#x/n",x);  -->0x2f
    %s  --> 字符串
  为什么需要输出控制符
   (1).01组成的代码可以表示数据也可以表示指令
   (2).如国01组成代码表示的是数据的话,那么同样01代码组合以不同的格式输出就会有不同的显示结果
 scanf()