C语言函数大全--s 开头的函数(2)

总览

函数声明 函数功能
void setlinestyle( int linestyle, unsigned upattern, int thickness ); 设置当前绘图窗口的线条样式、线型模式和线条宽度
void *setmem(void *dest, size_t n, int c); 用于将指定内存区域的每个字节都设置为指定的值
int setmode(int fd, int mode); 它是 Windows 系统下的特定库函数,用于将指定文件的 I/O 模式设置为文本模式或二进制模式
void setpalette(int colornum, int color); 设置调色板的颜色
void setrgbpalette(int colornum, int red, int green, int blue); 用于设置当前绘图窗口的调色板中某个颜色的 RGB
void settextjustify(int horiz, int vert); 用于设置文本输出的对齐方式
void settextstyle(int font, int direction, int charsize); 用于设置当前文本输出的字体、方向和大小
void settime(struct time *timep); 设置当前系统时间
void setusercharsize(int multx, int dirx, int multy, int diry); 用于设置用户定义的字符大小
int setvbuf(FILE *stream, char *buf, int type, unsigned size); 用于设置文件流的缓冲方式
void setviewport(int left, int top, int right, int bottom, int clipflag); 用于设置绘图窗口的视口范围
void setvisualpage(int pagenum); 用于设置图形窗口中用户可见的页面
void setwritemode(int mode); 用于设置绘画操作的写入模式
void (*signal(int signum, void (*handler)(int)))(int); 用于设置指定信号的处理方式。当系统接收到某个信号时,会调用相应的信号处理函数来处理该信号。在调用 signal 函数时,需要指定要处理的信号以及相应的信号处理函数。
double sin(double x); 用于计算一个角度(以弧度为单位)的正弦值(double)
float sinf(float x); 用于计算一个角度(以弧度为单位)的正弦值(float)
long double sinl(long double x); 用于计算一个角度(以弧度为单位)的正弦值(long double)
void sincos(double x, double* sinVal, double* cosVal); 用于同时计算一个角度(以弧度为单位)的正弦值和余弦值
void sincosf(float x, float* sinVal, float* cosVal); 用于同时计算一个角度(以弧度为单位)的正弦值和余弦值
void sincosl(long double x, long double* sinVal, long double* cosVal); 用于同时计算一个角度(以弧度为单位)的正弦值和余弦值
double sinh(double x); 用于计算一个数的双曲正弦值
float sinhf(float x); 用于计算一个数的双曲正弦值
long double sinhl(long double x); 用于计算一个数的双曲正弦值

1. setlinestyle

1.1 函数说明

函数声明 函数功能
void setlinestyle( int linestyle, unsigned upattern, int thickness ); 设置当前绘图窗口的线条样式、线型模式和线条宽度

参数:

  • linestyle : 线条样式,取值范围为 0 到 4,不同的值对应着不同的线条样式,详见如下表格
  • upattern : 线型模式,它是一个 16 位的无符号整数,用二进制位表示线型模式,其中 1 表示绘制线条,0 表示空白。例如,如果 upattern 的值是 0x00FF,则表示绘制一段线条,然后空白一段,重复这个过程直到结束。如果 upattern 的值是 0x5555,则表示绘制一段虚线。
  • thickness : 线条宽度,取值范围为 1 到 10,表示线条的像素宽度
线条样式 描述
SOLID_LINE 0 实线
DOTTED_LINE 1 虚线
CENTER_LINE 2 点线
DASHED_LINE 3 长短线
USERBIT_LINE 4 双点线

1.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <graphics.h>
#include <string.h>

/* the names of the line styles supported */
char *lname[] = {
"SOLID_LINE",
"DOTTED_LINE",
"CENTER_LINE",
"DASHED_LINE",
"USERBIT_LINE"
};

int main(void)
{
int gdriver = DETECT, gmode;

int style, midx, midy, userpat;
char stylestr[40];

initgraph(&gdriver, &gmode, "");

midx = getmaxx() / 2;
midy = getmaxy() / 2;

userpat = 1;

for (style=SOLID_LINE; style<=USERBIT_LINE; style++)
{
setlinestyle(style, userpat, 1);

strcpy(stylestr, lname[style]);

line(0, 0, midx-10, midy);

rectangle(100, 100, getmaxx() - 100, getmaxy() - 100);

outtextxy(midx, midy, stylestr);

getch();
cleardevice();
}

closegraph();
return 0;
}

1.3 运行结果

2. setmem

2.1 函数说明

函数声明 函数功能
void *setmem(void *dest, size_t n, int c); 用于将指定内存区域的每个字节都设置为指定的值

参数:

  • dest : 要设置的内存区域的指针
  • n : 要设置的字节数
  • c : 要设置的值

·注意: setmem() 并不是标准 C 函数,而是 POSIX 标准库函数,因此可能并不被所有平台所支持。如果您的编译器或操作系统不支持 setmem() 函数,可以使用标准 C 库函数 memset() 来代替

2.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
char *str = (char *)malloc(10); // 分配 10 字节的内存空间

// 将 str 中的每个字节都设置为 'A'
setmem(str, 10, 'A');

printf("%s\n", str);

free(str);

return 0;
}

在上面的示例程序中,

  • 我们首先使用 malloc() 函数分配了 10 字节的内存空间,并将其赋值给指针变量 str。
  • 然后,我们使用 setmem() 函数将 str 指向的内存区域的每个字节都设置为 'A'
  • 最后,我们输出 str 的内容并使用 free() 函数释放了分配的内存空间。

3. setmode

3.1 函数说明

函数声明 函数功能
int setmode(int fd, int mode); 它是 Windows 系统下的特定库函数,用于将指定文件的 I/O 模式设置为文本模式或二进制模式

参数:

  • fd : 要设置模式的文件描述符,通常使用 fileno() 函数将文件指针转换为文件描述符
  • mode : 要设置的模式,它可以取以下两个值中的一个:
    • _O_BINARY:二进制模式
    • _O_TEXT:文本模式

注意:Windows 系统中,文本模式和二进制模式之间的区别在于换行符的处理方式。在文本模式下,Windows 将回车符(\r)和换行符(\n)组成的字符序列映射为单个换行符(\n),因此在读取文本文件时可以正确处理换行符。在二进制模式下,Windows 不对回车符和换行符做任何转换,因此在读取文本文件时可能会出现问题。

3.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
#include <fcntl.h>

int main()
{
int result;
result = setmode(fileno(stdin), O_TEXT);
if (result == -1)
perror("Mode not available\n");
else
printf("Mode successfully switched\n");
return 0;
}

在上面的示例程序中,我们首先使用 setmode() 函数将标准输入流的模式从二进制模式切换到文本模式;如果调用成功,则返回 0,否则返回 -1,并将错误信息存储在全局变量 errno 中。在程序中,我们使用 perror() 函数来输出错误信息。如果调用成功,则输出一条提示信息。

注意: setmode() 函数只适用于 Windows 系统下的 C/C++ 编程,并且不是标准库函数,因此在跨平台编程时应该避免使用它。在 Unix/Linux 系统下,也可以使用 fcntl() 函数来设置文件描述符的模式。

3.3 运行结果

4. setpalette

4.1 函数说明

函数声明 函数功能
void setpalette(int colornum, int color); 设置调色板的颜色

参数:

  • colornum : 要设置的调色板中的颜色数量
  • color : 是一个整数类型的值,用于表示调色板中的颜色。这个参数可以是一个 RGB 值,也可以是一个预定义颜色名称,例如 REDBLUE

4.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <graphics.h>

int main()
{
int gd = DETECT, gm;
initgraph(&gd, &gm, "");

// 将第 5 种颜色设置为红色
setpalette(5, RED);

// 绘制一条红色的直线
setcolor(5);
line(100, 100, 200, 100);

getch();
closegraph();
return 0;
}

4.3 运行结果

5. setrgbpalette

5.1 函数说明

函数声明 函数功能
void setrgbpalette(int colornum, int red, int green, int blue); 用于设置当前绘图窗口的调色板中某个颜色的 RGB

参数:

  • colornum : 要修改的颜色索引,取值范围为 0~255
  • red、green 和 blue 要设置的 RGB 值,取值范围为 0~255

5.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <graphics.h>

int main()
{
int gd = DETECT, gm;
initgraph(&gd, &gm, "");

setbkcolor(WHITE);
cleardevice();

// 将第 5 种颜色设置为蓝绿色
setrgbpalette(5, 0, 128, 128);

// 绘制一条蓝绿色的斜线
setcolor(5);
line(100, 100, 200, 200);

getch();
closegraph();
return 0;
}

在上述的这个示例程序中,

  • 我们首先使用 setbkcolor() 函数设置背景颜色为白色,然后清除原有屏幕使前面设置生效。
  • 接着我们使用 setrgbpalette() 函数将第 5 种颜色设置为蓝绿色,并使用 setcolor() 函数将绘图颜色设为索引值 5(即蓝绿色);
  • 最后使用 line() 函数绘制了一条斜线。

5.3 运行结果

6. settextjustify

6.1 函数说明

函数声明 函数功能
void settextjustify(int horiz, int vert); 用于设置文本输出的对齐方式

参数:

  • horiz : 水平对齐方式,可以取以下值:
    • LEFT_TEXT:左对齐
    • CENTER_TEXT:居中对齐
    • RIGHT_TEXT:右对齐
  • vert : 垂直对齐方式,可以取以下值:
    • TOP_TEXT:顶部对齐
    • CENTER_TEXT:居中对齐
    • BOTTOM_TEXT:底部对齐

6.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <graphics.h>

int main()
{
int gd = DETECT, gm;
initgraph(&gd, &gm, "");

// 设置文本输出的对齐方式为居中对齐
settextjustify(CENTER_TEXT, CENTER_TEXT);

// 输出一行居中对齐的文本
outtextxy(getmaxx() / 2, getmaxy() / 2, "Hello, world!");

getch();
closegraph();
return 0;
}

在上述的示例程序中,我们使用 settextjustify() 函数将文本输出的对齐方式设置为居中对齐,然后使用 outtextxy() 函数在窗口的中心输出一行文本。

注意: 在使用 settextjustify() 函数设置对齐方式时,必须指定正确的参数值,并且同时考虑水平和垂直方向的对齐方式,否则可能会导致文本输出位置错误。

6.3 运行结果

7. settextstyle

7.1 函数说明

函数声明 函数功能
void settextstyle(int font, int direction, int charsize); 用于设置当前文本输出的字体、方向和大小

参数:

  • font : 要使用的字体编号,可以取以下值:
    • DEFAULT_FONT:默认字体
    • TRIPLEX_FONT:粗体三线字体
    • SMALL_FONT:小号字体
    • SANS_SERIF_FONT:无衬线字体
    • GOTHIC_FONT:哥特式字体
    • SCRIPT_FONT:手写字体
  • direction : 文本输出的方向,可以取以下值:
    • HORIZ_DIR:水平方向(从左到右)
    • VERT_DIR:垂直方向(从下到上)
  • horiz : 水平对齐方式,可以取以下值:
    • DEFAULT_WIDTHDEFAULT_HEIGHT:默认大小
    • TRIPLEX_WIDTHTRIPLEX_HEIGHT:大号尺寸
    • SMALL_WIDTHSMALL_HEIGHT:小号尺寸

7.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <graphics.h>

int main()
{
int gd = DETECT, gm;
initgraph(&gd, &gm, "");

// 设置文本输出的字体、方向和大小
settextstyle(TRIPLEX_FONT, HORIZ_DIR, 4);

// 输出一行文本
outtextxy(100, 100, "Hello, world!");

getch();
closegraph();
return 0;
}

在上述的示例程序中,我们使用 settextstyle() 函数将文本输出的字体设置为粗体三线字体、方向设置为水平方向、大小设置为大号尺寸,然后使用 outtextxy() 函数在窗口的指定位置输出一行文本。

注意: 在使用 settextstyle() 函数设置文本样式时,必须指定正确的参数值,并且根据具体需求灵活选择字体、方向和大小,否则可能会导致文本输出不符合预期。

7.3 运行结果

8. settime

8.1 函数说明

函数声明 函数功能
void settime(struct time *timep); 设置当前系统时间
参数:
  • timep : 用于存储当前系统时间的结构体变量

8.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
#include <dos.h>

int main(void)
{
struct time t;

gettime(&t);
printf("The current minute is: %d\n", t.ti_min);
printf("The current hour is: %d\n", t.ti_hour);
printf("The current hundredth of a second is: %d\n", t.ti_hund);
printf("The current second is: %d\n", t.ti_sec);

t.ti_min++;
settime(&t);

return 0;
}

在上述的程序中,

  • 我们首先定义了一个 struct time 类型的变量 t,用于存储当前系统时间。然后使用 gettime() 函数获取当前时间,并将小时、分钟、秒和百分之一秒等信息存储到 t 变量的对应成员变量中。
  • 接着,程序使用 printf() 函数输出了当前的分钟数、小时数、百分之一秒数和秒数。这里使用了 %d 占位符来指定输出整数类型的值。
  • 最后,程序将 t 变量的分钟数加上了 1,然后使用 settime() 函数将修改后的时间写入系统时钟中。

注意 : 这个程序依赖于 DOS 系统提供的日期和时间相关函数,可能无法在其他操作系统或环境下运行。此外,直接修改系统时间可能会对计算机的正常运行产生影响,因此应该谨慎使用。
在现代的 Windows 操作系统中,DOS 环境已经被废弃,因此这个程序可能无法正常工作。如果要获取和修改当前系统时间,可以使用操作系统提供的相关 API 或系统调用接口实现。例如,在 Windows 平台上,可以使用 GetSystemTime()SetSystemTime() 等函数来获取和设置系统时间。

9. setusercharsize

9.1 函数说明

函数声明 函数功能
void setusercharsize(int multx, int dirx, int multy, int diry); 用于设置用户定义的字符大小

参数:

  • multx : 水平放大倍数,取值为正整数
  • dirx : 水平方向,取值为 1-1。当 dirx 的值为 1 时,字符不进行左右翻转;当 dirx 的值为 -1 时,字符进行左右翻转
  • multy : 垂直放大倍数,取值为正整数
  • diry : 垂直方向,取值为 1-1。当 diry 的值为 1 时,字符不进行上下翻转;当 diry 的值为 -1 时,字符进行上下翻转。

9.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <graphics.h>

int main()
{
int gd = DETECT, gm;
initgraph(&gd, &gm, "");

// 设置字符的大小为水平方向放大 2 倍、垂直方向放大 3 倍
setusercharsize(2, 1, 3, 1);

// 输出一行文本
outtextxy(100, 100, "Hello, world!");

getch();
closegraph();
return 0;
}

在上述这个示例程序中,我们使用 setusercharsize() 函数将当前字符的大小设置为水平方向放大 2 倍、垂直方向放大 3 倍,然后使用 outtextxy() 函数在窗口的指定位置输出一行文本。

注意: 在使用 setusercharsize() 函数设置字符大小时,必须指定正确的参数值,并且考虑到水平和垂直方向的缩放倍数,否则可能会导致字符输出不符合预期。

9.3 运行结果

10. setvbuf

10.1 函数说明

函数声明 函数功能
int setvbuf(FILE *stream, char *buf, int type, unsigned size); 用于设置文件流的缓冲方式

参数:

  • stream : 要设置缓冲方式的文件指针,可以是标准输入流(stdin)、标准输出流(stdout)或标准错误流(stderr),也可以是通过 fopen() 函数打开的文件指针
  • buf : 缓冲区指针,可以是一个已经分配好的缓冲区,也可以是 NULL。如果 buf 参数为 NULL,则 setvbuf() 函数将自动为文件流分配一块缓冲区
  • type : 缓冲类型,可以取以下值:
    • _IONBF:不使用缓冲区,直接从或向设备读写数据
    • _IOLBF:行缓冲,每行数据结束后刷新缓冲区
    • _IOFBF:全缓冲,填满缓冲区后才进行读写操作
  • size: 缓冲区大小,如果 buf 参数不为 NULL,则 size 参数指定了缓冲区大小;如果 buf 参数为 NULL,则 size 参数指定了系统为缓冲区分配的大小。size 参数只对全缓冲方式有效,行缓冲和无缓存方式忽略该参数

10.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdio.h>

int main(void)
{
FILE *input, *output;
char bufr[512];

input = fopen("file.in", "r+b");
output = fopen("file.out", "w");

if (setvbuf(input, bufr, _IOFBF, 512) != 0)
printf("failed to set up buffer for input file\n");
else
printf("buffer set up for input file\n");

if (setvbuf(output, NULL, _IOLBF, 132) != 0)
printf("failed to set up buffer for output file\n");
else
printf("buffer set up for output file\n");

fclose(input);
fclose(output);
return 0;
}

在上述的示例程序中,

  • 我们首先定义了两个文件指针变量 inputoutput,分别表示输入文件和输出文件。
  • 然后调用 fopen() 函数打开输入文件和输出文件,并将返回的文件指针保存到对应的变量中。
  • 接着,程序使用 setvbuf() 函数分别为输入文件和输出文件设置缓冲方式。对于输入文件,使用 _IOFBF 缓冲类型和大小为 512 字节的缓冲区;对于输出文件,使用 _IOLBF 缓冲类型和大小为 132 字节的缓冲区(此处 bufr 缓冲区为空指针)。在设置完缓冲方式后,程序根据 setvbuf() 函数的返回值判断是否设置成功,如果返回值不为 0,则说明设置失败,否则说明设置成功,并输出相应的提示信息。
  • 最后,程序使用 fclose() 函数关闭输入文件和输出文件。

注意: 在使用文件流进行读写操作时,必须在适当的时候进行缓冲区清理操作,以避免数据丢失或者读取到过期数据等问题。另外,需要根据具体需求选择合适的缓冲方式和缓冲区大小,以实现最优的性能和稳定性。

10.3 运行结果

11. setviewport

11.1 函数说明

函数声明 函数功能
void setviewport(int left, int top, int right, int bottom, int clipflag); 用于设置绘图窗口的视口范围

参数:

  • left : 视口矩形的左上角横坐标,取值为正整数或 0
  • top: 视口矩形的左上角纵坐标,取值为正整数或 0
  • right: 视口矩形的右下角横坐标,取值为正整数
  • bottom: 视口矩形的右下角纵坐标,取值为正整数
  • clipflag: 裁剪标志,可以取以下值:
    • CLIP_ON:开启裁剪模式,只显示视口内的图形;
    • CLIP_OFF:关闭裁剪模式,显示整个画面。

11.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <graphics.h>

#define CLIP_ON 1

int main()
{
int gd = DETECT, gm;
initgraph(&gd, &gm, "");

setcolor(RED);
rectangle(100, 100, 300, 200);

// 将视口范围设置为矩形 (150, 150) - (250, 250)
setviewport(150, 150, 250, 250, CLIP_ON);

setcolor(GREEN);
rectangle(0, 0, 400, 300);

getch();
closegraph();
return 0;
}

在上面的示例程序中,

  • 我们首先使用 rectangle() 函数绘制了一个红色的矩形;
  • 然后使用 setviewport() 函数将视口范围设置为矩形 (150, 150) - (250, 250);
  • 最后使用 rectangle() 函数绘制了一个绿色的矩形,但这里只有在视口范围的矩形才显示出来。

注意: 在使用 setviewport() 函数设置视口范围时,必须指定正确的参数值,并考虑到裁剪模式的影响,否则可能会导致图形显示不符合预期。

11.3 运行结果

12. setvisualpage

12.1 函数说明

函数声明 函数功能
void setvisualpage(int pagenum); 用于设置图形窗口中用户可见的页面

参数:

  • pagenum : 要设置的可视化页面页码,整数类型。

在双缓冲绘图中,我们通常会使用两个页面来绘制图像,一个是前台页面,另一个是后台页面。当我们绘制完一个完整的画面时,可以通过调用 setactivepage() 函数将后台页面切换到前台页面以显示出来。而 setvisualpage() 函数则用于设置用户当前看到的页面,它实际上是将指定的页面置于前台,从而更新屏幕上显示的内容。

12.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <graphics.h>

int main(void)
{
int gdriver = EGA, gmode = EGAHI;
int x, y, ht;

initgraph(&gdriver, &gmode, "");

x = getmaxx() / 2;
y = getmaxy() / 2;
ht = textheight("W");

setactivepage(1);

line(0, 0, getmaxx(), getmaxy());

settextjustify(CENTER_TEXT, CENTER_TEXT);
outtextxy(x, y, "This is page #1:");
outtextxy(x, y+ht, "Press any key to halt:");

setactivepage(0);

outtextxy(x, y, "This is page #0.");
outtextxy(x, y+ht, "Press any key to view page #1:");
getch();

setvisualpage(1);

getch();
closegraph();
return 0;
}

上述示例将在屏幕上绘制两个页面,并允许用户通过按任意键查看第二个页面。

注意: setvisualpage() 函数只能用于已经创建的图形窗口,且参数 pagenum 必须在 0getmaxpages() 函数返回值之间。

12.3 运行结果

13. setwritemode

13.1 函数说明

函数声明 函数功能
void setwritemode(int mode); 用于设置绘画操作的写入模式

参数:

  • mode: 要设置的写入模式,整数类型。常用的写入模式有以下三种:
    • COPY_PUT:0,复制模式(默认),新绘制的图形将完全覆盖旧图形
    • XOR_PUT:1,异或模式,新绘制的图形将与旧图形进行异或运算后显示。在这种模式下,如果一个像素既在新图形中出现过,也在旧图形中出现过,则它最终不会被显示出来;如果一个像素只在新图形中出现过,或者只在旧图形中出现过,则它将会被显示出来。
    • OR_PUT:2,或模式,新绘制的图形将与旧图形进行或运算后显示。在这种模式下,如果一个像素既在新图形中出现过,也在旧图形中出现过,则它最终会被显示出来;如果一个像素只在新图形中出现过,或者只在旧图形中出现过,则它将会被显示出来。

13.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <graphics.h>

int main()
{
int gdriver = DETECT, gmode;
int xmax, ymax;

initgraph(&gdriver, &gmode, "");

xmax = getmaxx();
ymax = getmaxy();

setwritemode(XOR_PUT);

line(0, 0, xmax, ymax);
getch();

line(0, 0, xmax, ymax);
getch();

setwritemode(COPY_PUT);

line(0, 0, xmax, ymax);

getch();
closegraph();
return 0;
}

注意: setwritemode() 函数只对紧随其后的绘画操作生效,它不会影响之前已经绘制的图形。因此,在更改写入模式之前,必须先完成之前的绘画操作。

13.3 运行结果

14. signal

14.1 函数说明

函数声明 函数功能
void (*signal(int signum, void (*handler)(int)))(int); 用于设置指定信号的处理方式。当系统接收到某个信号时,会调用相应的信号处理函数来处理该信号。在调用 signal 函数时,需要指定要处理的信号以及相应的信号处理函数。

参数:

  • signum : 要设置的信号编号,整数类型。常见的信号有很多种,如:
    • SIGINT(中断信号):通常由用户按下 “Ctrl + C“ 产生,用于中断正在运行的程序。
    • SIGALRM(闹钟信号):用于在指定的时间后向进程发送信号,可以用于实现定时器等功能。
    • SIGFPE(浮点异常信号):在发生浮点运算异常时发送该信号。
    • SIGSEGV(段错误信号):在访问非法的内存地址时发送该信号。
  • handler : 要设置的信号处理函数,是一个指向函数的指针,其形式为 void handler(int)

返回值:

  • 如果调用成功,返回之前对信号的处理方式(通常是一个函数指针)。如果之前没有设置过该信号的处理方式,返回默认的处理方式(通常是 SIG_DFLSIG_IGN)。
  • 如果调用失败,返回 SIG_ERR

14.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>

void sigint_handler(int sig) {
printf("Caught signal %d\n", sig);
exit(0);
}

int main() {
signal(SIGINT, sigint_handler);

while (1) {
printf("Doing something...\n");
getchar();
// check for interrupt signal
raise(SIGINT);
}

return 0;
}

在上面的示例中,

  • 我们首先使用 signal() 函数设置了一个处理 SIGINT 信号的处理程序 sigint_handler()
  • 然后,在主循环中,我们随意输入一个字符后,就使用 raise() 函数向当前正在运行的进程发送 SIGINT 信号。当收到 SIGINT 信号时,程序将打印一条消息并退出。

14.3 运行结果

15. significand,significandf

15.1 函数说明

函数声明 函数功能
double significand(double x); 用于分离浮点数 x 的尾数部分(double)
float significandf(float x); 用于分离浮点数 x 的尾数部分(float)

参数:

  • x : 要求尾数的浮点数。

15.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
#include <math.h>

int main()
{
double x = 123.456789;
float y = -2.5;

printf("The significand of %lf is %lf\n", x, significand(x));
printf("The significand of %f is %f\n", y, significandf(y));

return 0;
}

注意: 在某些旧版本的编译器中,可能没有实现 significand 函数。这个时候可以考虑使用其他类似的函数来替代,如 frexpmodf 等。

16. sin,sinf,sinl

16.1 函数说明

函数声明 函数功能
double sin(double x); 用于计算一个角度(以弧度为单位)的正弦值(double)
float sinf(float x); 用于计算一个角度(以弧度为单位)的正弦值(float)
long double sinl(long double x); 用于计算一个角度(以弧度为单位)的正弦值(long double)

参数:

  • x : 要求正弦值的角度,以弧度为单位

16.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
#include <math.h>

int main()
{
double x = M_PI / 6.0; // M_PI 圆周率
float y = M_PI / 4.0L;
long double z = M_PI / 3.0L;

printf("sin(%lf) = %lf\n", x, sin(x));
printf("sinf(%f) = %f\n", y, sinf(y));
printf("sinl(%Lf) = %Lf\n", z, sinl(z));

return 0;
}

16.3 运行结果

17. sincos,sincosf,sincosl

17.1 函数说明

函数声明 函数功能
void sincos(double x, double* sinVal, double* cosVal); 用于同时计算一个角度(以弧度为单位)的正弦值和余弦值
void sincosf(float x, float* sinVal, float* cosVal); 用于同时计算一个角度(以弧度为单位)的正弦值和余弦值
void sincosl(long double x, long double* sinVal, long double* cosVal); 用于同时计算一个角度(以弧度为单位)的正弦值和余弦值

参数:

  • x : 要求正弦值和余弦值的角度,以弧度为单位
  • sinVal : 存放计算得到的正弦值的指针
  • cosVal : 存放计算得到的余弦值的指针

17.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <stdio.h>
#include <math.h>

int main()
{
double x = M_PI / 6.0;
float y = M_PI / 4.0L;
long double z = M_PI / 3.0L;

double sinVal, cosVal;
float sinfVal, cosfVal;
long double sinlVal, coslVal;

sincos(x, &sinVal, &cosVal);
sincosf(y, &sinfVal, &cosfVal);
sincosl(z, &sinlVal, &coslVal);

printf("sincos(%lf) = (%lf, %lf)\n", x, sinVal, cosVal);
printf("sincosf(%f) = (%f, %f)\n", y, sinfVal, cosfVal);
printf("sincosl(%Lf) = (%Lf, %Lf)\n", z, sinlVal, coslVal);

return 0;
}

17.3 运行结果

18. sinh,sinhf,sinhl

18.1 函数说明

函数声明 函数功能
double sinh(double x); 用于计算一个数的双曲正弦值
float sinhf(float x); 用于计算一个数的双曲正弦值
long double sinhl(long double x); 用于计算一个数的双曲正弦值

参数:

  • x : 要求双曲正弦值的数,以弧度为单位

18.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
#include <math.h>

int main()
{
double x = 1.0;
float y = 2.0;
long double z = 3.0;

printf("sinh(%lf) = %lf\n", x, sinh(x));
printf("sinhf(%f) = %f\n", y, sinhf(y));
printf("sinhl(%Lf) = %Lf\n", z, sinhl(z));

return 0;
}

18.3 运行结果

C语言函数大全--s 开头的函数(1)

总览

函数声明 函数功能
void *sbrk(intptr_t increment); 它是一个 Unix 系统的函数,用于调整程序的堆空间。
double scalb(double x, double n); 计算 x 乘以 2 的 n 次幂(double)
float scalbf(float x, float n); 计算 x 乘以 2 的 n 次幂(float)
long double scalbl(long double x, double n); 计算 x 乘以 2 的 n 次幂(long double)
double scalbln(double x, long int n); 计算 x 乘以 2 的指定长整数 n 次幂(double)
float scalblnf(float x, long int n); 计算 x 乘以 2 的指定长整数 n 次幂(float)
long double scalblnl(long double x, long int n); 计算 x 乘以 2 的指定长整数 n 次幂(long double)
double scalbn(double x, int n); 计算 x 乘以 2 的指定整数 n 次幂(double)
float scalbnf(float x, int n); 计算 x 乘以 2 的指定整数 n 次幂(float)
long double scalbnl(long double x, int n); 计算 x 乘以 2 的指定整数 n 次幂(long double)
int scanf(const char *format, ...); 从标准输入中读取指定格式的数据
void sector( int x, int y, int stangle, int endangle, int xradius, int yradius ); 画并填充椭圆扇区(Windows BGI)
void segread(struct SREGS *sregs); 它是一个 DOS 函数,用于从内存段(segment)中读取内容。
void setactivepage(int pagenum); 用于切换当前显示的页面
void setallpalette(struct palettetype *palette); 用于设置图形界面的整个调色板
void setaspectratio( int xasp, int yasp ); 设置图形纵横比
void setbkcolor(int color); 用于设置当前绘图窗口的背景色
void setbuf(FILE *stream, char *buffer); 用于设置标准输入流、标准输出流或标准错误流的缓冲方式
void setcolor(int color); 设置当前绘图颜色
void setfillpattern(char *upattern, int color); 用于设置当前绘图窗口的填充图案
void setfillstyle(int pattern, int color); 用于设置当前绘图窗口的填充样式,即用什么颜色或图案来填充绘制的图形
void setgraphmode(int mode); 设置当前的图形模式
int setjmp(jmp_buf env); 用于在程序执行过程中设置跳转点,并将当前程序状态保存到一个缓冲区中。当程序需要从该跳转点继续执行时,可以使用 longjmp() 函数恢复之前保存的程序状态并返回到该跳转点。

1. sbrk

1.1 函数说明

函数声明 函数功能
void *sbrk(intptr_t increment); 它是一个 Unix 系统的函数,用于调整程序的堆空间。

参数:

  • increment : 增加的堆空间的大小

返回值:

  • 如果调用成功,返回值即为增加空间前的原始堆顶指针;
  • 如果出错,则返回 (void *)-1

1.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <unistd.h>
#include <stdio.h>

int main() {
void *mem = sbrk(64);

if (mem == (void *)-1) {
perror("sbrk");
return 1;
}

printf("Allocated 64 bytes at address %p\n", mem);

return 0;
}

在上述示例中,

  • 首先调用 sbrk() 函数将堆顶位置向上移动 64 字节;
  • 然后将返回的指针保存在变量 mem 中;如果 sbrk 调用失败(即返回值等于 (void *)-1),则程序通过 perror() 函数输出错误信息并返回 1
  • 最后,程序打印出分配的内存地址,并返回 0 表示程序成功运行。

2. scalb,scalbf,scalbl

2.1 函数说明

函数声明 函数功能
double scalb(double x, double n); 计算 x 乘以 2 的 n 次幂(double)
float scalbf(float x, float n); 计算 x 乘以 2 的 n 次幂(float)
long double scalbl(long double x, double n); 计算 x 乘以 2 的 n 次幂(long double)

注意:如果 n 超过了可表示的范围,或者结果溢出,则函数可能返回正无穷大、负无穷大或 NaN

2.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>
#include <math.h>

int main() {
double x = 3.14159265359;
double y = scalb(x, 10);

printf("Before: %lf\n", x);
printf("After: %lf\n", y);

return 0;
}

3. scalbln,scalblnf,scalblnl

3.1 函数说明

函数声明 函数功能
double scalbln(double x, long int n); 计算 x 乘以 2 的指定长整数 n 次幂(double)
float scalblnf(float x, long int n); 计算 x 乘以 2 的指定长整数 n 次幂(float)
long double scalblnl(long double x, long int n); 计算 x 乘以 2 的指定长整数 n 次幂(long double)

3.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>
#include <math.h>

int main() {
double x = 1.5;
float y = 2.25f;
long double z = 3.75l;
long int n = 3;
// 将x乘以2的3次幂
double result = scalbln(x, n);
printf("scalbln(%lf, %ld) = %lf\n", x, n, result);

float resultf = scalblnf(y, n);
printf("scalblnf(%f, %ld) = %f\n", y, n, resultf);

long double resultL = scalblnl(z, n);
printf("scalblnl(%Lf, %ld) = %Lf", z, n, resultL);

return 0;
}

3.3 运行结果

4. scalbn,scalbnf,scalbnl

4.1 函数说明

函数声明 函数功能
double scalbn(double x, int n); 计算 x 乘以 2 的指定整数 n 次幂(double)
float scalbnf(float x, int n); 计算 x 乘以 2 的指定整数 n 次幂(float)
long double scalbnl(long double x, int n); 计算 x 乘以 2 的指定整数 n 次幂(long double)

4.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
#include <math.h>

int main()
{
double x = 3.1415926;
float y = 3.1415926f;
long double z = 3.1415926L;
int n = 5;

printf("scalbn(%lf, %d) = %.20lf\n", x, n, scalbn(x, n));
printf("scalbnf(%f, %d) = %.20f\n", y, n, scalbnf(y, n));
printf("scalbnl(%Lf, %d) = %.20Lf\n", z, n, scalbnl(z, n));

return 0;
}

4.3 运行结果

5. scanf

5.1 函数说明

函数声明 函数功能
int scanf(const char *format, ...); 从标准输入中读取指定格式的数据

详细内容 可参考 《scanf》

5.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
#include <math.h>

int main()
{
char name[20];

scanf("%s", name);

printf("Welcome, %s", name);

return 0;
}

在上述示例中,实现了从标准输入中读取一个字符串,并输出欢迎消息。

  • 我们首先定义一个名为 name 的字符数组,长度为 20;
  • 然后使用 scanf() 函数从标准输入中读取一个字符串,存储到 name 数组中;
  • 最后使用 printf() 函数输出欢迎消息,其中 %s 表示字符串格式化符号,会被 name 所代替。

5.3 运行结果

6. sector

6.1 函数说明

函数声明 函数功能
void sector( int x, int y, int stangle, int endangle, int xradius, int yradius ); 画并填充椭圆扇区(Windows BGI)

参数:

  • x : 扇形的圆心坐标的 x 轴
  • y : 扇形的圆心坐标的 y 轴
  • stangle : 起始角度(以度数为单位)
  • endangle : 结束角度(以度数为单位)
  • xradius : 横向半径
  • yradius : 纵向半径

6.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <graphics.h>

int main(void)
{
int gdriver = DETECT, gmode;
int midx, midy, i;
int stangle = 45, endangle = 135;
int xrad = 100, yrad = 50;

initgraph(&gdriver, &gmode, "");

midx = getmaxx() / 2;
midy = getmaxy() / 2;

for (i=EMPTY_FILL; i<USER_FILL; i++)
{
setfillstyle(i, getmaxcolor());

sector(midx, midy, stangle, endangle, xrad, yrad);

getch();
}

closegraph();
return 0;
}

6.3 运行结果

7. segread

7.1 函数说明

函数声明 函数功能
void segread(struct SREGS *sregs); 它是一个 DOS 函数,用于从内存段(segment)中读取内容。

7.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
#include <dos.h>
#include <stdio.h>

int main() {
struct SREGS regs;
segread(&regs); // 读取段寄存器的值
printf("Data segment: %04X\n", regs.ds);
printf("Code segment: %04X\n", regs.cs);
printf("Stack segment: %04X\n", regs.ss);
return 0;
}

上述的这个示例程序,使用了 <dos.h> 头文件中的 segread() 函数和 struct SREGS 结构体,并打印出数据段(DS)、代码段(CS)和堆栈段(SS)的值。

8. setactivepage

8.1 函数说明

函数声明 函数功能
void setactivepage(int pagenum); 用于切换当前显示的页面

8.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <graphics.h>

int main(void)
{
int gdriver = EGA, gmode = EGAHI;
int x, y, ht;

initgraph(&gdriver, &gmode, "");

x = getmaxx() / 2;
y = getmaxy() / 2;
ht = textheight("W");

setactivepage(1);

line(0, 0, getmaxx(), getmaxy());

settextjustify(CENTER_TEXT, CENTER_TEXT);
outtextxy(x, y, "This is page #1:");
outtextxy(x, y+ht, "Press any key to halt:");

setactivepage(0);

outtextxy(x, y, "This is page #0.");
outtextxy(x, y+ht, "Press any key to view page #1:");
getch();

setvisualpage(1);

getch();
closegraph();
return 0;
}

上述示例将在屏幕上绘制两个页面,并允许用户通过按任意键查看第二个页面。

8.3 运行结果

9. setallpallette

9.1 函数说明

函数声明 函数功能
void setallpalette(struct palettetype *palette); 用于设置图形界面的整个调色板

参数:

  • palette : 调色版结构体

9.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include <graphics.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>

int main(void)
{
int gdriver = DETECT, gmode;
struct palettetype pal, copypal;
int color, ht;
int y = 10;
char msg[80];

initgraph(&gdriver, &gmode, "");

ht = 2 * textheight("W");

getpalette(&pal);

for (color = 1; color <= MAXCOLORS; color++)
{
sprintf(msg, "old colors[%d]: %d", color, pal.colors[color]);
outtextxy(1, y, msg);
y += ht;
}

for (color = 1; color <= MAXCOLORS; color++)
{
setpalette(color, BLACK);
}

getpalette(&copypal);

getch();

y = 10;
for (color = 1; color <= MAXCOLORS; color++)
{
sprintf(msg, "new colors[%d]: %d", color, copypal.colors[color]);
outtextxy(150, y, msg);
y += ht;
}

getch();
// 重置调色板
setallpalette(&pal);

getpalette(&pal);

y = 10;
for (color = 1; color <= MAXCOLORS; color++)
{
sprintf(msg, "old colors[%d]: %d", color, pal.colors[color]);
outtextxy(300, y, msg);
y += ht;
}

getch();
closegraph();
return 0;
}

9.3 运行结果

10. setaspectratio

10.1 函数说明

函数声明 函数功能
void setaspectratio( int xasp, int yasp ); 设置图形纵横比

参数:

  • xasp : 水平缩放比例
  • yasp : 垂直缩放比例

10.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <graphics.h>

int main()
{
int gd = DETECT, gm;
initgraph(&gd, &gm, "");

// 设置水平和垂直缩放比例为 2:1
setaspectratio(2, 1);

// 在图形窗口中绘制一个正方形
rectangle(100, 100, 200, 200);

getch();
closegraph();
return 0;
}

注意: 因为 BGI 图形库在 Windows 上的实现是基于 Win32 API 的简单封装,并且没有提供缩放功能,所以上述程序在 Windows BGI 下不支持缩放功能,也就是 setaspectratio 没有效果。

11. setbkcolor

11.1 函数说明

函数声明 函数功能
void setbkcolor(int color); 用于设置当前绘图窗口的背景色

参数:

  • color : 要设置的颜色,预定义颜色有如下:
颜色值 英文枚举 中文描述
0 BLACK
1 BLUE
2 GREEN 绿
3 CYAN
4 RED
5 MAGENTA 洋红
6 BROWN
7 LIGHTGRAY 淡灰
8 DARKGRAY 深灰
9 LIGHTBLUE 淡兰
10 LIGHTGREEN 淡绿
11 LIGHTCYAN 淡青
12 LIGHTRED 淡红
13 LIGHTMAGENTA 淡洋红
14 YELLOW
15 WHITE

11.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <graphics.h>

int main()
{
int gd = DETECT, gm;
initgraph(&gd, &gm, "");

// 设置背景色为蓝色
setbkcolor(BLUE);

// 清除先前绘制的图形
cleardevice();

// 在图形窗口中绘制一条线段
line(100, 100, 200, 200);

getch();
closegraph();
return 0;
}

注意: 在修改背景颜色后,需要使用 cleardevice() 函数清除先前绘制的图形并更新背景颜色,不然背景颜色的修改不会生效。

11.3 运行结果

12. setbuf

12.1 函数说明

函数声明 函数功能
void setbuf(FILE *stream, char *buffer); 用于设置标准输入流、标准输出流或标准错误流的缓冲方式

参数:

  • FILE *stream : 目标文件流指针(如 stdin, stdout, stderr 或 fopen() 返回的指针)。必须指向已打开的文件流。
  • char *buffer : 缓冲区指针。
    • 若传递有效缓冲区地址:使用该缓冲区作为流的缓存
    • 若传递 NULL:禁用缓冲

12.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>

int main()
{
FILE *fp;

// 打开文件,并设置为不带缓冲
fp = fopen("test.txt","w");
setbuf(fp, NULL);

// 写入数据到文件中
fprintf(fp, "This is a line of text.");

// 关闭文件
fclose(fp);

return 0;
}

在上述这个示例程序中,我们打开了一个名为 test.txt 的文件,并使用 setbuf() 函数将其设置为不带缓冲。然后,我们向文件中写入一行文本,关闭文件并退出程序。

由于我们已经将文件设置为不带缓冲,因此写入的数据将直接写入磁盘,而不会在内存中留下缓冲区。

12.3 运行结果

13. setcolor

13.1 函数说明

函数声明 函数功能
void setcolor(int color); 设置当前绘图颜色

参数:

  • color : 要设置的颜色,预定义颜色有如下:
颜色值 英文枚举 中文描述
0 BLACK
1 BLUE
2 GREEN 绿
3 CYAN
4 RED
5 MAGENTA 洋红
6 BROWN
7 LIGHTGRAY 淡灰
8 DARKGRAY 深灰
9 LIGHTBLUE 淡兰
10 LIGHTGREEN 淡绿
11 LIGHTCYAN 淡青
12 LIGHTRED 淡红
13 LIGHTMAGENTA 淡洋红
14 YELLOW
15 WHITE

13.2 演示示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <graphics.h>

int main()
{
int gd = DETECT, gm;
initgraph(&gd, &gm, "");

setbkcolor(WHITE);

cleardevice();

// 设置绘画颜色为红色
setcolor(RED);

// 在图形窗口中绘制一条直线
line(100, 100, 200, 200);

getch();
closegraph();
return 0;
}

13.3 运行结果

14. setfillpattern

14.1 函数说明

函数声明 函数功能
void setfillpattern(char *upattern, int color); 用于设置当前绘图窗口的填充图案

参数:

  • upattern : 填充图案
  • color : 填充颜色

在调用 setfillpattern() 函数之前,需要先定义一个名为 upattern 的字符数组,并将其用作填充图案。这个图案通常使用一个 8 字节的字节数组表示,每个元素包含一个 8 比特位的掩码,用于表示该位置是否应该被绘制斜线或其他样式。

14.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <graphics.h>

int main(void)
{
int gdriver = DETECT, gmode;
int maxx, maxy;

char pattern[8] = {0x00, 0x70, 0x20, 0x27, 0x24, 0x24, 0x07, 0x00};

// 初始化图形模式
initgraph(&gdriver, &gmode, "");

// 获取屏幕的最大 X 和 Y 坐标
maxx = getmaxx();
maxy = getmaxy();

// 设置当前颜色为最大颜色值
setcolor(getmaxcolor());

// 设置填充图案
setfillpattern(pattern, getmaxcolor());

// 用填充图案填满整个窗口
bar(0, 0, maxx, maxy);

// 等待用户按下任意键后关闭窗口
getch();
closegraph();

return 0;
}

上述程序使用了 Windows BGI 图形库来创建一个空白的图形窗口,并在其中填充一种斜线筛子图案。

何为斜线筛子图案,参考如下程序打印:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>

int main() {
char pattern[8] = {0x00, 0x70, 0x20, 0x27, 0x24, 0x24, 0x07, 0x00};

for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
if (pattern[i] & (1 << (7 - j))) {
printf("*");
} else {
printf(" ");
}
}
printf("\n");
}

return 0;
}

14.3 运行结果

15. setfillstyle

15.1 函数说明

函数声明 函数功能
void setfillstyle(int pattern, int color); 用于设置当前绘图窗口的填充样式,即用什么颜色或图案来填充绘制的图形

参数:

  • pattern : 填充样式
  • color : 填充颜色

如下是支持的填充样式:

填充样式值 英文枚举 中文描述
0 EMPTY_FILL 空填充(无填充)
1 SOLID_FILL 实心填充
2 LINE_FILL 横线填充
3 LTSLASH_FILL 细斜线填充(左斜)
4 SLASH_FILL 粗斜线填充(左斜)
5 BKSLASH_FILL 粗反斜线填充(右斜)
6 LTBKSLASH_FILL 细反斜线填充(右斜)
7 HATCH_FILL 网格阴影填充
8 XHATCH_FILL 交叉网格填充
9 INTERLEAVE_FILL 交错线填充
10 WIDE_DOT_FILL 稀疏点状填充
11 CLOSE_DOT_FILL 密集点状填充
12 USER_FILL 用户自定义填充模式

setfillstyle() 函数还支持使用用户自定义的填充样式。如果要使用用户自定义的填充样式,需要调用 setuserchars() 函数来设置填充字形,然后将填充样式参数设置为 USER_FILL

15.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <graphics.h>

int main()
{
int gd = DETECT, gm;
initgraph(&gd, &gm, "");

// 设置填充样式为斜线筛子图案,颜色为红色
setfillstyle(SLASH_FILL, RED);

// 在图形窗口中填充一个矩形
rectangle(100, 100, 200, 200);
floodfill(150, 150, getmaxcolor());

getch();
closegraph();
return 0;
}

在上述的示例程序中,

  • 我们首先使用 setfillstyle() 函数将填充样式设置为斜线筛子图案(即 SLASH_FILL 样式),颜色设置为红色。
  • 然后,我们使用 rectangle() 函数在图形窗口中绘制一个矩形,并使用 floodfill() 函数将该矩形填充为红色的斜线筛子图案。
  • 最后按任意键退出图形模式。

15.3 运行结果

16. setgraphmode

16.1 函数说明

函数声明 函数功能
void setgraphmode(int mode); 设置当前的图形模式

16.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <graphics.h>
#include <stdlib.h>
#include <stdio.h>

int main(void)
{
int gdriver = DETECT, gmode;
int x, y;

initgraph(&gdriver, &gmode, "");

x = getmaxx() / 2;
y = getmaxy() / 2;

settextjustify(CENTER_TEXT, CENTER_TEXT);
outtextxy(x, y, "Press any key to exit graphics:");
getch();

// 将图形模式恢复到文本模式
restorecrtmode();
printf("We're now in text mode.\n");
printf("Press any key to return to graphics mode:");
getch();

// 返回图形模式
setgraphmode(getgraphmode());

settextjustify(CENTER_TEXT, CENTER_TEXT);
outtextxy(x, y, "We're back in graphics mode.");
outtextxy(x, y+textheight("W"), "Press any key to halt:");

getch();
closegraph();
return 0;
}

16.3 运行结果

17. setjmp

17.1 函数说明

函数声明 函数功能
int setjmp(jmp_buf env); 用于在程序执行过程中设置跳转点,并将当前程序状态保存到一个缓冲区中。当程序需要从该跳转点继续执行时,可以使用 longjmp() 函数恢复之前保存的程序状态并返回到该跳转点。

参数:

  • env : 要保存程序状态的缓冲区,通常声明为 jmp_buf 类型

返回值:
setjmp() 函数返回 0,除非它是从 longjmp() 函数调用返回的,这种情况下,它返回非零值。

17.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <stdio.h>
#include <setjmp.h>

jmp_buf buf;

void foo()
{
printf("foo() before longjmp()\n");
longjmp(buf, 1);
printf("foo() after longjmp()\n");
}

int main()
{
int ret = setjmp(buf);

if (ret == 0) {
printf("main() before foo()\n");
foo();
} else {
printf("main() after longjmp()\n");
}

return 0;
}

在上述的示例程序中,

  • 我们首先定义了一个名为 bufjmp_buf 类型的缓冲区,并将其作为参数传递给 setjmp() 函数,当前程序状态将保存到 buf 缓冲区中,并返回一个整形,用 ret 变量存储;此时 ret 的值为 0,则说明是第一次调用 setjmp() 函数,主函数内打印输出 ”main() before foo()“
  • 然后我们调用 foo() 函数,打印输出 ”foo() before longjmp()“
  • 接着调用 longjmp() 函数,将会返回到 setjmp() 函数调用的位置,并传递了一个值 1。因为 longjmp() 调用一定会返回 setjmp() 函数调用的位置,因此 foo() 函数的后面一行代码永远不会被执行。
  • 最后 setjmp() 函数返回 ret 的值为 1,则说明是从 longjmp() 函数中返回的,主函数内打印输出 ”main() after longjmp()“

17.3 运行结果

参考

  1. [API Reference Document]

C语言函数大全--r 开头的函数

总览

函数声明 函数功能
int raise(int sig); 用于向当前进程发送指定的信号。
int rand(void); 用于生成伪随机数
ssize_t read(int fd, void *buf, size_t count); 用于从文件描述符读取数据的函数。
void *realloc(void *ptr, size_t size); 用于重新分配已经分配过内存的空间大小。
void rectangle( int left, int top, int right, int bottom); 画一个矩形
int registerbgidriver(void(*driver)(void)); 用于将BGI(Borland Graphics Interface)驱动程序注册到系统中
int remove(char *filename); 用于删除指定的文件
int rename(char *oldname, char *newname); 用于重命名或移动文件。
void restorecrtmode(void); 将图形模式恢复到文本模式
void rewind(FILE *stream); 将文件指针 stream 指向的文件位置重置为文件开头,同时清除任何错误或文件结束标志。
int rmdir(const char *path); 用于删除一个空目录,即该目录必须为空。
double round(double x); 将传入的实数参数 x 四舍五入为最接近的整数(double)
float roundf(float x); 将传入的实数参数 x 四舍五入为最接近的整数(float)
long double roundl(long double x); 将传入的实数参数 x 四舍五入为最接近的整数(long double)
double remainder(double x, double y); 用于计算两个浮点数的余数(即模运算结果)(double)
float remainderf (float x, float y ); 用于计算两个浮点数的余数(即模运算结果)(float)
long double remainderl (long double x, long double y); 用于计算两个浮点数的余数(即模运算结果)(long double)
double remquo(double x, double y, int *quo); 用于计算两个浮点数的余数,并返回商和余数。
float remquof(float x, float y, int *quo); 用于计算两个浮点数的余数,并返回商和余数。
long double remquol(long double x, long double y, int *quo); 用于计算两个浮点数的余数,并返回商和余数。
double rint(double x); 将 x 四舍五入到最接近的整数(double)
float rintf(float x); 将 x 四舍五入到最接近的整数(float)
long double rintl(long double x); 将 x 四舍五入到最接近的整数(long double)

1. raise

1.1 函数说明

函数声明 函数功能
int raise(int sig); 用于向当前进程发送指定的信号。

参数:

  • sig : 指定要发送的信号编号

返回值:

  • 如果调用成功,raise() 函数将返回 0
  • 否则,它将返回一个非零值。

1.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>

void sigint_handler(int sig) {
printf("Caught signal %d\n", sig);
exit(0);
}

int main() {
signal(SIGINT, sigint_handler);

while (1) {
printf("Doing something...\n");
getchar();
// check for interrupt signal
raise(SIGINT);
}

return 0;
}

在上面的示例中,

  • 我们首先使用 signal() 函数设置了一个处理 SIGINT 信号的处理程序 sigint_handler()
  • 然后,在主循环中,我们随意输入一个字符后,就使用 raise() 函数向当前正在运行的进程发送 SIGINT 信号。当收到 SIGINT 信号时,程序将打印一条消息并退出。

注意: raise() 函数只能向当前进程发送信号,不能向其他进程发送信号。如果要向其他进程发送信号,可以使用 kill() 函数。

1.3 运行结果

2. rand

2.1 函数说明

函数声明 函数功能
int rand(void); 用于生成伪随机数

返回值:
每次调用它时会返回一个介于 0RAND_MAX 之间的伪随机整数。其中,RAND_MAX 是一个常量,表示返回值的最大值,通常为 32767

2.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main() {
// 使用系统时间作为随机数种子初始化
srand(time(NULL));

// 生成并输出 10 个随机数
for (int i = 0; i < 10; i++) {
printf("%d\n", rand());
}

return 0;
}

注意:

  • 每次程序运行时,rand() 函数返回的随机数序列都是相同的。如果要生成不同的随机数序列,可以使用 srand() 函数提供的种子来初始化随机数发生器。
  • 由于 rand() 函数只能生成伪随机数,不能保证其真正的随机性。因此,在需要高度安全性的应用程序中,建议使用更加安全的随机数生成器,如 /dev/random/dev/urandom 等系统提供的硬件随机数生成器。

2.3 运行结果

3. read

3.1 函数说明

函数声明 函数功能
ssize_t read(int fd, void *buf, size_t count); 用于从文件描述符读取数据的函数。

参数:

  • fd : 要读取的文件描述符
  • buf : 存储读取数据的缓冲区
  • count : 要读取的字节数。

3.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
#include <unistd.h>

#define BUFFER_SIZE 1024

int main() {
char buffer[BUFFER_SIZE];
ssize_t num_read;

num_read = read(STDIN_FILENO, buffer, BUFFER_SIZE);
if (num_read == -1) {
perror("read");
return 1;
}

printf("Read %ld bytes from standard input: %.*s", num_read, (int)num_read, buffer);

return 0;
}

在上述的示例中,

  • 我们首先定义了一个大小为 BUFFER_SIZE 的字符数组 buffer
  • 然后使用 read() 函数读取标准输入【STDIN_FILENO 表示标准输入的文件描述符】中的数据到 buffer 中;
  • 最后将读取的结果输出到控制台上。

3.3 运行结果

4. realloc

4.1 函数说明

函数声明 函数功能
void *realloc(void *ptr, size_t size); 用于重新分配已经分配过内存的空间大小。

参数:

  • ptr : 指向已分配内存区域的指针
  • size : 需要分配的新内存大小

返回值:

  • 它会尝试重新调整已经分配给 ptr 指向的内存区域大小,并返回一个指向新内存起始地址的指针。
  • 如果无法分配新的内存,则返回空指针 NULL

注意: realloc() 函数并不保证原有的内存区域内容会被完全保留。当内存大小增加时,可能会分配新的内存并将原有的数据复制到新内存区域中;当内存大小减小时,则可能截断部分原有的数据。因此,在使用 realloc() 函数时,需要注意备份原有的数据,以免出现数据丢失的情况。

4.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <stdio.h>
#include <stdlib.h>

int main() {
// 分配 10 个整型变量的内存空间
int *p = (int*) malloc(10 * sizeof(int));
if (p == NULL) {
printf("内存分配失败\n");
exit(1);
}

// 更改为 20 个整型变量的内存空间
int *q = (int*) realloc(p, 20 * sizeof(int));
if (q == NULL) {
printf("内存分配失败\n");
exit(1);
}

// 输出新的内存地址
printf("原内存地址:%p,新内存地址:%p\n", p, q);

// 释放新分配的内存空间
free(q);

return 0;
}

在上面的示例中,

  • 我们首先使用 malloc() 函数分配了 10 个整型变量的内存空间,并判断是否分配成功。
  • 接着,我们使用 realloc() 函数将分配的内存空间大小扩充为 20 个整型变量,并判断是否分配成功。
  • 最后,我们输出了原有的内存地址和新的内存地址,并释放了新分配的内存空间。

注意: 在使用 realloc() 函数时,应该始终检查返回值,以确保分配内存空间成功,避免因内存不足或其他原因导致程序崩溃。另外,也应该避免过度使用 realloc() 函数,因为频繁地重新分配内存会影响程序性能。

5. rectangle

5.1 函数说明

函数声明 函数功能
void rectangle( int left, int top, int right, int bottom); 画一个矩形

参数:
left, top, right, bottom,它们分别表示矩形左上角和右下角的坐标。

5.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <graphics.h>

int main(void)
{
int gdriver = DETECT, gmode;
int left, top, right, bottom;

initgraph(&gdriver, &gmode, "");

left = getmaxx() / 2 - 50;
top = getmaxy() / 2 - 50;
right = getmaxx() / 2 + 50;
bottom = getmaxy() / 2 + 50;

rectangle(left,top,right,bottom);

getch();
closegraph();
return 0;
}

5.3 运行结果

6. registerbgidriver

6.1 函数说明

函数声明 函数功能
int registerbgidriver(void(*driver)(void)); 用于将BGI(Borland Graphics Interface)驱动程序注册到系统中

注意:
它必须在使用任何 BGI 图形函数之前调用。该函数接受一个指向驱动程序结构的指针作为参数,并返回一个整数值以指示是否成功注册了驱动程序。BGI 驱动程序主要用于支持 Borland C++IDE 环境下的图形绘制和显示操作,它们通常存储在一个单独的库文件中,例如 graphics.h 头文件需要使用的 BGI driver 位于 libbgi.a 文件中。

6.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
#include <graphics.h>

int main()
{
int gd = DETECT, gm;
initgraph(&gd, &gm, "");
registerbgidriver(EGAVGA_driver); // 注册EGAVGA驱动程序
circle(100, 100, 50); // 绘制圆形
getch(); // 等待用户输入
closegraph(); // 关闭图形界面
return 0;
}

7. remove

7.1 函数说明

函数声明 函数功能
int remove(char *filename); 用于删除指定的文件

参数:

  • filename : 一个指向要删除文件的文件名的字符串指针

返回值:
返回一个整数表示操作是否成功

  • 如果文件成功删除,则返回 0
  • 否则,返回非零值以指示发生错误。

7.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>

int main()
{
int result;
char filename[] = "example.txt";
result = remove(filename);
if (result == 0)
{
printf("The file %s has been removed.\n", filename);
}
else
{
printf("Error deleting the file %s.\n", filename);
}
return 0;
}

7.3 运行结果


8. rename

8.1 函数说明

函数声明 函数功能
int rename(char *oldname, char *newname); 用于重命名或移动文件。

参数:

  • oldname : 指定要更改的文件名
  • newname : 指定新文件名或包含新路径的新文件名

返回值:

  • 在执行成功时,该函数返回 0
  • 否则返回非零值以指示发生错误。

8.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>

int main()
{
char oldname[] = "temp.txt";
char newname[] = "tempnew.txt";
int result;

result = rename(oldname, newname);

if (result == 0)
{
printf("The file has been renamed.\n");
}
else
{
printf("Error renaming the file.\n");
}

return 0;
}

8.3 运行结果

9. restorecrtmode

9.1 函数说明

函数声明 函数功能
void restorecrtmode(void); 将图形模式恢复到文本模式

9.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <graphics.h>
#include <stdlib.h>
#include <stdio.h>

int main(void)
{
int gdriver = DETECT, gmode;
int x, y;

initgraph(&gdriver, &gmode, "");

x = getmaxx() / 2;
y = getmaxy() / 2;

settextjustify(CENTER_TEXT, CENTER_TEXT);
outtextxy(x, y, "Press any key to exit graphics:");
getch();

// 将图形模式恢复到文本模式
restorecrtmode();
printf("We're now in text mode.\n");
printf("Press any key to return to graphics mode:");
getch();

// 返回图形模式
setgraphmode(getgraphmode());

settextjustify(CENTER_TEXT, CENTER_TEXT);
outtextxy(x, y, "We're back in graphics mode.");
outtextxy(x, y+textheight("W"), "Press any key to halt:");

getch();
closegraph();
return 0;
}

9.3 运行结果

10. rewind

10.1 函数说明

函数声明 函数功能
void rewind(FILE *stream); 将文件指针 stream 指向的文件位置重置为文件开头,同时清除任何错误或文件结束标志。

10.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <stdio.h>

int main() {
FILE *fp = fopen("tempnew.txt", "r");
if (fp == NULL) {
perror("Failed to open file");
return 1;
}

// 读取文件内容
char buffer[1024];
while (fgets(buffer, sizeof(buffer), fp)) {
printf("%s", buffer);
}

printf("\n");

// 将文件指针重置到开头
rewind(fp);

// 再次读取文件内容
while (fgets(buffer, sizeof(buffer), fp)) {
printf("%s", buffer);
}

fclose(fp);
return 0;
}

在上述的示例中,

  • 我们首先打开一个名为 tempnew.txt 的文件;
  • 然后使用 fgets() 函数从文件中读取文本行,并输出内容;
  • 接着使用 rewind() 函数将文件指针重置到文件开头,并再次读取文件内容并输出;
  • 最后关闭文件,退出程序。

10.3 运行结果

11. rmdir

11.1 函数说明

函数声明 函数功能
int rmdir(const char *path); 用于删除一个空目录,即该目录必须为空。

参数:

  • path : 待删除的空目录路径

返回值:

  • 如果成功,则返回 0
  • 否则返回 -1,并设置 errno 错误码。

11.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <stdio.h>
#include <stdlib.h>
int main() {
const char *dir_name = "test";
if (mkdir(dir_name) I= 0) {
perror("Failed to create directory");
return 1;
}

//在目录中创建一些文件
FILE *fp1 = fopen("test/file1.txt","w");
FILE *fp2 = fopen("test/file2.txt","w");
fclose(fp1);
fclose(fp2);

//尝试刪除非空目录
if (rmdir(dir name) |= 0) {
perror("Failed to remove directory");
return 1;
}
printf("Directory removed successfullyIn");
return 0;
}

在上述的示例中,

  • 我们首先创建一个名为 test 的目录;
  • 然后在其中创建两个文件 file1.txtfile2.txt
  • 接着使用 rmdir() 函数尝试删除该目录,但会失败,因为该目录不是空的。

注意: 如果要删除非空目录,可以使用上面的 remove() 函数来删除目录及其所有内容。

11.3 运行结果

12. round,roundf,roundl

12.1 函数说明

函数声明 函数功能
double round(double x); 将传入的实数参数 x 四舍五入为最接近的整数(double)
float roundf(float x); 将传入的实数参数 x 四舍五入为最接近的整数(float)
long double roundl(long double x); 将传入的实数参数 x 四舍五入为最接近的整数(long double)

12.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <math.h>
#include <stdio.h>

int main() {
double x = 3.14159265;

double rounded1 = round(x); // 将 x 四舍五入为整数,结果为 3
double rounded2 = round(x * 100) / 100; // 将 x 精确到小数点后两位,结果为 3.14

printf("rounded1: %lf\n", rounded1);
printf("rounded2: %lf\n", rounded2);

float xf = 2.5;
printf("rountf(%f) = %f\n", xf, roundf(xf)); // 将 xf 四舍五入为整数,结果为 3

long double xL = 2.4;
printf("rountl(%Lf) = %Lf", xL, roundl(xL)); // 将 xL 四舍五入为整数,结果为 2
return 0;
}

12.3 运行结果

13. remainder,remainderf,remainderl

13.1 函数说明

函数声明 函数功能
double remainder(double x, double y); 用于计算两个浮点数的余数(即模运算结果)(double)
float remainderf (float x, float y ); 用于计算两个浮点数的余数(即模运算结果)(float)
long double remainderl (long double x, long double y); 用于计算两个浮点数的余数(即模运算结果)(long double)

参数:

  • x : 被除数
  • y : 除数

返回值: x/y 的余数

13.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
#include <math.h>

int main() {
double x = 10.5, y = 3.2;
printf("remainder(%lf, %lf) = %.20lf\n", x, y, remainder(x, y));


float xf = 10.5f, yf = 3.2f;
printf("remainder(%f, %f) = %.20f\n", xf, yf, remainderf(xf, yf));


long double xL = 10.5L, yL = 3.2L;
printf("remainder(%Lf, %Lf) = %.20Lf\n", xL, yL, remainderl(xL, yL));
return 0;
}

13.3 运行结果

14. remquo,remquof,remquol

14.1 函数说明

函数声明 函数功能
double remquo(double x, double y, int *quo); 用于计算两个浮点数的余数,并返回商和余数。
float remquof(float x, float y, int *quo); 用于计算两个浮点数的余数,并返回商和余数。
long double remquol(long double x, long double y, int *quo); 用于计算两个浮点数的余数,并返回商和余数。

参数:

  • x : 被除数
  • y : 除数
  • quo : 返回商的指针。如果不需要返回商,则可以传递 NULL

返回值: 返回 x/y 的余数,并通过 quo 指针返回商。

14.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
#include <math.h>

int main() {
int quo;
double x = 10.5, y = 3.2;
double rem = remquo(x, y, &quo);
printf("remquo(%lf, %lf, quo) = %.20lf, quo = %d\n", x, y, rem, quo);

float xf = 10.5f, yf = 3.2f;
float remf = remquof(xf, yf, &quo);
printf("remquof(%f, %f, quo) = %.20f, quo = %d\n", xf, yf, remf, quo);

long double xL = 10.5L, yL = 3.2L;
long double remL = remquol(xL, yL, &quo);
printf("remquol(%Lf, %Lf, quo) = %.20Lf, quo = %d\n", xL, yL, remL, quo);

return 0;
}

14.3 运行结果

15. rint,rintf,rintl

15.1 函数说明

函数声明 函数功能
double rint(double x); 将 x 四舍五入到最接近的整数(double)
float rintf(float x); 将 x 四舍五入到最接近的整数(float)
long double rintl(long double x); 将 x 四舍五入到最接近的整数(long double)

15.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>
#include <math.h>

int main() {
double d = 3.7;
float f = 2.4f;
long double ld = 5.9L;

printf("rint(%f) = %.1f\n", d, rint(d)); // Output: rint(3.700000) = 4.0
printf("rintf(%f) = %.1f\n", f, rintf(f)); // Output: rintf(2.400000) = 2.0
printf("rintl(%Lf) = %.1Lf\n", ld, rintl(ld)); // Output: rintl(5.900000) = 6.0

return 0;
}

15.3 运行结果

参考

  1. [API Reference Document]

C语言函数大全--q 开头的函数

总览

函数声明 函数功能
void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)); 用于将指定数组按指定顺序进行排序
void quick_exit(int status); 它是 C11 标准中新增的函数,用于快速退出程序并执行一些清理操作。它类似于 exit() 函数,但不会调用 atexit() 注册的函数,并且不会刷新标准 I/O 流(例如 stdoutstderr)。
int qunsetenv(const char *name); 用于从进程环境中移除指定的环境变量。该函数在某些操作系统上可能不可用,因为它并非标准的 C 语言函数,而是 POSIX 标准中定义的函数。
QuRT相关的函数 详见 4.1 所示

1. qsort

1.1 函数说明

函数声明 函数功能
void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)); 用于将指定数组按指定顺序进行排序
参数:
  • base : 指向要排序的数组的第一个元素的指针
  • nmemb : 表示数组中元素的数量
  • size : 表示每个元素的大小(以字节为单位)
  • compar : 指向一个函数,用于比较两个元素的值。该函数需要接受两个 const void* 类型的参数,分别指向要比较的两个元素,并返回一个整数值,表示它们的相对顺序。

1.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <stdio.h>
#include <stdlib.h>

int compare(const void* a, const void* b) {
return (*(int*)a - *(int*)b);
}

int main() {
int arr[] = { 5, 2, 8, 4, 1, 9, 3, 6, 7 };
size_t n = sizeof(arr) / sizeof(int);

printf("Before sorting:");
for (int i = 0; i < n; i++) {
printf(" %d", arr[i]);
}
printf("\n");

qsort(arr, n, sizeof(int), compare);

printf("After sorting:");
for (int i = 0; i < n; i++) {
printf(" %d", arr[i]);
}
printf("\n");

return 0;
}

在上述的示例中,

  • 我们首先定义了一个整数数组 arr,并计算出数组的长度,赋值给 n
  • 接着我们输出原始数组 "Before sorting: 5 2 8 4 1 9 3 6 7"
  • 然后我们使用 qsort() 函数将其按照升序排列。qsort() 函数中传入一个比较函数 compare(),用于比较两个元素的值。
  • 最后我们再次输出排序后的结果 ”After sorting: 1 2 3 4 5 6 7 8 9“

注意: 在编写比较函数时,需要根据元素的实际类型进行转换,并确保返回值符合要求(小于零表示第一个元素小于第二个元素,等于零表示两个元素相等,大于零表示第一个元素大于第二个元素)。此外,还需要特别注意参数类型和返回值类型的 const 限定符。

1.3 运行结果

2. quick_exit

2.1 函数说明

函数声明 函数功能
void quick_exit(int status); 它是 C11 标准中新增的函数,用于快速退出程序并执行一些清理操作。它类似于 exit() 函数,但不会调用 atexit() 注册的函数,并且不会刷新标准 I/O 流(例如 stdoutstderr)。
参数:
  • status :程序退出时返回的状态码,0 表示程序正常退出,非零值表示出现了异常情况。

2.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
#include <stdlib.h>

void cleanup() {
printf("Cleaning up...\n");
}

int main() {
if (at_quick_exit(cleanup) != 0) {
fprintf(stderr, "Failed to register cleanup function\n");
exit(EXIT_FAILURE);
}

printf("Running...\n");

quick_exit(EXIT_SUCCESS);
}

在如上的示例中,

  • 我们首先使用 at_quick_exit() 函数注册一个清理函数 cleanup(),当程序使用 quick_exit() 函数退出时,该函数会自动执行。
  • 然后,我们调用 quick_exit() 函数并传入状态码 EXIT_SUCCESS 表示程序正常退出。

注意: 在使用 quick_exit() 函数时需要特别小心,因为它不会调用 atexit() 注册的函数,并且可能导致一些资源泄漏或未完成的操作。只有在必须立即结束程序并执行清理操作时,才应该使用该函数。

3. qunsetenv

3.1 函数说明

函数声明 函数功能
int qunsetenv(const char *name); 用于从进程环境中移除指定的环境变量。该函数在某些操作系统上可能不可用,因为它并非标准的 C 语言函数,而是 POSIX 标准中定义的函数。
参数:
  • name : 要移除的环境变量的名称

返回值:

  • 如果环境变量不存在,则不进行任何操作,并返回 0
  • 否则将其移除,并返回一个非零值。

3.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <stdlib.h>
#include <stdio.h>

int main() {
// 设置一个环境变量
setenv("MY_VAR", "hello world", 1);

// 移除这个环境变量
if (qunsetenv("MY_VAR") != 0) {
perror("qunsetenv() failed");
exit(EXIT_FAILURE);
}

// 尝试访问这个环境变量
char *val = getenv("MY_VAR");
if (val == NULL) {
printf("Environment variable MY_VAR has been removed.\n");
} else {
printf("Unexpected value: %s\n", val);
}

return EXIT_SUCCESS;
}

在上述这个示例程序中,

  • 我们首先使用 setenv() 函数设置了一个名为 MY_VAR 的环境变量;
  • 然后使用 qunsetenv() 函数移除了这个环境变量;
  • 最后再次尝试访问这个环境变量,如果返回值为 NULL,则说明环境变量已经被成功移除了。

注意: 使用 qunsetenv() 函数可以修改当前进程的环境变量,但是对于其他进程或子进程来说,它们的环境变量不受影响。此外,一些操作系统可能不支持对环境变量进行动态修改,因此无法保证 qunsetenv() 函数在所有平台上都能正常工作。

4. QuRT

4.1 函数说明

函数声明 函数功能
void *qurt_sysenv_getvirtaddr(void *phys_addr, unsigned int size); 将物理地址转换为虚拟地址。
void *qurt_malloc(unsigned int size); 动态分配内存
void *qurt_calloc(unsigned int nmemb, unsigned int size); 动态分配内存,并初始化为零。
void qurt_free(void *ptr); 释放动态分配的内存。
int qurt_thread_create(qurt_thread_t *tid, const qurt_thread_attr_t *attr, void (*start)(void *), void *arg); 创建新线程。
int qurt_thread_join(qurt_thread_t tid, int *status); 等待线程结束并释放其资源。
unsigned int qurt_thread_get_priority(qurt_thread_t thread); 用于获取指定线程的优先级。其中参数 thread 是要获取优先级的线程的句柄。返回一个无符号整数,表示线程的优先级。
void qurt_thread_set_priority(qurt_thread_t thread, unsigned int priority); 用于设置指定线程的优先级。其中参数 thread 是要设置优先级的线程的句柄,而参数 priority 是要设置的优先级值。
char *qurt_thread_get_name(char *name, qurt_thread_t thread); 用于获取指定线程的名称。其中参数 name 是一个指向存储线程名称的缓冲区的指针,而参数 thread 是要获取名称的线程的句柄。返回一个指向缓冲区中存储线程名称的指针。
void qurt_thread_set_name(qurt_thread_t thread, const char *name); 用于设置指定线程的名称。其中参数 thread 是要设置名称的线程的句柄,而参数 name 是要设置的线程名称。
int qurt_thread_stop(qurt_thread_t thread); 用于停止指定线程的执行,即立即终止线程的运行。其中参数 thread 是要停止执行的线程的句柄。返回一个整数值,表示是否成功停止线程。如果成功,则返回 0;否则返回一个负数错误代码。
int qurt_thread_resume(qurt_thread_t thread); 用于恢复指定线程的执行,即让线程从上次暂停处继续运行。其中参数 thread 是要恢复执行的线程的句柄。返回一个整数值,表示是否成功恢复线程。如果成功,则返回 0;否则返回一个负数错误代码。
void qurt_mutex_init(qurt_mutex_t *mutex); 用于初始化一个互斥锁,即在使用之前必须进行初始化。其中参数 mutex 是指向要初始化的互斥锁对象的指针。
void qurt_mutex_lock(qurt_mutex_t *mutex); 用于以阻塞方式获取一个互斥锁。如果该互斥锁已被其他线程锁定,则当前线程将一直等待,直到可以获取该锁。其中参数 mutex 是指向要获取的互斥锁对象的指针。
void qurt_mutex_unlock(qurt_mutex_t *mutex); 用于释放一个互斥锁,即解除对该互斥锁的占用。其中参数 mutex 是指向要释放的互斥锁对象的指针。
void qurt_timer_sleep(unsigned int ticks); 用于让当前线程进入休眠状态,休眠时间由参数 ticks 指定(每个 tick 的长度取决于系统时钟频率)。在休眠期间,该线程将不会被调度执行。注意,该函数可能会提前唤醒线程,因此休眠时间并不精确。
void qurt_signal_init(qurt_signal_t *signal); 用于初始化一个信号量,即在使用之前必须进行初始化。其中参数 signal 是指向要初始化的信号量对象的指针。
unsigned int qurt_signal_wait(qurt_signal_t *signal, unsigned int mask, unsigned int option, unsigned int *ret_signal); 用于等待一个或多个信号量的触发。其中参数 signal 是指向要等待的信号量对象的指针,参数 mask 表示要等待哪些信号量,参数 option 用于指定等待的行为选项,参数 ret_signal 用于返回实际触发的信号量。
void qurt_signal_set(qurt_signal_t *signal, unsigned int mask); 用于触发一个或多个信号量。其中参数 signal 是指向要触发的信号量对象的指针,参数 mask 表示要触发哪些信号量。
void qurt_signal2_init(qurt_signal2_t *signal); 用于初始化一个带有两个信号量的信号量对象。其中参数 signal 是指向要初始化的信号量对象的指针。
void qurt_signal2_destroy(qurt_signal2_t *signal); 用于销毁带有两个信号量的信号量对象,并释放其占用的内存空间。其中参数 signal 是要销毁的信号量对象的指针。
void qurt_signal2_set(qurt_signal2_t *signal, unsigned int mask); 用于设置带有两个信号量的信号量对象中的一个或多个信号量。其中参数 signal 是要设置信号量的信号量对象的指针,而参数 mask 是一个 32 位无符号整数,表示要设置的信号量掩码。掩码中每个位代表一个信号量,如果该位为 1,则表示相应的信号量被设置;如果该位为 0,则表示相应的信号量未被设置。
unsigned int qurt_signal2_wait(qurt_signal2_t *signal, unsigned int mask, unsigned int options); 用于等待带有两个信号量的信号量对象中指定的信号量被触发。其中参数 signal 是要等待的信号量对象的指针,而参数 mask 是一个 32 位无符号整数,表示要等待的信号量掩码。掩码中每个位代表一个信号量,如果该位为 1,则表示相应的信号量需要被触发;如果该位为 0,则表示相应的信号量不需要被触发。参数 options 则指定等待信号量的选项,例如是否超时等。它返回一个 32 位无符号整数,表示哪些信号量已被触发。返回值中每个位代表一个信号量,如果该位为 1,则表示相应的信号量已被触发;如果该位为 0,则表示相应的信号量未被触发。
void qurt_timer_create(qurt_timer_t *timer, const char *name); 用于创建一个新的定时器。其中参数 timer 是指向要创建的定时器对象的指针,参数 name 是定时器的名称(可以为 NULL)。
void qurt_timer_delete(qurt_timer_t timer); 用于删除一个已经创建的定时器。其中参数 timer 是要删除的定时器对象。
void qurt_timer_start(qurt_timer_t timer, uint32_t duration); 用于启动一个定时器,并指定定时器的超时时间。其中参数 timer 是要启动的定时器对象,参数 duration 是定时器的超时时间(以 tick 为单位)。
void qurt_timer_stop(qurt_timer_t timer); 用于停止一个已经运行的定时器。其中参数 timer 是要停止的定时器对象。
qurt_thread_t qurt_thread_get_id(void); 用于获取当前线程的 ID
int qurt_mem_region_create(qurt_mem_region_t *region, unsigned int size, qurt_mem_cache_mode_t cache_attrib, qurt_mem_region_type_t type); 用于创建一个内存区域对象,并分配指定大小的内存空间。其中参数 region 是指向要创建的内存区域对象的指针,参数 size 指定内存区域的大小,而 cache_attribtype 分别指定内存区域的缓存属性和类型。返回一个整数值,表示是否成功创建内存区域。如果成功,则返回 0;否则返回一个负数错误代码。
int qurt_mem_region_delete(qurt_mem_region_t region); 用于删除指定的内存区域对象,并释放其占用的内存空间。其中参数 region 是要删除的内存区域对象的句柄。返回一个整数值,表示是否成功删除内存区域。如果成功,则返回 0;否则返回一个负数错误代码。
void qurt_mem_region_attr_init(qurt_mem_region_attr_t *attr); 用于初始化一个内存区域属性对象。其中参数 attr 是指向要初始化的内存区域属性对象的指针。
int qurt_mem_pool_create(qurt_mem_pool_t *pool, void *baseaddr, unsigned int size, qurt_mem_cache_mode_t cache_attrib); 用于创建一个内存池对象,并分配指定大小的内存空间。其中参数 pool 是指向要创建的内存池对象的指针,参数 baseaddr 指定内存池的起始地址,而 sizecache_attrib 分别指定内存池的大小和缓存属性。返回一个整数值,表示是否成功创建内存池。如果成功,则返回 0;否则返回一个负数错误代码。
int qurt_mem_pool_delete(qurt_mem_pool_t pool); 用于删除指定的内存池对象,并释放其占用的内存空间。其中参数 pool 是要删除的内存池对象的句柄。返回一个整数值,表示是否成功删除内存池。如果成功,则返回 0;否则返回一个负数错误代码。
int qurt_pipe_create(qurt_pipe_t *pipe, unsigned int pipe_type, unsigned int pipe_elements, unsigned int elem_size); 用于创建一个管道对象,并分配指定大小的内存空间。其中参数 pipe 是指向要创建的管道对象的指针,参数 pipe_type 指定管道类型,参数 pipe_elements 指定管道元素个数,而 elem_size 指定每个管道元素的大小。 返回一个整数值,表示是否成功创建管道。如果成功,则返回 0;否则返回一个负数错误代码。
int qurt_pipe_delete(qurt_pipe_t pipe); 用于删除指定的管道对象,并释放其占用的内存空间。其中参数 pipe 是要删除的管道对象的句柄。返回一个整数值,表示是否成功删除管道。如果成功,则返回 0;否则返回一个负数错误代码。
int qurt_pipe_send(qurt_pipe_t pipe_id, void *buf, unsigned int size, unsigned int timeout); 用于向指定的管道发送数据。其中参数 pipe_id 是要发送数据的管道对象的句柄,参数 buf 指向要发送的数据缓冲区,参数 size 指定要发送的数据大小,而 timeout 指定等待发送操作完成的超时时间(单位为 ticks)。 返回一个整数值,表示是否成功发送数据。如果成功,则返回 0;否则返回一个负数错误代码。
int qurt_pipe_receive(qurt_pipe_t pipe_id, void *buf, unsigned int size, unsigned int *recv_size, unsigned int timeout); 用于从指定的管道接收数据。其中参数 pipe_id 是要接收数据的管道对象的句柄,参数 buf 指向接收数据的缓冲区,参数 size 指定要接收的数据大小,而 recv_size 是一个指针,用于返回实际接收到的数据大小。参数 timeout 指定等待接收操作完成的超时时间(单位为 ticks)。返回一个整数值,表示是否成功接收数据。如果成功,则返回 0;否则返回一个负数错误代码。

4.2 演示示例

4.2.1 QuRT 创建线程示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <stdio.h>
#include "qurt.h"

void task1(void *arg) {
printf("Task 1 is running...\n");
printf("Task 1 is done.\n");
}

void task2(void *arg) {
printf("Task 2 is running...\n");
printf("Task 2 is done.\n");
}

int main() {
qurt_thread_t t1, t2;
qurt_thread_attr_t attr;

qurt_thread_attr_init(&attr);
qurt_thread_create(&t1, &attr, (void (*)(void *))task1, NULL);
qurt_thread_create(&t2, &attr, (void (*)(void *))task2, NULL);

qurt_thread_join(t1, NULL);
qurt_thread_join(t2, NULL);

return 0;
}

在上述的示例中,我们使用 qurt_thread_create() 函数创建了两个线程,分别执行 task1()task2() 函数,并使用 qurt_thread_join() 函数等待它们结束。
注意: 在开发过程中,需要根据实际情况合理使用内存管理函数和多任务调度函数,并避免出现死锁、资源泄漏等问题。

4.2.2 QuRT 互斥锁示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include "qurt.h"
#include <stdio.h>

// 共享资源
int global_counter = 0;

// 互斥锁对象
static qurt_mutex_t mutex;

int main() {
// 初始化互斥锁对象
qurt_mutex_init(&mutex);

// 创建两个线程,同时访问共享资源
qurt_thread_t thread1, thread2;
qurt_thread_create(&thread1, NULL, increment_global_counter, NULL);
qurt_thread_create(&thread2, NULL, increment_global_counter, NULL);

// 等待两个线程结束
qurt_thread_join(thread1, NULL);
qurt_thread_join(thread2, NULL);

// 输出最终结果
printf("Global counter: %d\n", global_counter);

return 0;
}

void increment_global_counter(void *arg) {
for (int i = 0; i < 1000000; ++i) {
// 获取互斥锁
qurt_mutex_lock(&mutex);

// 访问共享资源
++global_counter;

// 释放互斥锁
qurt_mutex_unlock(&mutex);
}
}

在上面这个示例程序中,

  • 我们首先使用 qurt_mutex_init() 函数初始化了一个互斥锁对象。
  • 然后创建了两个线程,它们都会调用 increment_global_counter() 函数来增加全局计数器 global_counter 的值。由于多个线程可能同时访问该共享资源,因此在访问之前需要先获取互斥锁,以避免竞争条件的发生。在 increment_global_counter() 函数中,我们使用 qurt_mutex_lock() 函数获取互斥锁,并使用 qurt_mutex_unlock() 函数释放互斥锁。
  • 最后,我们在主函数中输出了最终的计数器值。

4.2.3 QuRT 信号量示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include "qurt.h"
#include <stdio.h>

// 共享资源
int global_counter = 0;

// 信号量对象
static qurt_signal_t sem;

int main() {
// 初始化信号量对象
qurt_signal_init(&sem);

// 创建两个线程,分别增加和减少全局计数器的值
qurt_thread_t thread1, thread2;
qurt_thread_create(&thread1, NULL, increment_global_counter, NULL);
qurt_thread_create(&thread2, NULL, decrement_global_counter, NULL);

// 等待两个线程结束
qurt_thread_join(thread1, NULL);
qurt_thread_join(thread2, NULL);

// 输出最终结果
printf("Global counter: %d\n", global_counter);

return 0;
}

void increment_global_counter(void *arg) {
for (int i = 0; i < 1000000; ++i) {
// 等待信号量
qurt_signal_wait(&sem, 1, QURT_SIGNAL_ATTR_WAIT_ANY, NULL);

// 访问共享资源
++global_counter;

// 触发信号量
qurt_signal_set(&sem, 1);
}
}

void decrement_global_counter(void *arg) {
for (int i = 0; i < 1000000; ++i) {
// 等待信号量
qurt_signal_wait(&sem, 1, QURT_SIGNAL_ATTR_WAIT_ANY, NULL);

// 访问共享资源
--global_counter;

// 触发信号量
qurt_signal_set(&sem, 1);
}
}

在上述的示例程序中,

  • 我们首先使用 qurt_signal_init() 函数初始化了一个信号量对象。
  • 然后创建了两个线程,一个增加全局计数器的值,一个减少全局计数器的值。由于多个线程同时访问该共享资源,因此需要使用信号量进行同步。在每个线程中,我们使用 qurt_signal_wait() 函数等待信号量,当信号量触发时才能访问共享资源,并使用 qurt_signal_set() 函数释放信号量。
  • 接着 使用 qurt_thread_join() 函数等待两个线程结束;
  • 最后输出最终结果。

4.2.4 QuRT 定时器示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include "qurt.h"
#include <stdio.h>

// 定时器对象
static qurt_timer_t timer;

// 定时器回调函数
void timer_callback(int arg) {
printf("Timer expired\n");
}

int main() {
// 创建定时器对象
qurt_timer_create(&timer, NULL);

// 启动定时器
qurt_timer_start(timer, 1000);

// 注册定时器回调函数
qurt_timer_set_attr(timer, QURT_TIMER_ATTR_CALLBACK_FUNCTION, (void *)timer_callback);
qurt_timer_set_attr(timer, QURT_TIMER_ATTR_CALLBACK_ARGUMENT, (void *)0);

// 等待定时器超时
while (1) {
qurt_timer_sleep(10);
}

// 停止定时器
qurt_timer_stop(timer);

// 删除定时器对象
qurt_timer_delete(timer);

return 0;
}

在上述的示例程序中,

  • 我们首先使用 qurt_timer_create() 函数创建了一个定时器。
  • 然后使用 qurt_timer_start() 函数启动了该定时器,并指定了定时器的超时时间(1000 毫秒)。
  • 接着使用 qurt_timer_set_attr() 函数注册了定时器回调函数。
  • 最后进入一个无限循环,每隔 10 毫秒调用 qurt_timer_sleep() 函数进入休眠状态,等待定时器超时。当定时器超时时,将触发定时器回调函数 timer_callback(),输出一条消息。

注意: 在程序结束时需要使用 qurt_timer_stop() 停止定时器,并使用 qurt_timer_delete() 删除定时器对象。

4.2.5 QuRT 共享内存区域示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include "qurt.h"
#include <stdio.h>

#define SHM_SIZE 1024

int main() {
// 创建共享内存区域
qurt_mem_region_t shm;
qurt_mem_region_attr_t attr;
qurt_mem_region_attr_init(&attr);
qurt_mem_region_create(&shm, SHM_SIZE, QURT_MEM_CACHE_NONE, QURT_MEM_REGION_SHARED | QURT_MEM_REGION_PERM_READ | QURT_MEM_REGION_PERM_WRITE);

// 在共享内存区域中写入数据
char *buf = (char *)qurt_mem_region_get_vaddr(&shm);
sprintf(buf, "Hello, shared memory!");

// 打印从共享内存区域中读取的数据
printf("%s\n", buf);

// 删除共享内存区域
qurt_mem_region_delete(shm);

return 0;
}

在上述这个示例程序中,

  • 我们首先使用 qurt_mem_region_create() 函数创建了一个大小为 SHM_SIZE 的共享内存区域,并设置其缓存属性为 QURT_MEM_CACHE_NONE,类型为 QURT_MEM_REGION_SHARED,并且具有读写权限。
  • 然后,在共享内存区域中写入了一些数据,并使用 printf() 函数打印了从共享内存区域中读取的数据。
  • 最后,使用 qurt_mem_region_delete() 函数删除了共享内存区域。

4.2.6 QuRT 使用管道进行进程间通信的示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include "qurt.h"
#include <stdio.h>

#define PIPE_SIZE 1024

int main() {
// 创建管道
qurt_pipe_t pipe;
qurt_pipe_create(&pipe, QURT_PIPE_ATTR_BLOCKING | QURT_PIPE_ATTR_PIPE_TYPE_BYTE_QUEUE, PIPE_SIZE, 1);

// 创建子进程
qurt_thread_t child;
qurt_thread_create(&child, NULL, child_thread, (void *)&pipe);

// 向管道发送数据
char msg[] = "Hello, pipe!";
qurt_pipe_send(pipe, msg, sizeof(msg), QURT_TIME_WAIT_FOREVER);

// 等待子进程结束
qurt_thread_join(child, NULL);

// 删除管道
qurt_pipe_delete(pipe);

return 0;
}

void child_thread(void *arg) {
// 从管道接收数据
char buf[PIPE_SIZE];
unsigned int recv_size;
qurt_pipe_receive(*(qurt_pipe_t *)arg, buf, PIPE_SIZE, &recv_size, QURT_TIME_WAIT_FOREVER);

// 打印从管道中接收到的数据
printf("%s\n", buf);
}

在上述示例程序中,

  • 我们首先使用 qurt_pipe_create() 函数创建一个大小为 1024 字节的管道对象,属性设置为阻塞式字节队列。
  • 然后我们使用 qurt_thread_create() 函数创建了一个名为 child 的子线程,并将管道对象传递给它。我们在 child_thread() 函数中调用了 qurt_pipe_receive() 函数来从管道接收数据,然后使用 printf() 函数打印出接收到的字符串。
  • 接着我们定义了一个字符串 msg,并使用 qurt_pipe_send() 函数向管道发送该字符串。
  • 最后我们使用 qurt_pipe_delete() 函数删除了管道对象。

C语言函数大全--p 开头的函数

总览

函数声明 函数功能
void perror(const char *s); 用于将当前错误码对应的错误信息打印到标准输出设备(通常是终端)。
void pieslice(int x, int y, int stanle, int endangle, int radius); 在图形模式下绘制并填充一个扇形(饼图切片)
double pow(double x, double y); 用于计算 x 的 y 次幂,并返回结果(double)
float powf(float x, float y); 用于计算 x 的 y 次幂,并返回结果(float)
long double powl(long double x, long double y); 用于计算 x 的 y 次幂,并返回结果(long double)
double pow10(double x); 用于计算 $10^x$ (double)
float pow10f(float x); 用于计算 $10^x$(float)
long double pow10l(long double x); 用于计算 $10^x$ (long double)
int printf(const char *format, ...); 它是标准 I/O 库中定义的函数,用于将格式化的数据输出到标准输出流(通常是控制台窗口)
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg); 创建一个新的线程
int pthread_join(pthread_t thread, void **retval); 阻塞当前线程,等待指定的线程结束。
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr); 初始化互斥锁。返回值为 0 表示成功,否则表示失败。
int pthread_mutex_destroy(pthread_mutex_t *mutex); 销毁互斥锁。返回值为 0 表示成功,否则表示失败。
int pthread_mutex_lock(pthread_mutex_t *mutex); 尝试获取互斥锁,如果已经被占用,则会阻塞当前线程。返回值为 0 表示成功获取互斥锁,否则表示失败。
int pthread_mutex_unlock(pthread_mutex_t *mutex); 释放互斥锁。
int putc(int c, FILE *stream); 它是标准 I/O 库中定义的函数,用于将一个字符输出到指定的文件流。
int putchar(int c); 它是标准 I/O 库中定义的函数,用于将一个字符输出到标准输出流(通常是控制台窗口)。
int putenv(char *string); 用于设置环境变量的值。
void putimage(int left, int top, void *bitmap, int op); 用于将位图图像输出到指定的窗口或屏幕上
void putpixel(int x, int y, int color); 用于将一个像素点画在指定的位置上
int puts(const char *s); 用于将一个字符串输出到标准输出流
int putw(int w, FILE *stream); 用于将一个整数值以二进制形式写入到指定的文件中。

1. perror

1.1 函数说明

函数声明 函数功能
void perror(const char *s); 用于将当前错误码对应的错误信息打印到标准输出设备(通常是终端)。

参数:

  • s : 用于描述错误类型或者出错的上下文信息。它会在该信息后面追加当前错误码对应的错误信息,并且自动换行。

1.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>
#include <errno.h>

int main() {
FILE *fp = fopen("tempfile.txt", "r");
if (fp == NULL) {
perror("Failed to open file");
printf("Error code: %d\n", errno);
}
return 0;
}

在上述的示例中,

  • 我们首先尝试打开一个不存在的文件,并通过 fopen() 函数返回的值来检查是否成功。由于该文件不存在,fopen() 函数将返回 NULL
  • 然后我们可以使用 perror() 函数来输出一个错误消息和具体的错误信息,以帮助我们找到问题所在。如果发生了错误,errno 全局变量会被设置为一个非零值,我们还可以使用它来获取具体的错误代码。

1.3 运行结果

2. pieslice

2.1 函数说明

函数声明 函数功能
void pieslice(int x, int y, int stanle, int endangle, int radius); 在图形模式下绘制并填充一个扇形(饼图切片)

参数:

  • x : 圆心的x 坐标
  • y : 圆心的y 坐标
  • startangle : 圆弧的起始角度(以度为单位)
  • endangle : 圆弧的结束角度(以度为单位)
    • radius : 圆的半径

2.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <graphics.h>

int main() {
int gdriver = DETECT, gmode;
int midx, midy;
int stangle = 45, endangle = 135, radius = 100;

initgraph(&gdriver, &gmode, ""); // 初始化图形窗口

midx = getmaxx() / 2;
midy = getmaxy() / 2;

setcolor(YELLOW); // 设置画笔颜色为黄色
setfillstyle(EMPTY_FILL, getmaxcolor()); // 设置填充样式。
// 绘制一个半径为100像素、起始角度为45度、结束角度为135度的圆弧
pieslice(midx, midy, stangle, endangle, radius);

getch(); // 等待用户按键
closegraph(); // 关闭图形窗口
return 0;
}

2.3 运行结果

3. pow,powf,powl

3.1 函数说明

函数声明 函数功能
double pow(double x, double y); 用于计算 x 的 y 次幂,并返回结果(double)
float powf(float x, float y); 用于计算 x 的 y 次幂,并返回结果(float)
long double powl(long double x, long double y); 用于计算 x 的 y 次幂,并返回结果(long double)

3.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>
#include <math.h>

int main() {
double result = pow(2.0, 3.5);
printf("The result of pow(2.0, 3.5) is: %.20lf\n", result);

float resultf = powf(2.0f, 3.5f);
printf("The result of powf(2.0f, 3.5f) is: %.20f\n", resultf);

long double resultL = powl(2.0L, 3.5L);
printf("The result of powl(2.0L, 3.5L) is: %.20Lf\n", resultL);
return 0;
}

3.3 运行结果

4. pow10,pow10f,pow10l

4.1 函数说明

函数声明 函数功能
double pow10(double x); 用于计算 $10^x$ (double)
float pow10f(float x); 用于计算 $10^x$(float)
long double pow10l(long double x); 用于计算 $10^x$ (long double)

4.2 演示示例

1
2
3
4
5
6
7
8
#include <stdio.h>
#include <math.h>

int main() {
double result = pow10(-2.0);
printf("The result is: %lf\n", result);
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
#include <cmath>

int main() {
float result = std::pow10f(-2.0f);
std::cout << "10^-2 = " << result << std::endl;

long double result = std::pow10l(-2.0L);
std::cout << "10^-2 = " << result << std::endl;

return 0;
}

5. printf

5.1 函数说明

函数声明 函数功能
int printf(const char *format, ...); 它是标准 I/O 库中定义的函数,用于将格式化的数据输出到标准输出流(通常是控制台窗口)
参数:
  • format : 一个格式化字符串
  • 可变参数 : 任意数量,这些可变参数会根据格式化字符串进行格式化,并被输出到标准输出流。

返回值 :

  • 成功打印的字符数。

5.2 演示示例

1
2
3
4
5
6
7
8
#include <stdio.h>

int main() {
printf("Hello, world!\n");
char name[20] = "Huazie";
printf("My name is %s", name);
return 0;
}

5.3 运行结果

6. pthread_create,pthread_join

6.1 函数说明

函数声明 函数功能
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg); 创建一个新的线程
int pthread_join(pthread_t thread, void **retval); 阻塞当前线程,等待指定的线程结束。

pthread_create 参数:

  • thread : 指向线程标识符的指针,用于返回新创建线程的标识符
  • attr : 指向线程属性结构体的指针,用于指定线程的属性,通常为 NULL 表示使用默认属性
  • start_routine : 指向线程函数的指针,用于指定线程的入口点
  • arg : 传递给线程函数的参数,可以为任意类型的指针。

pthread_join 参数:

  • pthread_t thread :目标线程的标识符(由 pthread_create() 返回)。必须是已创建且未被分离(non-detached)的线程。
  • void **retval :用于接收目标线程的退出状态值的指针的地址。
    • 若目标线程通过 return 返回值或调用 pthread_exit(void *retval) 终止,retval 将指向该值。
    • 若不需要获取退出状态,可设为 NULL
    • 若目标线程被取消,retval 会被设为 PTHREAD_CANCELED(通常为 -1)。

6.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>
#include <pthread.h>

void *thread_func(void *arg) {
printf("Hello from the new thread!\n");
return NULL;
}

int main() {
pthread_t thread;
int ret = pthread_create(&thread, NULL, thread_func, NULL);
if (ret != 0) {
printf("Failed to create thread!\n");
return -1;
}

pthread_join(thread, NULL);

printf("Hello from the main thread!\n");
return 0;
}

在上述的示例中,主线程调用了 pthread_create() 函数来创建一个新的线程,并传递一个函数指针 thread_func 作为新线程的入口点。新线程运行这个函数,并输出一条消息。主线程等待新线程结束,然后继续运行自己的代码。

6.3 运行结果

7. pthread_mutex_init,pthread_mutex_destroy,pthread_mutex_lock,pthread_mutex_unlock

7.1 函数说明

函数声明 函数功能
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr); 初始化互斥锁。返回值为 0 表示成功,否则表示失败。
int pthread_mutex_destroy(pthread_mutex_t *mutex); 销毁互斥锁。返回值为 0 表示成功,否则表示失败。
int pthread_mutex_lock(pthread_mutex_t *mutex); 尝试获取互斥锁,如果已经被占用,则会阻塞当前线程。返回值为 0 表示成功获取互斥锁,否则表示失败。
int pthread_mutex_unlock(pthread_mutex_t *mutex); 释放互斥锁。

参数:

  • mutex : 指向互斥锁对象的指针。
  • attr : 指向线程属性结构体的指针,用于指定互斥锁对象的属性,通常为 NULL 表示使用默认属性。

7.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <stdio.h>
#include <pthread.h>

pthread_mutex_t mutex;

void *thread_func(void *arg) {
printf("Thread %d: Attempting to lock the mutex.\n", (int)arg);

pthread_mutex_lock(&mutex);

printf("Thread %d: Locked the mutex!\n", (int)arg);
// ... Critical section code ...
printf("Thread %d: Unlocking the mutex.\n", (int)arg);

pthread_mutex_unlock(&mutex);

return NULL;
}

int main() {
pthread_t thread1, thread2;
int ret;

ret = pthread_mutex_init(&mutex, NULL);
if (ret != 0) {
printf("Failed to initialize mutex!\n");
return -1;
}

ret = pthread_create(&thread1, NULL, thread_func, (void *)1);
if (ret != 0) {
printf("Failed to create thread 1!\n");
return -1;
}

ret = pthread_create(&thread2, NULL, thread_func, (void *)2);
if (ret != 0) {
printf("Failed to create thread 2!\n");
return -1;
}

pthread_join(thread1, NULL);
pthread_join(thread2, NULL);

pthread_mutex_destroy(&mutex);

return 0;
}

在上述的示例中,两个线程分别调用了 pthread_mutex_lock()pthread_mutex_unlock() 函数来保护临界区代码,以确保同时只有一个。

7.3 运行结果

8. putc

8.1 函数说明

函数声明 函数功能
int putc(int c, FILE *stream); 它是标准 I/O 库中定义的函数,用于将一个字符输出到指定的文件流。

参数:

  • c : 要输出的字符
  • stream : 指向目标文件流的指针

返回值:

  • 成功输出的字符的 ASCII 码

8.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>

int main() {
FILE *fp;
char *str = "Hello, world!\n";

fp = fopen("output.txt", "w");
if (fp == NULL) {
printf("Failed to open file for writing!\n");
return -1;
}

int i = 0;
while (str[i] != '\0') {
putc(str[i], fp);
i++;
}

fclose(fp);

return 0;
}

在上述的示例中,我们打开名为 output.txt 的文件以供写入,并使用 putc() 函数将字符串中的每个字符逐一输出到文件中。最后,我们关闭文件。

注意:putchar() 函数类似,putc() 函数可以用来逐一输出字符串中的每个字符,但通常会更多地用于将数据写入文件或其他输出流。

8.3 运行结果

9. putchar

9.1 函数说明

函数声明 函数功能
int putchar(int c); 它是标准 I/O 库中定义的函数,用于将一个字符输出到标准输出流(通常是控制台窗口)。

参数:

  • c : 要输出的字符

返回值 :

  • 成功输出,则返回该字符的 ASCII 码值

9.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>

int main() {
putchar('H');
putchar('e');
putchar('l');
putchar('l');
putchar('o');
putchar(',');
putchar(' ');
putchar('w');
putchar('o');
putchar('r');
putchar('l');
putchar('d');
putchar('!');
putchar('\n');
return 0;
}

注意: 单引号用于表示字符常量,例如 ‘H’ 表示字符 H 的 ASCII 码。

9.3 运行结果

10. putenv

10.1 函数说明

函数声明 函数功能
int putenv(char *string); 用于设置环境变量的值。

参数:

  • string : 字符串参数,格式为 name=value,其中 name 是要设置的环境变量的名称,value 是要为其设置的值。

返回值:

  • 0 表示成功;
  • 0 表示失败。

10.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
#include <stdlib.h>

int main() {
char *var = "MY_VAR=hello";
int ret = putenv(var);
if (ret != 0) {
printf("Failed to set environment variable!\n");
return -1;
}

char *val = getenv("MY_VAR");
printf("The value of MY_VAR is: %s\n", val);

return 0;
}

在上述的示例中,

  • 我们首先使用 putenv() 函数将一个名为 MY_VAR 的环境变量设置为字符串 "hello"
  • 然后,我们使用 getenv() 函数获取 MY_VAR 环境变量的值;
  • 最后使用 printf() 函数输出它。

注意: 由于 putenv() 函数接受一个指向可变字符串的指针,因此应该避免将局部变量的地址传递给它,以免在函数返回后出现未定义行为。

10.3 运行结果

11. putimage

11.1 函数说明

函数声明 函数功能
void putimage(int left, int top, void *bitmap, int op); 用于将位图图像输出到指定的窗口或屏幕上

参数:

  • left: 表示位图左上角的 x 坐标
  • top: 表示位图左上角的 y 坐标
  • bitmap: 一个指向位图数据的指针,这个数据必须按照指定格式存储
  • op: 表示绘制位图的方式,可以为以下值之一:
    • COPY_PUT:覆盖模式,即将位图完全覆盖到目标位置。
    • AND_PUT:按位与模式,即将位图与目标位置进行按位与运算后输出。
    • OR_PUT:按位或模式,即将位图与目标位置进行按位或运算后输出。
    • XOR_PUT:按位异或模式,即将位图与目标位置进行按位异或运算后输出。

11.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <graphics.h>

#define ARROW_SIZE 10

void draw_arrow(int x, int y);

int main(void)
{
int gdriver = DETECT, gmode;
void *arrow;
int x, y, maxx;
unsigned int size;

initgraph(&gdriver, &gmode, "");

maxx = getmaxx();
x = 0;
y = getmaxy() / 2;

draw_arrow(x, y);

size = imagesize(x, y-ARROW_SIZE, x+(4*ARROW_SIZE), y+ARROW_SIZE);

arrow = malloc(size);

getimage(x, y-ARROW_SIZE, x+(4*ARROW_SIZE), y+ARROW_SIZE, arrow);

while (!kbhit())
{
putimage(x, y-ARROW_SIZE, arrow, XOR_PUT);

x += ARROW_SIZE;
if (x >= maxx)
x = 0;

putimage(x, y-ARROW_SIZE, arrow, XOR_PUT);
}

free(arrow);
closegraph();
return 0;
}

void draw_arrow(int x, int y)
{
moveto(x, y);
linerel(4*ARROW_SIZE, 0);
linerel(-2*ARROW_SIZE, -1*ARROW_SIZE);
linerel(0, 2*ARROW_SIZE);
linerel(2*ARROW_SIZE, -1*ARROW_SIZE);
}

上述程序使用了 graphics.h 图形库来画一个箭头,并在屏幕上循环移动它。

  • 首先,程序初始化图形库,然后调用 getmaxx()getmaxy() 函数获取屏幕的宽度和高度。
  • 接着,程序调用 draw_arrow() 函数来绘制箭头图形,并使用 imagesize() 函数计算出需要分配给位图数据的内存大小。
  • 接下来,程序使用 malloc() 函数动态分配了一块内存空间,并调用 getimage() 函数获取箭头图像的位图数据。该函数会将指定位置的屏幕区域保存到指定的内存地址中。
  • 最后,程序进入一个循环,在每次迭代中先使用 putimage() 函数将之前存储的箭头图像覆盖掉屏幕上的箭头,然后将箭头向右移动一定的距离。当用户按下任意键时,程序结束循环并退出。

11.3 运行结果

12. putpixel

12.1 函数说明

函数声明 函数功能
void putpixel(int x, int y, int color); 用于将一个像素点画在指定的位置上

参数:

  • x: 表示要绘制像素的 x 坐标
  • y: 表示要绘制像素的 y 坐标
  • color: 表示要绘制的像素颜色,通常为一个整数值。

12.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <graphics.h>
#include <time.h>

#define PIXEL_COUNT 1000
#define DELAY_TIME 100

int main(void)
{
int gdriver = DETECT, gmode;
int i, x, y, color, maxx, maxy, maxcolor, seed;

initgraph(&gdriver, &gmode, "");

maxx = getmaxx() + 1;
maxy = getmaxy() + 1;
maxcolor = getmaxcolor() + 1;

while (!kbhit())
{
srand((unsigned)time(NULL));
for (i=0; i<PIXEL_COUNT; i++)
{
x = rand() % maxx + 1;
y = rand() % maxy + 1;
color = rand() % maxcolor + 1;
putpixel(x, y, color);
}

delay(DELAY_TIME);
}

getch();
closegraph();
return 0;
}

上述这个程序使用 graphics.h 图形库在屏幕上绘制随机像素点,并不断更新它们的颜色。

  • 首先,程序初始化图形库,并调用 getmaxx()getmaxy()getmaxcolor() 函数获取屏幕的尺寸和颜色范围。
  • 接着,程序进入一个循环,在每次迭代中使用 rand() 函数生成随机的坐标和颜色值,并使用 putpixel() 函数绘制对应位置的像素点。另外还使用了 delay() 函数来控制每次更新之间的时间间隔,该函数会使程序暂停指定的毫秒数,以便让用户观察到像素点的变化效果。
  • 最后当用户按下任意键时,程序退出循环并结束执行。

12.3 运行结果

13. puts

13.1 函数说明

函数声明 函数功能
int puts(const char *s); 用于将一个字符串输出到标准输出流

参数:

  • s: 要输出的以 '\0' 结尾的字符串

返回值:

  • 成功输出的字符数(包括换行符)

13.2 演示示例

1
2
3
4
5
6
7
#include <stdio.h>

int main() {
char *str = "Hello, world!";
puts(str);
return 0;
}

注意: 在输出字符串时,puts() 函数会自动将字符串的内容和换行符写入到标准输出流中,因此不需要再进行额外的操作。如果要将字符串输出到文件或其他输出流中,则可以使用 fputs() 函数。

13.3 运行结果

14. putw

14.1 函数说明

函数声明 函数功能
int putw(int w, FILE *stream); 用于将一个整数值以二进制形式写入到指定的文件中。

参数:

  • w : 要写入的整数值
  • stream : 指向要写入的文件的指针。

返回值:

  • 如果成功,则返回写入的字节数(通常为 4 个字节);
  • 如果发生错误,则返回 EOF

14.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>

int main() {
int num = 42;
FILE *fp = fopen("output.bin", "wb");

putw(num, fp);

fclose(fp);
return 0;
}

在上述的示例中,

  • 我们首先定义了一个整数变量,并使用 fopen() 函数打开一个名为 "output.bin" 的二进制文件;
  • 接着,我们调用 putw() 函数将整数值写入到该文件中;
  • 最后关闭文件并结束程序。

注意: 由于 putw() 函数是以二进制形式写入数据的,因此相对于文本文件而言,它更适合用于存储数字、结构体等复杂类型的数据。如果要将字符串或其他文本数据写入到文件中,则可以使用 fprintf() 函数。

14.3 运行结果

参考

  1. [API Reference Document]

C语言函数大全--o 开头的函数

总览

函数声明 函数功能
void obstack_init(struct obstack *obstack_ptr); 它是 POSIX 标准库中的一个非标准函数,用于初始化对象堆栈。对象堆栈是一种可以动态增长以存储任意类型的对象的数据结构。其中,obstack_ptr 参数是一个指向 struct obstack 类型的指针,表示要初始化的对象堆栈。
void obstack_free(struct obstack *obstack_ptr, void *object_ptr); 用于释放通过对象堆栈分配的所有内存。其中,obstack_ptr 参数是一个指向 struct obstack 类型的指针,表示要释放的对象堆栈;object_ptr 参数是要释放的内存块。
void *obstack_alloc(struct obstack *obstack_ptr, int size); 用于从对象堆栈中分配指定大小的内存,并返回其地址。其中,obstack_ptr 参数是一个指向 struct obstack 类型的指针,表示要从中分配内存的对象堆栈;size 参数表示要分配的内存块的大小。
void *obstack_blank(struct obstack *obstack_ptr, int size); 用于向对象堆栈添加指定数量的空间,并返回指向添加的第一个字节的指针。其中,obstack_ptr 参数是一个指向 struct obstack 类型的指针,表示要添加空间的对象堆栈;size 参数表示要添加的空间大小。
void *obstack_grow(struct obstack *obstack_ptr, const void *data, int size); 用于将数据复制到对象堆栈,并返回指向添加的第一个字节的指针。其中,obstack_ptr 参数是一个指向 struct obstack 类型的指针,表示要添加数据的对象堆栈;data 参数是要复制的数据的指针;size 参数表示要复制的数据的大小。
#define offsetof(type, member) ((size_t)(&((type *)0)->member)) 它是一个宏,用于获取结构体中某个成员的偏移量。
int open(const char *path, int oflag, ...); 用于打开文件
int openat(int dirfd, const char *pathname, int flags, mode_t mode); 它是 Linux 系统定义的一个函数,它可以打开一个相对于指定目录的文件。与 open() 函数相比,openat() 函数更加灵活,并支持更多的选项。
DIR *opendir(const char *name); 它是 POSIX 标准定义的一个函数,用于打开目录并返回一个指向 DIR 结构体类型的指针。
int openpty(int *amaster, int *aslave, char *name, const struct termios *termp, const struct winsize *winp); 它是 POSIX 标准定义的一个函数,用于打开一个伪终端(PTY)并返回与之关联的主从设备文件描述符。伪终端可以用于在进程之间建立通信,或者在程序中模拟终端行为。
int on_exit(void (*function)(int, void *), void *arg); 它是 POSIX 标准定义的一个函数,用于在进程退出时调用注册的回调函数。这个函数可以用于在程序异常退出或者正常退出时执行一些清理工作、记录日志等操作
void outtext(char *textstring); 在图形视区显示一个字符串
void outtextxy(int x, int y, char *textstring); 在指定位置显示一字符串

1. obstack_init,obstack_free,obstack_alloc,obstack_blank,obstack_grow

1.1 函数说明

函数声明 函数功能
void obstack_init(struct obstack *obstack_ptr); 它是 POSIX 标准库中的一个非标准函数,用于初始化对象堆栈。对象堆栈是一种可以动态增长以存储任意类型的对象的数据结构。其中,obstack_ptr 参数是一个指向 struct obstack 类型的指针,表示要初始化的对象堆栈。
void obstack_free(struct obstack *obstack_ptr, void *object_ptr); 用于释放通过对象堆栈分配的所有内存。其中,obstack_ptr 参数是一个指向 struct obstack 类型的指针,表示要释放的对象堆栈;object_ptr 参数是要释放的内存块。
void *obstack_alloc(struct obstack *obstack_ptr, int size); 用于从对象堆栈中分配指定大小的内存,并返回其地址。其中,obstack_ptr 参数是一个指向 struct obstack 类型的指针,表示要从中分配内存的对象堆栈;size 参数表示要分配的内存块的大小。
void *obstack_blank(struct obstack *obstack_ptr, int size); 用于向对象堆栈添加指定数量的空间,并返回指向添加的第一个字节的指针。其中,obstack_ptr 参数是一个指向 struct obstack 类型的指针,表示要添加空间的对象堆栈;size 参数表示要添加的空间大小。
void *obstack_grow(struct obstack *obstack_ptr, const void *data, int size); 用于将数据复制到对象堆栈,并返回指向添加的第一个字节的指针。其中,obstack_ptr 参数是一个指向 struct obstack 类型的指针,表示要添加数据的对象堆栈;data 参数是要复制的数据的指针;size 参数表示要复制的数据的大小。

1.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <obstack.h>

int main(void)
{
struct obstack my_obstack;
const char *str1 = "Hello, ";
const char *str2 = "World!";
char *dst;

obstack_init(&my_obstack);

dst = (char *)obstack_alloc(&my_obstack, strlen(str1) + strlen(str2) + 1);
strcpy(dst, str1);
strcat(dst, str2);

printf("%s\n", (char *)my_obstack.chunk);

dst = (char *)obstack_blank(&my_obstack, sizeof(int)*2);
int a = 100;
int b = 200;
memcpy(dst, &a, sizeof(int));
memcpy(dst+sizeof(int), &b, sizeof(int));

printf("%d %d\n", *(int *)(my_obstack.next_free-sizeof(int)*2), *(int *)(my_obstack.next_free-sizeof(int)));

double d = 3.1415926;
dst = (char *)obstack_grow(&my_obstack, &d, sizeof(double));

printf("%f\n", *(double *)(my_obstack.next_free-sizeof(double)));

obstack_free(&my_obstack, NULL);

return 0;
}

在上述的程序中,

  • 我们首先定义一个名为 my_obstackstruct obstack 类型变量,并将其传递给 obstack_init() 函数以初始化对象堆栈。
  • 接着,我们使用 obstack_alloc() 函数从对象堆栈中分配一块内存,并将两个字符串连接起来。
  • 然后,我们使用 obstack_blank() 函数向对象堆栈添加一块指定大小的空间,并使用 memcpy() 函数将两个整数复制到该空间中。
  • 接下来,我们使用 obstack_grow() 函数向对象堆栈添加一个双精度浮点数,并返回指向该浮点数的指针。
  • 最后,我们使用 printf() 函数将连接后的字符串、添加的整数和添加的双精度浮点数输出到终端,并使用 obstack_free() 函数释放通过对象堆栈分配的所有内存。

注意:在使用 obstack_blank() 函数向对象堆栈添加空间时,建议使用 sizeof 运算符来计算要添加的空间大小,并在使用 memcpy() 复制数据时也应该小心不要越界。同时,在使用 obstack_grow() 函数向对象堆栈添加数据时,需要小心指针是否正确,并且操作前需要先使用 memcpy() 将要添加的数据复制到一个临时变量中。

2. offsetof

2.1 宏说明

宏定义 宏描述
#define offsetof(type, member) ((size_t)(&((type *)0)->member)) 它是一个宏,用于获取结构体中某个成员的偏移量。

参数:

  • type : 表示结构体类型
  • member : 表示结构体中的一个成员变量名

返回值: 一个 size_t 类型的值,表示该成员变量在结构体中的偏移量(单位是字节)。

2.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
#include <stddef.h>

struct example {
int a;
char b;
double c;
};

int main(void)
{
size_t offset_b = offsetof(struct example, b);
printf("Offset of 'b' in struct example: %zu\n", offset_b);

return 0;
}

在这个程序中,

  • 我们定义了一个名为 example 的结构体类型,并使用 offsetof 宏获取结构体中成员变量 b 的偏移量。
  • 最后,我们使用 printf() 函数将结果输出到终端。

注意: 在使用 offsetof 宏时,结构体类型名称必须使用括号括起来,否则代码会产生语法错误。此外,offsetof 宏的参数必须是已定义的结构体类型名称和该结构体类型中的成员变量名称,否则也会导致编译错误。

3. open

3.1 函数说明

函数声明 函数功能
int open(const char *path, int oflag, ...); 用于打开文件

参数:

  • path : 表示要打开的文件路径
  • oflag : 表示打开文件时的选项标志,可以为以下常量之一或多个按位或组合而成:
    • O_RDONLY:只读模式打开文件。
    • O_WRONLY:只写模式打开文件。
    • O_RDWR:读写模式打开文件。
    • O_CREAT:如果文件不存在,则创建它。
    • O_TRUNC:如果文件已存在,则将其长度截断为 0。
    • O_APPEND:在文件末尾追加数据。
  • 可选参数 : 表示文件所有者、组和其他用户的访问权限。如果使用了 O_CREAT 选项,则必须提供这个参数

3.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>

int main(void)
{
int fd = open("temp.txt", O_RDONLY);
if (fd == -1) {
perror("open");
exit(1);
}

char buf[1024];
ssize_t nread;
while ((nread = read(fd, buf, sizeof(buf))) > 0) {
if (write(STDOUT_FILENO, buf, nread) != nread) {
perror("write");
exit(1);
}
}

if (nread == -1) {
perror("read");
exit(1);
}

if (close(fd) == -1) {
perror("close");
exit(1);
}

return 0;
}

在上述的程序中,

  • 我们使用 open() 函数打开文件 temp.txt,并通过 read() 函数读取其中的数据。
  • 然后,我们使用 write() 函数将数据写入标准输出,直到读取完整个文件。
  • 最后,我们使用 close() 函数关闭文件。

注意: 在使用 open() 函数打开文件时,返回值为负数则表示出现了错误。此时可以使用 perror() 函数输出错误信息,并使用 exit() 函数退出程序。同时,在使用 read() 函数和 write() 函数读写文件时也需要小心处理返回值,以避免出现不可预期的错误。

3.3 运行结果

4. openat

4.1 函数说明

函数声明 函数功能
int openat(int dirfd, const char *pathname, int flags, mode_t mode); 它是 Linux 系统定义的一个函数,它可以打开一个相对于指定目录的文件。与 open() 函数相比,openat() 函数更加灵活,并支持更多的选项。

参数:

  • dirfd : 表示要打开文件所在目录的文件描述符。如果传递的是 AT_FDCWD,则表示使用当前工作目录。
  • pathname : 表示要打开的文件路径
  • flags : 表示打开文件时的选项标志,可以为以下常量之一或多个按位或组合而成:
    • O_RDONLY:只读模式打开文件。
    • O_WRONLY:只写模式打开文件。
    • O_RDWR:读写模式打开文件。
    • O_CREAT:如果文件不存在,则创建它。
    • O_TRUNC:如果文件已存在,则将其长度截断为 0。
    • O_APPEND:在文件末尾追加数据。
    • O_DIRECTORY:要求打开的文件必须是一个目录。
    • O_NOFOLLOW:不跟随符号链接打开文件。
  • mode : 表示文件所有者、组和其他用户的访问权限。如果使用了 O_CREAT 选项,则必须提供这个参数

4.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <dirent.h>

int main(void)
{
int dirfd = open(".", O_RDONLY | O_DIRECTORY);
if (dirfd == -1) {
perror("open");
exit(1);
}

DIR *dirp = fdopendir(dirfd);
if (dirp == NULL) {
perror("fdopendir");
exit(1);
}

struct dirent *entry;
while ((entry = readdir(dirp)) != NULL) {
printf("%s\n", entry->d_name);
}

if (closedir(dirp) == -1) {
perror("closedir");
exit(1);
}

return 0;
}

在这个程序中,

  • 我们使用 openat() 函数打开当前目录,并通过 fdopendir() 函数将文件描述符转换为目录流。
  • 然后,我们使用 readdir() 函数读取目录中的文件,并将文件名输出到终端。
  • 最后,我们使用 closedir() 函数关闭目录。

注意: 在使用 openat() 函数打开文件时,可以通过传递不同的文件描述符指定要打开的目录,从而实现更加灵活的操作。此外,在使用 readdir() 函数读取目录时也需要注意判断返回值是否为 NULL,以避免出现不可预期的错误。

5. opendir

5.1 函数说明

函数声明 函数功能
DIR *opendir(const char *name); 它是 POSIX 标准定义的一个函数,用于打开目录并返回一个指向 DIR 结构体类型的指针。

参数:

  • name : 表示要打开的目录路径

返回值:

  • 如果该函数执行成功,则返回一个指向 DIR 类型的指针;
  • 否则返回 NULL

5.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>

int main(void)
{
DIR *dirp = opendir(".");
if (dirp == NULL) {
perror("opendir");
exit(1);
}

struct dirent *entry;
while ((entry = readdir(dirp)) != NULL) {
printf("%s\n", entry->d_name);
}

if (closedir(dirp) == -1) {
perror("closedir");
exit(1);
}

return 0;
}

在上述的程序中,我们使用 opendir() 函数打开当前目录,并通过 readdir() 函数读取目录中的文件名,最后使用 closedir() 函数关闭目录。

注意: 在使用 opendir() 函数打开目录时,返回值为 NULL 则表示出现了错误。此时可以使用 perror() 函数输出错误信息,并使用 exit() 函数退出程序。同时,在使用 readdir() 函数读取目录时也需要小心处理返回值,以避免出现不可预期的错误。

6. openpty

6.1 函数说明

函数声明 函数功能
int openpty(int *amaster, int *aslave, char *name, const struct termios *termp, const struct winsize *winp); 它是 POSIX 标准定义的一个函数,用于打开一个伪终端(PTY)并返回与之关联的主从设备文件描述符。伪终端可以用于在进程之间建立通信,或者在程序中模拟终端行为。

参数:

  • amaster : 表示要返回的主设备文件描述符
  • aslave : 表示要返回的从设备文件描述符
  • name : 表示从设备名称的缓冲区,如果不需要则可以传递 NULL
  • termp : 表示要使用的终端属性,如果不需要则可以传递 NULL
  • winp : 表示要使用的窗口大小,如果不需要则可以传递 NULL

返回值:

  • 如果该函数执行成功,则返回值为 0
  • 否则返回 -1

6.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>

int main(void)
{
int master, slave;
char buf[1024];
ssize_t nread;

if (openpty(&master, &slave, NULL, NULL, NULL) == -1) {
perror("openpty");
exit(1);
}

printf("Slave device: /dev/pts/%d\n", slave);

while ((nread = read(STDIN_FILENO, buf, sizeof(buf))) > 0) {
if (write(master, buf, nread) != nread) {
perror("write");
exit(1);
}
}

if (nread == -1) {
perror("read");
exit(1);
}

if (close(master) == -1) {
perror("close");
exit(1);
}

return 0;
}

在上述的程序中,

  • 我们使用 openpty() 函数打开一个伪终端,并通过 read() 函数读取标准输入中的数据。
  • 然后,我们将数据写入主设备文件描述符;
  • 最后关闭该设备。

注意: 在使用 openpty() 函数打开伪终端时,返回值为 -1 则表示出现了错误。此时可以使用 perror() 函数输出错误信息,并使用 exit() 函数退出程序。同时,在使用 read() 函数和 write() 函数读写文件时也需要小心处理返回值,以避免出现不可预期的错误。

7. on_exit

7.1 函数说明

函数声明 函数功能
int on_exit(void (*function)(int, void *), void *arg); 它是 POSIX 标准定义的一个函数,用于在进程退出时调用注册的回调函数。这个函数可以用于在程序异常退出或者正常退出时执行一些清理工作、记录日志等操作

参数:

  • function : 表示要注册的回调函数
  • arg : 表示传递给回调函数的参数

返回值:

  • 如果该函数执行成功,则返回值为 0
  • 否则返回 -1

7.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

void cleanup(int status, void *arg)
{
printf("Cleanup function called with status %d\n", status);
}

int main(void)
{
if (on_exit(cleanup, NULL) != 0) {
perror("on_exit");
exit(EXIT_FAILURE);
}

printf("This is the main program\n");

return 0;
}

在如上的程序中,

  • 我们使用 on_exit() 函数注册了一个回调函数 cleanup(),并将其参数设置为 NULL。
  • 然后,在主函数中输出了一条消息。当程序退出时,会自动调用回调函数来进行清理操作。

8. outtext

8.1 函数说明

函数声明 函数功能
void outtext(char *textstring); 在图形视区显示一个字符串

参数:

  • char *textstring :指向以空字符(’\0’)结尾的字符串的指针。

8.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <graphics.h>

int main(void)
{
int gdriver = DETECT, gmode, errorcode;
int midx, midy;

initgraph(&gdriver, &gmode, "");

midx = getmaxx() / 2;
midy = getmaxy() / 2;

moveto(midx, midy);

outtext("This ");
outtext("is ");
outtext("a ");
outtext("test.");

getch();
closegraph();
return 0;
}

在上述的程序中,

  • 我们首先调用 initgraph() 函数初始化图形系统;
  • 然后获取窗口的中心坐标;
  • 接着使用 moveto() 函数将当前绘图位置移动到屏幕中心。
  • 最后,使用 outtext() 函数输出一段文字,然后等待用户按下任意键,并关闭图形窗口。

8.3 运行结果

9. outtextxy

9.1 函数说明

函数声明 函数功能
void outtextxy(int x, int y, char *textstring); 在指定位置显示一字符串

参数:

  • int x : 字符串输出的水平起始坐标(单位为像素)。取值范围:与当前图形模式的屏幕分辨率相关(例如,640x480 模式下,x 范围为 0 到 639)。

  • int y : 字符串输出的垂直起始坐标(单位为像素)。取值范围:与当前图形模式的屏幕分辨率相关(例如,480p 模式下,y 范围为 0 到 479)。

  • char *textstring : 指向以空字符(’\0’)结尾的字符串的指针。

9.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <graphics.h>

int main(void)
{
int gdriver = DETECT, gmode, errorcode;
int x, y;

initgraph(&gdriver, &gmode, "");

x = getmaxx() / 2;
y = getmaxy() / 2;

outtextxy(x, y, "Hello, world!");

getch();
closegraph();
return 0;
}

在上述这个程序中,

  • 我们首先通过 initgraph() 函数初始化图形系统并创建一个窗口;
  • 然后,定义了一个坐标位置 (x, y) 并使用 outtextxy() 函数在该位置输出一段文本。
  • 最后,使用 getch 函数等待用户按下任意键,然后关闭图形窗口。

9.3 运行结果

C语言函数大全--n 开头的函数

总览

函数声明 函数功能
double nan(const char *tagp); 用于返回一个表示 NaN(非数值)的 double 类型数字
int nanosleep(const struct timespec *req, struct timespec *rem); 用于暂停当前进程的执行一段指定的时间。相比于 sleep() 函数,nanosleep() 函数可以精确地指定等待时间,以纳秒为单位。
double nearbyint(double x); 用于将一个浮点数四舍五入到最接近的整数值(double)
float nearbyintf(float x); 用于将一个浮点数四舍五入到最接近的整数值(float)
long double nearbyintl(long double x); 用于将一个浮点数四舍五入到最接近的整数值(long double)
double nextafter(double x, double y); 用于找出与给定的浮点数最接近的下一个浮点数(double)
float nextafterf(float x, float y); 用于找出与给定的浮点数最接近的下一个浮点数(float)
long double nextafterl(long double x, long double y); 用于找出与给定的浮点数最接近的下一个浮点数(long double)
double nexttoward(double x, long double y); 用于找出与给定的浮点数最接近、并朝着指定方向的下一个浮点数(double)
float nexttowardf(float x, long double y); 用于找出与给定的浮点数最接近、并朝着指定方向的下一个浮点数(float)
long double nexttowardl(long double x, long double y); 用于找出与给定的浮点数最接近、并朝着指定方向的下一个浮点数(long double)
locale_t newlocale(int category_mask, const char *locale, locale_t base); 用于创建并返回一个新的本地化环境变量,以便在不同的本地化设置之间进行切换。
int nftw(const char *dirpath, int (*fn)(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf), int nopenfd, int flags); 用于递归遍历指定目录下的所有文件和子目录,并对每个文件或目录执行指定操作。
int nice(int inc); 它是一个系统调用,可将进程截止到当前用户的最大优先级减少指定的优先级,以更改进程的调度优先级。较高的 niceness 值意味着较低的优先级。
char *nl_langinfo(nl_item item); 它是一个 POSIX 标准函数,用于获取当前本地化环境下的语言环境信息。它可以返回一些与语言、货币、日期和时间格式等相关的信息。
long nrand48(unsigned short xsubi[3]); 用于生成带有指定状态的随机数。它使用 48 位整数来表示随机数的状态,可以方便地切换不同的随机数生成器状态。
uint32_t ntohl(uint32_t netlong); 用于将网络字节序(大端序)转换为主机字节序(小端序)。
uint16_t ntohs(uint16_t netshort); 用于将网络字节序(大端序)转换为主机字节序(小端序)。

1. nan

1.1 函数说明

函数声明 函数功能
double nan(const char *tagp); 用于返回一个表示 NaN(非数值)的 double 类型数字

参数:

  • tagp : 指向字符串的指针;用于指定 NaN 数字的类型。如果不需要指定类型,则可以将该参数设置为 NULL。

1.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
#include <math.h>

int main(void)
{
double x = 0.0 / 0.0; // 使用除 0 运算符来生成 NaN 数字
printf("x: %f\n", x);

double y = nan(NULL); // 使用 nan() 函数来生成 NaN 数字
printf("y: %f\n", y);

return 0;
}

注意: NaN 数字具有一些特殊的属性,例如与任何数字进行比较都会返回 false,因此在实际编程中需要特别小心处理 NaN 的情况,避免出现异常结果

1.3 运行结果

2. nanosleep

2.1 函数说明

函数声明 函数功能
int nanosleep(const struct timespec *req, struct timespec *rem); 用于暂停当前进程的执行一段指定的时间。相比于 sleep() 函数,nanosleep() 函数可以精确地指定等待时间,以纳秒为单位。

参数:

  • req : 指向 timespec 结构体的指针,用于指定要等待的时间。timespec 结构体包含两个成员变量:tv_sec 表示等待时间的整数部分(秒),tv_nsec 表示等待时间的小数部分(纳秒)。如果 rem 参数不为 NULL,则在函数返回时,未完成的等待时间将被存储在 rem 指向的 timespec 结构体中。
  • rem : 未完成的等待时间

2.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
#include <time.h>

int main(void)
{
struct timespec req = { 0 };
req.tv_sec = 2; // 等待时间为 2 秒
req.tv_nsec = 5000000; // 加上 5 毫秒

int ret = nanosleep(&req, NULL);
if (ret == 0) {
printf("nanosleep completed\n");
} else {
printf("nanosleep interrupted by signal\n");
}

return 0;
}

在上述的程序中,

  • 我们首先创建一个 timespec 结构体变量 req,用于指定等待时间。在本例中,我们将等待时间设置为 2 秒加上 5 毫秒。
  • 接着,我们调用 nanosleep() 函数,并传递 req 变量的地址作为第一个参数。如果函数执行成功(即完成了预定的等待时间),则返回值为 0,否则返回 -1
  • 最后,我们检查函数的返回值,以确定 nanosleep() 是否成功完成。如果返回值为 0,则表示函数已经完成了预定的等待时间;如果返回值为 -1,则说明函数被信号中断。在实际编程中,我们还可以通过检查 errno 变量来获取更具体的错误信息。

3. nearbyint,nearbyintf,nearbyintl

3.1 函数说明

函数声明 函数功能
double nearbyint(double x); 用于将一个浮点数四舍五入到最接近的整数值(double)
float nearbyintf(float x); 用于将一个浮点数四舍五入到最接近的整数值(float)
long double nearbyintl(long double x); 用于将一个浮点数四舍五入到最接近的整数值(long double)

3.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>
#include <math.h>

int main(void)
{
double x = 2.3;
double y = -1.8;

double z = nearbyint(x); // 将 2.3 四舍五入到 2
double w = nearbyint(y); // 将 -1.8 四舍五入到 -2

printf("x: %lf, nearbyint(x): %lf\n", x, z);
printf("y: %lf, nearbyint(y): %lf\n", y, w);

float xf = 2.5;
printf("xf: %f, nearbyintf(xf): %f\n", xf, nearbyintf(xf));

long double xL = -1.3;
printf("xL: %Lf, nearbyintl(xL): %Lf\n", xL, nearbyintl(xL));

return 0;
}

注意: nearbyint() 函数对于 0.5 的情况具有特殊处理:如果要转换的数恰好与两个整数的距离相等,则按照偶数方向进行舍入(即选择更接近偶数的整数)。例如,如果要将 2.5 转换为整数,那么将近似到最接近的偶数 2,而不是 3。这种舍入方式称为 “银行家舍入法”“四舍六入五成双”

3.3 运行结果

4. nextafter,nextafterf,nextafterl

4.1 函数说明

函数声明 函数功能
double nextafter(double x, double y); 用于找出与给定的浮点数最接近的下一个浮点数(double)
float nextafterf(float x, float y); 用于找出与给定的浮点数最接近的下一个浮点数(float)
long double nextafterl(long double x, long double y); 用于找出与给定的浮点数最接近的下一个浮点数(long double)

参数:

  • x : 要查找其下一个浮点数的浮点数
    • y : 给定浮点数的目标值,表示前进方向。

返回值:

  • 如果 y 大于 x,则向正无穷方向查找;
  • 如果 y 小于 x,则向负无穷方向查找;如果 y 等于 x,则返回 y

4.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>
#include <math.h>

int main(void)
{
double x = 1.0;
double y = 2.0;

printf("nextafter(%lf, %lf): %.20lf\n", x, y, nextafter(x, y));
printf("nextafter(%lf, %lf): %.20lf\n", y, x, nextafter(y, x));

float xf = 2.0;
float yf = 1.0;
printf("nextafterf(%f, %f): %.20f\n", xf, yf, nextafterf(xf, yf));

long double xL = -1.2;
long double yL = - 1.5;
printf("nextafterl(%Lf, %Lf): %.20Lf\n", xL, yL, nextafterl(xL, yL));

return 0;
}

注意: 由于计算机内部存储浮点数的方式是有限制的,因此在进行浮点数计算时可能会存在误差。在实际编程中,我们应该特别小心处理这些情况,避免出现异常结果。

4.3 运行结果

5. nexttoward,nexttowardf,nexttowardl

5.1 函数说明

函数声明 函数功能
double nexttoward(double x, long double y); 用于找出与给定的浮点数最接近、并朝着指定方向的下一个浮点数(double)
float nexttowardf(float x, long double y); 用于找出与给定的浮点数最接近、并朝着指定方向的下一个浮点数(float)
long double nexttowardl(long double x, long double y); 用于找出与给定的浮点数最接近、并朝着指定方向的下一个浮点数(long double)

参数:

  • x : 要查找其下一个浮点数的浮点数
  • y : 给定浮点数的目标值,表示前进方向。

返回值:

  • 如果 y 大于 x,则向正无穷方向查找;
  • 如果 y 小于 x,则向负无穷方向查找;如果 y 等于 x,则返回 y

5.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
#include <math.h>

int main(void)
{
double x = 1.0;
long double y = 2.0;

printf("nexttoward(%lf, %Lf): %.20lf\n", x, y, nexttoward(x, y));

float xf = 3.2;
printf("nexttowardf(%f, %Lf): %.20f\n", xf, y, nexttowardf(xf, y));

long double xL = 1.9;
printf("nexttowardl(%Lf, %Lf): %.20Lf\n", xL, y, nexttowardl(xL, y));

return 0;
}

5.3 运行结果

6. newlocale

6.1 函数说明

函数声明 函数功能
locale_t newlocale(int category_mask, const char *locale, locale_t base); 用于创建并返回一个新的本地化环境变量,以便在不同的本地化设置之间进行切换。

参数:

  • category_mask : 指定了要创建的本地化环境变量包含哪些类别。可以使用下列常量按位或来指定:
    • LC_ALL_MASK:表示所有类别。
    • LC_COLLATE_MASK:表示字符串比较和排序规则。
    • LC_CTYPE_MASK:表示字符分类和转换规则。
    • LC_MESSAGES_MASK:表示本地化消息文本。
    • LC_MONETARY_MASK:表示货币格式。
    • LC_NUMERIC_MASK:表示数字格式。
    • LC_TIME_MASK:表示时间和日期格式。
  • locale : 指定了要使用的区域设置名称。如果为 NULL 或空字符串,则使用当前系统默认的本地化设置。
  • base : 指定了要基于的基础本地化环境变量。如果为 NULL,则使用 LC_GLOBAL_LOCALE

6.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
#include <locale.h>

int main()
{
// 创建一个新的本地化环境变量,用于解析德语字符串比较和排序规则。
locale_t loc = newlocale(LC_COLLATE_MASK, "de_DE.UTF-8", LC_GLOBAL_LOCALE);

// 在新的本地化环境变量下比较两个字符串,并输出比较结果。
const char *str1 = "äbc";
const char *str2 = "abc";
int result = strcoll_l(str1, str2, loc);
printf("%s %s %s\n", str1, (result < 0 ? "<" : (result > 0 ? ">" : "==")), str2);

// 释放本地化环境变量
freelocale(loc);

return 0;
}

在上述程序中,

  • 我们首先使用 newlocale() 函数创建一个新的本地化环境变量 loc,以便比较和排序德语字符串。
  • 接着,我们使用 strcoll_l() 函数来在新的本地化环境变量下比较两个字符串 str1str2
  • 最后,我们输出比较结果,并使用 freelocale() 函数释放 loc 变量。

注意: 在实际编程中应该特别注意本地化设置对字符处理、货币格式、时间格式等方面的影响,避免出现不必要的错误。

7. nftw

7.1 函数说明

函数声明 函数功能
int nftw(const char *dirpath, int (*fn)(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf), int nopenfd, int flags); 用于递归遍历指定目录下的所有文件和子目录,并对每个文件或目录执行指定操作。

参数:

  • dirpath : 要遍历的目录路径
  • fn : 一个回调函数,用于在遍历过程中对每个文件或目录执行指定操作。该函数的参数如下:
    • fpath : 当前文件的完整路径。
    • sb : 当前文件的 struct stat 结构体指针,包含了当前文件的各种属性信息。
    • typeflag : 表示当前文件的类型,可能为以下值之一:
      • FTW_F:普通文件。
      • FTW_D:目录。
      • FTW_DNR:无法读取的目录。
      • FTW_NS:无法访问的文件(可能是因为权限问题)。
      • FTW_SL:符号链接。
      • FTW_DP:与 FTW_D 相同,但目录本身还未被访问。
      • FTW_SLN:符号链接,指向不存在的文件。
    • ftwbuf : 一个 struct FTW 结构体指针,包含了一些关于遍历状态的信息。
  • nopenfd : 最大打开文件描述符数
  • flags : 控制遍历行为的标志位,可以使用下列常量按位或来指定:
    • FTW_CHDIR:进入目录后更改工作目录。
    • FTW_DEPTH:深度优先遍历。
    • FTW_MOUNT:不跨越文件系统边界。
    • FTW_PHYS:不跟随符号链接。

7.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <stdio.h>
#include <stdlib.h>
#include <ftw.h>

static int count = 0;

int print_file_info(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf)
{
// 打印文件路径和类型
printf("%s ", fpath);
if (typeflag == FTW_F) {
printf("(file)\n");
} else if (typeflag == FTW_D) {
printf("(dir)\n");
} else {
printf("(other)\n");
}

// 计数器加一
count++;

return 0;
}

int main(void)
{
int result = nftw(".", print_file_info, 10, FTW_PHYS);

if (result == -1) {
perror("nftw");
exit(EXIT_FAILURE);
}

printf("Total files and directories: %d\n", count);

return 0;
}

在上述的程序中,

  • 我们首先定义了一个回调函数 print_file_info(),用于打印每个文件或目录的路径和类型,并将计数器加一。
  • 接着,我们调用 nftw() 函数来递归遍历当前目录下的所有文件和子目录,并对每个文件或目录执行 print_file_info() 函数。
  • 最后,我们输出遍历总数。

注意: 在实际编程中应该特别注意文件访问权限等问题,以避免出现不必要的错误。

7.3 运行结果

8. nice

8.1 函数说明

函数声明 函数功能
int nice(int inc); 它是一个系统调用,可将进程截止到当前用户的最大优先级减少指定的优先级,以更改进程的调度优先级。较高的 niceness 值意味着较低的优先级。

参数:

  • inc : 要增加或减少的优先级值。如果 inc 的值为正数,则表示将进程的优先级降低;如果 inc 的值为负数,则表示将进程的优先级提高。通常情况下,只有具有 root 权限的进程才能将自己的优先级升高。

8.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
#include <unistd.h>

int main(void)
{
// 输出当前进程的初始优先级
printf("Initial nice value: %d\n", nice(0));

// 将进程的优先级减少 10
int result = nice(10);
if (result == -1) {
perror("nice");
} else {
printf("New nice value: %d\n", result);
}

return 0;
}

在上述程序中,

  • 我们首先使用 nice(0) 函数输出当前进程的初始优先级;
  • 接着,我们使用 nice(10) 函数将进程的调度优先级降低 10
  • 最后将新的优先级值输出到终端。

注意: 由于 nice() 函数并不是标准 C 库中的函数,因此在编译时需要传递 -posix 参数或其他类似参数以启用 POSIX 标准。在实际编程中应该特别注意优先级修改对进程正常运行的影响,以避免出现不必要的错误。

9. nl_langinfo

9.1 函数说明

函数声明 函数功能
char *nl_langinfo(nl_item item); 它是一个 POSIX 标准函数,用于获取当前本地化环境下的语言环境信息。它可以返回一些与语言、货币、日期和时间格式等相关的信息。

参数:

  • item : 指定要获取的本地化信息。可以使用下列常量之一来指定:
    • ABDAY_*:星期缩写名称(0 ~ 6 表示周日到周六)。
    • DAY_*:星期全称(0 ~ 6 表示周日到周六)。
    • ABMON_*:月份缩写名称(0 ~ 11 表示一月到十二月)。
    • MON_*:月份全称(0 ~ 11 表示一月到十二月)。
    • AM_STR:上午字符串。
    • PM_STR:下午字符串。
    • D_FMT:日期格式字符串。
    • T_FMT:时间格式字符串。
    • ERA:纪元字符串。
    • ERA_D_T_FMT:带日期和时间的纪元字符串。
    • ERA_D_FMT:仅带日期的纪元字符串。
    • ERA_T_FMT:仅带时间的纪元字符串。
    • ALT_DIGITS:非十进制数字字符。

9.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
#include <langinfo.h>

int main(void)
{
char *time_fmt = nl_langinfo(T_FMT);
char *date_fmt = nl_langinfo(D_FMT);

printf("Time format: %s\n", time_fmt);
printf("Date format: %s\n", date_fmt);

return 0;
}

在上述的程序中,

  • 我们使用 nl_langinfo(T_FMT) 函数获取当前本地化环境下的时间格式字符串,并将其输出到终端。
  • 接着,我们使用 nl_langinfo(D_FMT) 函数获取当前本地化环境下的日期格式字符串,并将其输出到终端。

注意: 在实际编程中应该特别注意处理不同本地化环境下信息的差异,以避免出现不必要的错误。

10. nrand48

10.1 函数说明

函数声明 函数功能
long nrand48(unsigned short xsubi[3]); 用于生成带有指定状态的随机数。它使用 48 位整数来表示随机数的状态,可以方便地切换不同的随机数生成器状态。

参数:

  • xsubi : 一个包含 316 位无符号整数的数组,表示了当前随机数生成器的状态。如果想更改随机数生成器的状态,只需修改 xsubi 数组即可。

10.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(void)
{
unsigned short seed[3];
seed[0] = (unsigned short) time(NULL);
seed[1] = (unsigned short) getpid();
seed[2] = 12345;

srand48(seed);

printf("Random number: %ld\n", nrand48(seed));

return 0;
}

在上述的程序中,

  • 我们首先创建了一个包含 316 位无符号整数的数组 seed,并将其用作随机数生成器的种子。
  • 接着,我们使用 srand48() 函数初始化随机数生成器,并使用 nrand48() 函数生成一个随机数,并将其输出到终端。

注意: 由于 nrand48() 函数生成的是伪随机数,因此在实际使用时需要注意选择足够复杂的种子,并采取适当的加密措施以避免出现不必要的安全问题。

11. ntohl,ntohs

11.1 函数说明

函数声明 函数功能
uint32_t ntohl(uint32_t netlong); 用于将网络字节序(大端序)转换为主机字节序(小端序)。
uint16_t ntohs(uint16_t netshort); 用于将网络字节序(大端序)转换为主机字节序(小端序)。

参数:

  • netlong : 表示要转换的 32 位整数。
  • netshort : 表示要转换的 16 位整数。

11.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>
#include <stdint.h>
#include <netinet/in.h>

int main(void)
{
uint32_t num1 = 0x12345678;
uint16_t num2 = 0x5678;

printf("Original value (hex):\n");
printf("num1: %08X\n", num1);
printf("num2: %04X\n", num2);

num1 = ntohl(num1);
num2 = ntohs(num2);

printf("Converted value (hex):\n");
printf("num1: %08X\n", num1);
printf("num2: %04X\n", num2);

return 0;
}

注意: 在实际编程中应该特别注意不同平台之间的字节序差异,以避免出现不必要的错误。