输出小技巧
- 对printf的输出格式,%后面节的数字表示输出的位数
- %8d表示输出8位,不足的左边用空格补齐
- %-8d表示输出8位,不足的右边用空格补齐
因为看了书上ls的输出,突然不记得这个表示的意思了,所以查了一下书,还是没有把基础的东西理解透彻,要好好反思一下
Linux下如何通过UID和GID获得用户名和组名
getpwuid
通过用户的uid查找passwd,返回一个空指针并设置errno的值,用户可以根据perror函数查看出错的信息
原型:
#include<sys/types.h> #include<pwd.h> struct passwd *getpwuid(uid_t uid);
struct passwd { char *pw_name;//user name char *pw_passwd;//user passwd uid_t pw_uid;//user id gid_t pw_gid;//group id char *pw_gecos;//user real name char *pw_dir;//home directory char *pw_shell;//shell program(使用的shell) }
getgrgid
作用:通过gid找到该组的相关信息,并以group结构体返回其信息
原型:
#include<grp.h> #include<sys/types.h> struct group *getgrpid(gid_t gid);
struct group { char *gr_name;//组名 char *gr_passwd;//组密码 gid_t gr_gid;//组识别码 char **gr_mem;//组成员账号 }
在遇到ls -l中要输出用户名和组名,然后就不知道该怎么办了,看了书上知道有这两个函数,所以总结在这里
关于时间的函数
- 结构体 struct tm的定义
struct tm
{
int tm_sec;
int tm_min;
int tm_hour;
int tm_mday;//一月中的第n天
int tm_mon;
int tm_year;//自1900年起的年
int tm_wday;//一周中的第n天
int tm_yday;//一年中的第n天
int tm_isdst;//夏令时标识符
const char *tm_zone;//当时时区的名字
}
time.h的定义
头文件定义了4个变量的类型,两个宏
4个变量
size_t:无符号整形数
- clock_t:一个适合存储处理器时间的类型,类型为unsigned long
- time_t:是和存储日历时间类型
struct tm:用来保存时间和日期的结构
两个宏
NULL:这个宏是一个空指针常量的值
CLOCKC_PER_SEC:每秒的处理器时钟的个数,用于将clock()函数的结果转化为疫苗为单位的量。具体值与操作系统有关,通常为1000
time
原型:
time_t time(time_t *timer);
timer=NULL得到的是当前日历的时间
timer=时间数时用于设置日历时间
功能:得到当前日历时间或设置日历时间
eg:
#include<stdio.h> #include<time.h> int main(void) { time_t seconds; seconds=time(NULL); printf("自1970-01-01起的小时数:%d\n",seconds/3600); }
ctime
原型
char *ctime(const time_t *timer);
功能:将日历时间参数timer转换成一个表示本地时间的字符串
返回:返回格式:星期,月,日,小时:分:秒,年
timer由time获得
eg:
#include<stdio.h> #include<time.h> int main(void) { time_t t; time(&t); printf("%s\n",ctime(&t)); }
忘记在书的哪个部分看到了这个函数,就百度了一下,觉得还是很实用,这里没有列全这里面的函数,只是列举了比较常见的。
getpid和getppid
getpid:返回当前进程标识
getppid:返回父进程标识
#include<sys/types.h> #include<unistd.h> pid_t getpid(void); pid_t getppid(void);
close-on-exec标志位
- 意义:(方便我们关闭无用的文件描述符)
- close-on-exec 字面意思是:执行时关闭。进程中每个打开的描述符都有一个执行时关闭的标志,如果设置此标志,则在执行exec时关闭该描述符。
- 父fork出一个子进程,子进程是父进程的副本,获得父进程的数据空间,堆和栈的副本,淡然包括父进程打开的文件描述符,fork之后,我们会调用exec执行另一个程序,此时会用全新的程序替换子进程的正文数据,堆和栈等。此时保存的文件描述符变量就不存在了,我们就无法关闭无用的文件描述符了。所以通常我们会在fork子进程后,在子进程中直接close掉无用的文件描述符。
因为在fcntl中遇到了这个问题,所以上网搜了一下关于这个的解释。
—LINE—,—FILE—,#LINE,—func—
LINE :用来指示本行语句所在的源文件的文件名
- eg:
#include<stdio.h> int main(void) { printf("%s\n",__LINE__); }
结果为a.c
—LINE—:用来表示本行语句在源文件中的位置信息
- eg:
#include<stdio.h> int main(void) { printf("%d\n",__LINE__); }
结果为:6
line:重新设定—LINE—的值
- eg:
#include<stdio.h> #line 20; int main(void) { printf("%d\n",__LINE__); printf("%d\n",__LINE__); }
结果:23
24
—func —:指所在的函数
—TIME:时间
—FUNCTION—:函数名
在遇见—LINE—时还不知道表示的什么意思,突然发现其实c语言挺喜欢定义宏的,觉得还不错,挺有意思的这几个宏
stdout,stderr
stdout:输出方式是行缓冲,输出的字符会先存放在缓冲区,等按下回车的时候才进行实际的I/O操作
stderr:不带缓冲的
之前不知道这些东西,以后多多了解总结ba
#### 单链表中判断是否有环
在讲座中学长提出了这个问题,觉得挺有意思的,不过ta很快说了答案。。。。。,如果让我想的话,其实也想不出来。。。
把环看做操场,两位选手在操场上赛跑,一个v快,一个慢,如果是马拉松,就不会相遇,如果是圈,一定会相遇的!