toward baidu programming

本文详细介绍了C语言中文件操作的基础知识,包括stat、fstat、lstat函数的使用方法及struct stat结构体的解析。此外,还讲解了size_t类型的跨平台应用,wchar_t类型在国际化程序中的作用,sockaddr_in结构体在网络编程中的应用,以及sprintf函数的使用注意事项。
函数原型:
int stat(const char *restrict pathname, struct stat *restrict buf);           restrict,C语言中的一种类型限定符(Type Qualifiers),用于告诉编译器,对象已经被指针所引用,不能通过除该指针外所有其他直接或间接的方式修改该对象的内容。
提供文件名字,获取文件对应属性。
int fstat(int filedes, struct stat *buf);
通过文件描述符获取文件对应的属性。
int lstat(const char *restrict pathname, struct stat *restrict buf);
连接文件描述命,获取文件属性。


文件对应的属性
struct stat {
        mode_t     st_mode;       //文件对应的模式,文件,目录等
        ino_t      st_ino;       //inode节点号
        dev_t      st_dev;        //设备号码
        dev_t      st_rdev;       //特殊设备号码
        nlink_t    st_nlink;      //文件的连接数
        uid_t      st_uid;        //文件所有者
        gid_t      st_gid;        //文件所有者对应的组
        off_t      st_size;       //普通文件,对应的文件字节数
        time_t     st_atime;      //文件最后被访问的时间
        time_t     st_mtime;      //文件内容最后被修改的时间
        time_t     st_ctime;      //文件状态改变时间
        blksize_t st_blksize;    //文件内容对应的块大小
        blkcnt_t   st_blocks;     //伟建内容对应的块数量
      };
示例:
#include < sys/stat.h >
#include < stdio.h >


int main() {
    struct stat buf;
    stat("/etc/hosts", &buf);
    printf("/etc/hosts file size = %d\n", buf.st_size);

}





在C++中,设计 size_t 就是为了适应多个平台的 。size_t的引入增强了程序在不同平台上的可移植性。size_t是针对系统定制的一种数据类型,一般是整型,因为C/C++标准只定义一最低的位数,而不是必需的固定位数。而且在内存里,对数的高位对齐存储还是低位对齐存储各系统都不一样。为了提高代码的可移植性,就有必要定义这样的数据类型。一般这种类型都会定义到它具体占几位内存等。当然,有些是编译器或系统已经给定义好的。经测试发现,在32位系统中size_t是4字节的,而在64位系统中,size_t是8字节的,这样利用该类型可以增强程序的可移植性。




wchar_t是C/C++的字符类型,是一种扩展的存储方式。wchar_t类型主要用在国际化程序的实现中,但它不等同于uni编码。uni编码的字符一般以wchar_t类型存储。




sockaddr_in(在netinet/in.h中定义):
struct sockaddr_in
{
 
short sin_family;/*Address family一般来说AF_INET(地址族)PF_INET(协议族)*/
 
unsigned short sin_port;/*Port number(必须要采用网络数据格式,普通数字可以用htons()函数转换成网络数据格式的数字)*/
 
struct in_addr sin_addr;/*IP address in network byte order(Internet address)*/
 
unsigned char sin_zero[8];/*Same size as struct sockaddr没有实际意义,只是为了 跟SOCKADDR结构在内存中对齐*/
 

};

struct sockaddr 这个结构体是linux的网络编程接口中用来表示IP地址的标准结构体,bind、connect等函数中都需要这个结构体,这个结构体是兼容IPV4和IPV6的。在实际编程中这个结构体会被一个struct sockaddr_in所填充。


AF_INET=2(又称 PF_INET)是 IPv4 网络协议的套接字类型,AF_INET6 =10  则是 IPv6 的;而 AF_UNIX 则是 Unix 系统本地通信。
选择 AF_INET 的目的就是使用 IPv4 进行通信。因为 IPv4 使用 32 位地址,相比 IPv6 的 128 位来说,计算更快,便于用于局域网通信。

而且 AF_INET 相比 AF_UNIX 更具通用性,因为 Windows 上有 AF_INET 而没有 AF_UNIX。



sprintf指的是字符串格式化命令,主要功能是把格式化的数据写入某个字符串中。sprintf 是个变参函数。使用sprintf 对于写入buffer的字符数是没有限制的,这就存在了buffer溢出的可能性。sprintf(s, "%d", 123); //产生"123"


atoi:功能:将任意类型的数字转换为字符串。在<stdlib.h>中与之有相反功能的函数是atoi。



不同的CPU有不同的字节顺序类型,这些字节顺序类型指的是整数在内存中保存的顺序,即主机字节顺序。常见的有两种:
序号
英文名
中文名
描述
1
big-endian
大尾顺序
地址的低位存储值的高位
2
little-endian
小尾顺序
地址的低位存储值的低位

相关函数:fork, execle, execlp, execv, execve, execvp
头文件:#include <unistd.h>
函数定义:int execl(const char *path, const char *arg, ...);
函数说明:execl()用来执行参数path字符串所代表的文件路径, 接下来的参数代表执行该文件时传递的argv[0],argv[1].....最后一个参数必须用空指针NULL作结束。
返回值 :成功则不返回值, 失败返回-1, 失败原因存于errno中
范例:
/* 执行 /bin/ls -al /ect/passwd */
#include <unistd.h>/*** File: execl.c**/
main()
{
execl("/bin/ls", "ls", "-al", "/etc/passwd", (char *) 0);
} 或
#include <unistd.h>/*** File: execl.c**/
int main()
{
char args[]=" -l";
execl("/bin/ls","ls","-al","/etc/",NULL);
return 0;
}
[cnscn@test c]$ make execl
gcc execl.c -o execl
[cnscn@test c]$ ./execl
-rw-r--r-- 1 root root 2218 Jan 13 11:36 /etc/passwd
本词条缺少信息栏、名片图,补充相关内容使词条更完整,还能快速升级,赶紧来编辑吧!
execl()其中后缀"l"代表list也就是参数列表的意思,第一参数path字符指针所指向要执行的文件路径, 接下来的参数代表执行该文件时传递的参数列表:argv[0],argv[1]... 最后一个参数须用空指针NULL作结束。
### Godot 中 `move_toward` 函数的使用说明 在 Godot 引擎中,`move_toward` 是一个非常实用的工具函数,用于平滑地将某个数值逐步接近目标值。它不仅适用于简单的数值操作,还广泛应用于游戏开发中的对象移动逻辑。 #### 函数签名 ```gdscript Vector2 move_toward(Vector2 current, Vector2 target, float delta) const ``` - **参数解释** - `current`: 当前的位置或值。 - `target`: 目标位置或值。 - `delta`: 单次调用的最大变化量,控制移动的速度。 - **返回值**: 返回一个新的向量,表示当前值朝着目标值移动了一定的距离,但不超过指定的 `delta` 值。 --- #### 功能描述 `move_toward` 的核心功能是以受控的方式让某变量逐渐逼近另一个目标值。如果两者之间的距离小于等于 `delta`,则直接到达目标;否则仅前进一段固定的距离[^1]。 这种行为非常适合模拟物理效果、AI 追踪逻辑以及任何需要平稳过渡的场景。 --- #### 示例代码 以下是几个典型的使用案例: ##### 1. 敌人追踪玩家 假设敌人需要缓慢靠近玩家角色,则可以利用 `move_toward` 实现这一需求: ```gdscript func chase_state(): # 设置动画状态为跑步 animation_player.play("Run") # 计算方向并调整翻转 var direction = Globals.last_Player.position - global_position if direction.x < 0: sprite.flip_h = true else: sprite.flip_h = false # 更新全局位置,使其逐步靠近玩家 global_position = global_position.move_toward(Globals.last_Player.position, SPEED * delta) ``` 在此例子中,`global_position` 表示敌人的当前位置,而 `Globals.last_Player.position` 则是玩家的目标位置。通过乘以时间步长 (`delta`) 和速度常数 (`SPEED`) 来动态调节每次更新的实际位移大小。 --- ##### 2. 平滑减速停止 当希望物体能够优雅地停下来而不是瞬间静止时,也可以借助此方法完成处理: ```gdscript extends KinematicBody2D const MAX_SPEED = 300.0 var velocity := Vector2.ZERO func _physics_process(delta): var input_direction = Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down").normalized() if input_direction.length() > 0: velocity = velocity.move_toward(input_direction * MAX_SPEED, 10.0) else: velocity = velocity.move_toward(Vector2.ZERO, 5.0) position += velocity * delta ``` 这段脚本展示了如何基于输入指令改变实体的速度矢量,并且无论是否有按键按下都会应用相应的加减速机制来保持流畅感[^2]. --- ##### 3. 绘制像素级线条 除了常规的游戏玩法外,“逐点生成路径”的场合同样适用该技术。比如下面这个绘制直线的例子就很好地体现了它的灵活性: ```gdscript func draw_line(p1: Vector2, p2: Vector2, color: Color): var steps = int(max(abs(p2.x - p1.x), abs(p2.y - p1.y))) for i in range(steps + 1): var t = clamp(float(i)/float(steps), 0, 1) var point = p1.linear_interpolate(p2, t).floored() set_pixel(point, color) ``` 虽然这里并未直接调用 `move_toward`, 不过其背后的思路是一致的——即按照一定比例分割总行程再逐一访问沿途各节点[^3]. --- ### 总结 综上所述,`move_toward` 提供了一个简单却强大的接口帮助开发者轻松达成许多复杂的效果。无论是构建基础物理仿真还是设计高级人工智能模块都离不开这样一类辅助型API的支持.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值