Unix环境高级编程代码(实时更新)

2023-05-16

实例1-3 列出一个目录中所有文件(ls.c)

#include "apue.h"
#include <dirent.h>

int main(int argc, char *argv[]){
	DIR *dp;
	struct dirent *dirp;
	if(argc != 2)
		err_quit("ls dir");
	if((dp = opendir(argv[1])) == NULL)
		err_sys("can not open %s", argv[1]);
	while((dirp = readdir(dp)) != NULL)
		printf("%s\n", dirp->d_name);
	closedir(dp);
	exit(0);
}

关于apue.h得从官网获取源码:http://www.apuebook.com/src.3e.tar.gz

然后复制include下的apue.h和error.c到ls.c同目录下

用gcc编译出二进制文件:

gcc ls.c error.c -o ls

执行二进制文件可以看到文件名被输出了(包括隐藏文件):

 实例1-4 将标准输入复制到标准输出中(example2.c)

#include "apue.h"

#define BUFFSIZE 4096

int main(void){
	int n; //要读写的字节数
	char buf[BUFFSIZE];
	while((n = read(STDIN_FILENO, buf, BUFFSIZE)) > 0)
		if(write(STDOUT_FILENO, buf, n) != n)
			err_sys("write error");
	if(n < 0){
		err_sys("read error");
	}
	exit(0);
}

 其中:

#include <unistd.h>
ssize_t read(int filedes, void *buf, size_t nbytes);
// 返回:若成功则返回读到的字节数,若已到文件末尾则返回0,若出错则返回-1
// filedes:文件描述符
// buf:读取数据缓存区
// nbytes:要读取的字节数
#include <unistd.h>
ssize_t write(int filedes, void *buf, size_t nbytes);
// 返回:若成功则返回写入的字节数,若出错则返回-1
// filedes:文件描述符
// buf:待写入数据缓存区
// nbytes:要写入的字节数

 STDIN_FILENOSTDOUT_FILENO分别是标准输入和标准输出的文件描述符,被定义在unistd.h中。

编译:

gcc example2.c error.c

执行:

./a.out > data

执行上述指令后后面键入命令行的任何内容会被保存到data文件中(不使用重定向则会输出你键入的内容两次)

 

 指令./a.out < file1 > file2 则会把file1中的内容复制到file2中

类似的功能还可以用getc和putc(这两个函数包含在stdio.h中)实现:

#include "apue.h"

#define BUFFSIZE 4096

int main(void){
	int c; //要读写的字符数
	
	while((c = getc(stdin)) != EOF)
		if(putc(c, stdout) == EOF)
			err_sys("output error");
	if(ferror(stdin)){
		err_sys("input error");
	}
	exit(0);
}

 实例1-6 获取自身进程的pid

#include "apue.h"

int main(){
	printf("my pid is: %ld\n", (long) getpid());
	exit(0);
}

实例1-7 从标准输入读取命令,然后执行这些命令

#include "apue.h"
#include <sys/wait.h>

void sig_int(int signo){
	printf("interrupt\n%% ");
}


int main(){
	char buf[MAXLINE]; //MAXLINE来自apue.h
	pid_t pid;
	int status;

   if(signal(SIGINT, sig_int) == SIG_ERR)
		err_sys("signal error");

	printf("%%");

	while(fgets(buf, MAXLINE, stdin) != NULL){
		if(buf[strlen(buf) - 1] == '\n')
			buf[strlen(buf) - 1] = 0; //用null替换换行符
		if((pid = fork()) < 0){
			err_sys("fork error");
		}else if(pid == 0){
			//在子进程中执行
			execlp(buf, buf, (char *) 0);
			//若上述指令执行成功则终止,若执行失败则继续往下执行
			err_ret("executr %s failed", buf); //报错,执行指令失败
			exit(127);
		}

		if((pid = waitpid(pid, &status, 0)) < 0)
			err_sys("waitpid error");
		printf("%%");
	}
	exit(0);
}

其中:

fork()函数会创建一个子进程,相当于父进程的一个副本,fork()函数返回子进程的pid给父进程,返回0给子进程,如果创建失败则返回负数。并且!!fork函数创建的子进程并不是从头开始执行,而是把进程当前的情况拷贝一份,执行fork时,进程已经执行完了上面的代码,所以只需要拷贝下面要执行的代码到新的进程执行。

execlp函数要求指令字符串以null结尾,而不是换行符\n。

execlp()会从PATH 环境变量所指的目录中查找符合参数file的文件名, 找到后便执行该文件, 然后将第二个以后的参数当做该文件的argv[0]、argv[1]……, 最后一个参数必须用空指针(NULL)作结束,即(char *)0。

如果execlp()函数执行成功,进程自己的执行代码就会变成加载程序的代码(exec()族函数用一个新的进程映像替换当前进程映像),execlp()后边的代码也就不会执行了。

waitpid函数对等待pid对应进程执行完毕。

signal(参数1,参数2);

参数1:我们要进行处理的信号。系统的信号我们可以再终端键入 kill -l查看(共64个)。其实这些信号时系统定义的宏。

参数2:我们处理的方式(是系统默认还是忽略还是捕获)

实例3-2 创建一个具有空洞的文件

#include "apue.h"
#include <fcntl.h> //creat函数
#include <unistd.h> //write, lseek函数

char buf1[] = "AAAAAAAAAA";
char buf2[] = "bbbbbbbbAA";

int main(){
	int fd; //文件描述符

	if((fd = creat("file.hole", FILE_MODE)) < 0)
		err_sys("creat error"); //创建文件失败

	if(write(fd, buf1, 10) != 10)
		err_sys("write error");

	printf("ofset 10 is: %ld\n", (long) lseek(fd, 0, SEEK_CUR));

	if(lseek(fd, 16384, SEEK_SET) == -1)
		err_sys("lseek error");

	if(write(fd ,buf2, 10) != 10)
		err_sys("write error");

	printf("ofset 16384 is: %ld\n", (long) lseek(fd, 0, SEEK_CUR));

	exit(0);
}

creat(const char* path, mode_t mode); 用于创建一个文件,并且以只写方式打开,返回文件描述符,来自fcntl.h。

lseek(int fd, off_t offset, int whence); 用于设置文件的偏移量,返回文件的当前偏移量。

whence有SEEK_SET, SEEK_CUR, SEEK_END三种状态。

 实例3-11 对指定的描述符打印文件标志

#include "apue.h"
#include <fcntl.h>

int main(int argc, char *argv[]){
	int val; //接收状态标志

	if(argc != 2)
		err_quit("./a.out fd");
	
	if((val = fcntl(atoi(argv[1]), F_GETFL, 0)) < 0)
		err_sys("fcntl error for fd: %d", atoi(argv[1]));

	switch(val & O_ACCMODE){
		case O_RDONLY:
			printf("read only");
			break;
		case O_WRONLY:
			printf("write only");
			break;
		case O_RDWR:
			printf("read write");
			break;
		default:
			err_dump("unknow access mode");
	}
	if(val & O_APPEND)
		printf(", append");
	if(val & O_NONBLOCK)
		printf(", nonblocking");
	if(val & O_SYNC)
		printf(", synchrinous writes");

#if !defined(_POSIX_C_SOURCE) && defined(O_FSYNC) && (O_FSYNC != O_SYNC)
	if(val & O_FSYNC)
		printf(", synchronous writes");
#endif
	putchar('\n');
	exit(0);
}

 其中:

#include <fcntl.h>
int fcntl(int fd, int cmd, ... /*int arg*/);
// 返回:若成功则返回的结果依赖于cmd,若出错则返回-1
// fd:文件描述符
// cmd:指令,工具不同的指令可以实现不同的操作,返回不同的结果
// arg:目前用不到

对fcntl函数设置不同的cmd可以实现不同的功能,代码中cmd=F_GETFL,实现了获取文件状态标志的功能。

 

  实例4-3 针对每一个命令行参数打印其文件类型

#include "apue.h"

int main(int argc, char *argv[]){
	int i;
	struct stat buf; //
	char *ptr; //字符串

	for(i = 1;i < argc;i++){
		printf("%s: ", argv[i]); //打印文件名
		if(lstat(argv[i], &buf) < 0){
			err_ret("lstat error");
			continue;
		}
		if(S_ISREG(buf.st_mode))
			ptr = "regular";
		else if(S_ISDIR(buf.st_mode))
			ptr = "directory";
		else if(S_ISCHR(buf.st_mode))
                        ptr = "character special";
		else if(S_ISBLK(buf.st_mode))
                        ptr = "block special";
		else if(S_ISFIFO(buf.st_mode))
                        ptr = "fifo";
		else if(S_ISLNK(buf.st_mode))
                        ptr = "symbolic link";
		else if(S_ISSOCK(buf.st_mode))
                        ptr = "socket";
		else
                        ptr = "**unknow**";
		printf("%s\n", ptr);
	}
	exit(0);
}

 其中:

#include <sys/stat.h>
int lstat(const char *restrict pathname, struct stat *restrict buf);
//成功返回0,失败返回-1
//pathname:文件路径
//buf:stat结构,包含了文件的各种信息

  实例4-9 使用umask函数改变文件权限

#include "apue.h"
#include <fcntl.h>

#define RWRWRW (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)

int main(){
	umask(0); //不创建屏蔽字
	if(creat("foo", RWRWRW) < 0)
		err_sys("creat foo error");
	if(access("/root/unix/foo", R_OK) < 0)
		printf("read access error for foo");
	else 
		printf("read access ok\n");

	umask(S_IRUSR | S_IWUSR); //屏蔽用户读和写
	if(creat("bar", RWRWRW) < 0)
                err_sys("creat bar error");
        if(access("/root/unix/bar", R_OK) < 0)
                printf("read access error for bar");
        else
                printf("read access ok\n");
	exit(0);
}

其中:

#include <unistd.h>
int access(const char *pathname, int mode); //可用于对当前用户进行访问权限测试
//成功返回0,出错返回1
//pathname:文件绝对路径
//mode:要测试的权限,R_OK W_OK X_OK
#include <sys/stat.h>
mode_t umask(mode_t cmask);
//返回之前文件模式创建屏蔽字

实例4-16 使用unlink函数使文件计数减一

#include "apue.h"
#include <fcntl.h>

int main(){
	if(open("/root/unix/tempfile", O_RDWR) < 0)
		err_sys("open error");
	if(unlink("/root/unix/tempfile") < 0)
		err_sys("unlink error");
	printf("file unlinked\n");
	sleep(15);
	printf("done\n");
	exit(0);
}
#include <unistd.h>
int unlink(const char *pathname); //可以把文件的链接计数减一
//成功返回0,失败返回1
//pathname:文件的绝对路径

可以看到执行代码后tempfile文件消失(执行前先自己创建这个文件),因为链接计数为0会被删除,但是有进程如果打开了这个文件,那么这个文件在进程关闭该文件之前不会删除文件。如果想要进程执行期间创建临时文件,进程结束立刻删除临时文件,则可以利用这个特性(creat文件后立刻调用unlink,这样即使程序崩溃也能删除临时文件)。

实例7-3 使用atexit函数

#include "apue.h"
#include <stdlib.h>

static void my_exit1();
static void my_exit2();

int main(){
	if(atexit(my_exit1) != 0)
		err_sys("can not resgister my_exit1");
	if(atexit(my_exit2) != 0)
                err_sys("can not resgister my_exit2");
	if(atexit(my_exit1) != 0)
                err_sys("can not resgister my_exit1");
	exit(0);
}

static void my_exit1(){
	printf("第1个函数做的事情\n");
}

static void my_exit2(){
        printf("第2个函数做的事情\n");
}

其中:

#include <stdlib.h>
int atexit(void (*func) (void));
//成功返回0,出错返回非0
//传入函数名

调用该函数后,被注册的函数会在exit调用时执行。

实例8-1 研究子进程对变量所做的改变是否会影响父进程

#include <unistd.h>
#include "apue.h"

int globvar = 6;
char buf[] = "a write to stdout\n";

int main(){
	int var = 88;
	pid_t pid;

	if(write(STDOUT_FILENO, buf, sizeof(buf) - 1) != sizeof(buf) - 1)
		err_sys("write error");
	printf("before fork, we don't flush stdout\n");

	if((pid = fork()) < 0)
		err_sys("fork error");
	else if(pid > 0)
		sleep(2); //父进程
	else{
        //pid=0时为子进程
		globvar++;
		var++;
	}
	
	printf("pid = %ld, glob = %d, var = %d\n", (long) getpid(), globvar, var);
	exit(0);
}

 其中:

#include <unistd.h>
pid_t fork(void);
//子进程返回0,父进程返回子进程的id

 可以发现子进程对变量所做的操作不会影响父进程(父进程后输出,因为父进程sleep了两秒)

孤儿进程:若一个父进程退出,则他的还未执行完的子进程成为孤儿进程,他们会被init进程收养。

僵死进程:子进程退出后,父进程没有及时调用wait系列函数获取子进程的状态,则此时子进程为僵死进程。

消去僵死进程的方法:除掉父进程,让僵死进程变成孤儿进程让init收养,然后init会获取其状态而消去僵死进程。

 实例8-16 execlp的用法

#include "apue.h"
#include <sys/wait.h>
#include <unistd.h>

int main(){
	pid_t pid;
	if((pid = fork()) < 0)
		err_sys("fork error");
	else if(pid == 0){
		//子进程
		if(execlp("ls", "ls", "-al", (char *)0) < 0)
			err_sys("execlp error");
	}
	//父进程
	if(waitpid(pid, NULL, 0) < 0)
		err_sys("wait error");
	printf("execlp successful!\n");
	exit(0);
}

其中:

#include <unistd.h>
int execl(const char *pathname, const char *arg0, 000 /* (char *)0 */);
int execv(const char *pathname, char *const argv[]);
int execle(const char *pathname, const char *arg0, 000 /* (char *)0, char *const envp[] */);
int execve(const char *pathname, char *const argv[], char *const envp[]);
int execlp(const char *filename, const char *arg0, 000 /* (char *)0 */);
int execvp(const char *filename, char *const argv[]);
int fexecve(int fd, char *const argv[], char *const envp[]);
//出错返回-1,成功则不返回
//filename为文件名,若以/开头,则视为路径名;否则就去PATH环境变量中寻找可执行文件
//execlp可以将调用者的环境传到新程序

执行:

 实例10-2 signal的用法

#include "apue.h"

static void sig_usr(int);

int main(){
	if(signal(SIGUSR1, sig_usr) == SIG_ERR)
		err_sys("can not catch usr1");
	if(signal(SIGUSR2, sig_usr) == SIG_ERR)
                err_sys("can not catch usr2");
	for(;;)
		pause(); //pause函数使调用函数在接到一个信号前挂起
}

//接收到信号后执行的函数
static void sig_usr(int signo){
	if(signo == SIGUSR1)
		printf("usr1 received!\n");
	else if(signo == SIGUSR2)
                printf("usr2 received!\n");
	else
		err_dump("received signal %d\n", signo);
}

 其中:

pause函数使得调用函数在接到一个信号前挂起

signal函数调用后,在接收到对应信号后会执行对应函数,并且只会执行一次。

  实例10-6 SIGCHLD信号

#include "apue.h"
#include <signal.h>
#include <sys/wait.h>

static void sig_cld(int);

int main(){
	pid_t pid;

	if(signal(SIGCHLD, sig_cld) == SIG_ERR)
		perror("signal error");
	if((pid = fork()) < 0)
		perror("fork error");
	else if(pid == 0){
		//子进程
		sleep(2);
		_exit(0);
	}
	//父进程
	pause();
	exit(0);
}

static void sig_cld(int signo){
	pid_t pid;
	int status;
	printf("SIGCHLD RECEIVED!\n");
	if(signal(SIGCHLD, sig_cld) == SIG_ERR)
                perror("signal error");

	if((pid = wait(&status)) < 0)
		perror("wait error");

	printf("pid = %d\n", pid);
}

 当子进程终止时,会产生SIGCHLD信号,可以用来避免产生僵死进程。

实例10-15 sigprocmask设置信号屏蔽字

#include "apue.h"

static void sig_quit(int signo);

int main(void){
	sigset_t newmask, oldmask, pendmask;
	/*注册sigquit信号*/
	if(signal(SIGQUIT, sig_quit) == SIG_ERR){
		err_sys("can not catch SIGQUIT\n");
	}
	/*初始化信号集*/
	sigemptyset(&newmask);
	/*往信号集中添加SIGQUIT信号*/
	sigaddset(&newmask, SIGQUIT);
	/*阻塞SIGQUIT信号,并保存老的信号集*/
	if(sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0){
		err_sys("SIG_BLOCK error\n");
	}
	/*此时可以发出SIGQUIT信号,发现信号被阻塞,不会触发sig_quit函数*/
	sleep(5);

	/*查看sigquit信号是否被阻塞*/
	if(sigpending(&pendmask) < 0)
		err_sys("sigpending error\n");
	if(sigismember(&pendmask, SIGQUIT))
		printf("\nSIGQUIT pending\n");

	/*取消sigquit信号的阻塞,将原来的信号屏蔽字放进去*/
	if(sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)
		err("SIGMASK error\n");
	printf("SIGQUIT UNBLOCK\n");

	sleep(5);
	exit(0);
}

static void sig_quit(int signo){
	printf("caught SIGQUIT\n");
	if(signal(SIGQUIT, sig_quit) == SIG_ERR){
                err_sys("can not catch SIGQUIT\n");
        }
}

实例11-2 打印线程id

#include <pthread.h>
#include "apue.h"

pthread_t ntid;

void printids(const char *s){
	pid_t pid;
	pthread_t tid;

	pid = getpid();
	tid = pthread_self();

	printf("%s pid %lu, tid %lu, (0x%lx)\n", s, (unsigned long) pid, (unsigned long) tid, (unsigned long) tid);
}

void *thr_fn(void *arg){
	printids("new thread: ");
	return ((void *) 0);
}

int main(void){
	int err;
	err = pthread_create(&ntid, NULL, thr_fn, NULL);
	if(err != 0)
		printf("create thread error\n");
	printids("main thread: ");
	sleep(1);
	exit(0);
}

 两个线程对全局变量a进行a++100次,最后a的值在100~200之间

实例12-16 同步信号处理

#include "apue.h"
#include <pthread.h>
#include <signal.h>

int quitflag;
sigset_t mask; //信号集

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; //互斥量
pthread_cond_t waitloc = PTHREAD_COND_INITIALIZER; //条件变量

/*线程执行的函数*/
void *thr_fn(void *arg){
	int err, signo;
	for(;;){
		err = sigwait(&mask, &signo); //mask是线程等待的信号集,signo是接收到的信号
		if(err != 0)
			err_exit(err, "sigwait failed\n");
		switch(signo){
			case SIGINT:
				printf("\ninterrupt\n");
				break;
			case SIGQUIT:
				pthread_mutex_lock(&lock);
				quitflag = 1;
				pthread_mutex_unlock(&lock);
				pthread_cond_signal(&waitloc); //唤醒等待该条件变量的线程
				return 0;

			default:
				printf("unknow signal\n");
				exit(1);
		}
	}
}

int main(void){
	int err;
	sigset_t oldmask;
	pthread_t tid; //线程id

	sigemptyset(&mask); //初始化信号集
	sigaddset(&mask, SIGINT);
	sigaddset(&mask, SIGQUIT);

	if(pthread_sigmask(SIG_BLOCK, &mask, &oldmask) != 0)
		err_sys("sigmask error\n");

	err = pthread_create(&tid, NULL, thr_fn, 0);
	if(err != 0)
		err_exit(err, "create thread error\n");

	pthread_mutex_lock(&lock);
       	while(quitflag == 0)
		pthread_cond_wait(&waitloc, &lock); //等待条件变量waitloc,并且释放lock锁		
        pthread_mutex_unlock(&lock);

	quitflag = 0;

	if(pthread_sigmask(SIG_SETMASK, &oldmask, NULL) != 0)
                err_sys("sigmask error\n");
	exit(0);
}

 编译:

gcc threadSig.c error.c  -lpthread

 执行结果:

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Unix环境高级编程代码(实时更新) 的相关文章

  • AIGPT中文版(无需魔法,直接使用)不愧是生活工作的好帮手。

    AIGPT AIGPT是一款非常强大的人工智能技术的语言处理工具软件 xff0c 它具有 AI绘画 功能 AI写作 写论文 写代码 哲学探讨 创作等功能 xff0c 可以说是生活和工作中的好帮手 我们都知道使用ChatGPT是需要账号以及使
  • Tomcat10版本避坑

    Tomcat版本选择 Tomcat 服务器是一个免费的开放源代码的Web 应用服务器 xff0c 属于轻量级应用服务器 xff0c 在中小型系统和 并发访问用户不是很多的场合下被普遍使用 xff0c 是开发和调试JSP 程序的首选 并且To
  • 阿里云ECS服务器ubuntu18图形界面安装

    文章目录 前言一 配置阿里镜像源二 安装图形界面三 VNC远程连接总结 前言 文章中的图形界面基于阿里云ECS服务器远程连接中的VNC连接 xff0c 使用时会体验到明显的延迟 xff0c 介意可以使用Xshell 43 Xmanger 4
  • 实验二 HDFS实验操作

    一 实验目的 理解HDFS在Hadoop体系结构中的角色熟练使用HDFS操作常用的Shell命令熟悉HDFS操作常用的Java API 二 实验平台 操作系统 xff1a ubuntu18Hadoop版本 xff1a 3 2 2JDK版本
  • Java程序部署到Linux环境上运行

    文章目录 前言一 Java环境安装二 Eclipse编译java程序并导出jar包三 Linux环境上运行jar包 前言 想要在Linux上运行java程序 xff0c 可以将java程序编译成功后导出成jar包 xff0c 然后在Linu
  • python疫情大数据可视化

    一 实验目的 通过本次实验掌握数据获取 数据清洗与存储和数据可视化工具的基本使用方法 二 实验平台 操作系统 xff1a window10 python版本 xff1a 3 8 IDE xff1a pycharm 可视化工具 xff1a e
  • MybatisPlus-乐观锁&悲观锁

    乐观锁 xff1a 每次不加锁而是假设没有冲突而去完成某项操作 xff0c 如果失败就重试 xff0c 直到成功为止 悲观锁 xff1a synchronized是独占锁即悲观锁 xff0c 会导致其他所有需要锁的线程挂起 xff0c 等待
  • ConcurrentHashMap -1.8 源码解析

    ConcurrentHashMap 1 8 源码解析 加锁机制 在JDK1 7之前 xff0c ConcurrentHashMap是通过分段锁机制来实现的 xff0c 所以其最大并发度受Segment的个数限制 因此 xff0c 在JDK1
  • Redis五种基本数据类型

    五种基本数据类型 redis无论什么数据类型 xff0c 在数据库中都是以key value形式保存 xff0c 并且所有的key 键 都是字符串 xff0c 所以讨论基础数据结构都是讨论的value值的数据类型 主要包括常见的5种数据类型
  • 直线的斜率

    斜率 xff0c 亦称 34 角系数 34 xff0c 表示一条直线相对于横轴的倾斜程度 一条直线与某平面直角坐标系横轴正半轴方向的夹角的正切值即该直线相对于该坐标系的斜率 如果直线与x轴垂直 xff0c 直角的正切值无穷大 xff0c 故
  • ElasticSearch--整合SpringBoot

    引入依赖 span class token tag span class token tag span class token punctuation lt span dependency span span class token pun
  • ElasticSearch--聚合查询

    聚合查询 简介 聚合 xff1a 英文为Aggregation xff0c 是es除搜索功能外提供的针对es数据做统计分析的功能 聚合有助于根据搜索查询提供聚合数据 聚合查询是数据库中重要的功能特性 xff0c ES作为搜索引擎兼数据库 x
  • CopyOnWriteArrayList简介

    1 简介 CopyOnWriteArrayList 是 ArrayList 的线程安全版本 就是在进行写操作的时候会 copy 原数组 xff0c 然后写完将指针指向新的数组 xff0c 是一种读写分离的思想 xff0c 可以并发的读 xf
  • PX4平台(V3)+T8S遥控器校准

    1 PX4与接收机的连接 首先 xff0c 将遥控器接收机的信号线与PX4的RC IN信号相连 xff08 注意正负极 xff09 xff0c 在主控上电之后 xff0c 观察接收机信号指示灯的颜色 xff1a 1 PWM 信号工作模式 接
  • PX4编写CAN应用程序控制底盘运动

    目录 一 在PX4平台中添加自己的应用程序 1 建立应用程序 Hello can c文件 xff1a Kconfig文件 xff1a CMakeLists txt文件 xff1a 2 编译应用程序及固件 3 测试应用 xff08 硬件 xf
  • PyCharm2021安装教程

    Windows安装PyCharm2021教程 一 下载安装PyCharm二 安装Python三 配置PyCharm环境四 使用PyCharm五 PyCharm简介 一 下载安装PyCharm 1 进入官网PyCharm的下载地址 xff1a
  • ROS学习(二)创建功能包

    在上一讲中我们已经创建好工作空间catkin ws xff0c 我们要在其src文件中创建功能包 文章目录 一 创建功能包二 编译功能包三 查看功能包的依赖3 1一阶依赖3 2间接依赖 四 定制功能包自定义package xml文件4 1
  • 双冒号(::)和单冒号(:)在 C++ 中的含义和作用

    目录 一 双冒号 xff08 xff09 在C 43 43 中的含义和作用 二 单冒号 xff08 xff09 在C 43 43 中的含义和作用 双冒号 xff08 xff09 和单冒号 xff08 xff09 在 C 43 43 中都是特
  • 【OpenCV教程】OpenCV中的数据类型

    文章目录 1 CV 8U2 CV 8S3 CV 16U4 CV 16S5 CV 16F6 CV 32S7 CV 32F8 CV 64F9 一图流 1 CV 8U CV 8U 占8位的unsigned CV 8UC n 占8位的unsigne
  • 【ROS教程】安装ROS全流程及可能遇到的问题

    文章目录 1 配置Softerware amp Updates2 添加软件源3 设置key4 更新并安装4 1 更新4 2 安装 ros noetic desktop full 4 2 1 安装aptitude4 2 2 安装ROS软件包

随机推荐

  • 【unix】unix环境高级编程

    文章目录 1 UNIX基础知识1 基本知识2 文件和目录3 输入和输出4 程序和进程5 出错处理6 用户标识7 信号8 时间9 系统调用和库函数 标准化和实现1 标准化 ISO C POSIX Single UNIX Specificati
  • 在 Ubuntu 中安装 VSCode

    在 Ubuntu 中安装 VSCode 如果想要通过 ubuntu 安装 vscode 有三种方式 xff0c 可以通过应用中心下载 xff0c 也可以通过安装包下载 xff0c 以及指令安装 方式一 xff1a 首先在 ubuntu 桌面
  • 常用命名规范分类:匈牙利命名法、下划线命名法、驼峰命名法、帕斯卡命名法

    目录 1 匈牙利命名法 xff08 Hungarian xff09 变量属性 2 下划线命名法 xff08 UnderScoreCase xff09 3 驼峰命名法 xff08 小驼峰命名法 xff09 xff08 Camel xff09
  • keil5无法跳转自己要查询的函数

    之前用keil5的时候想要查询函数的意思 xff0c 去跳转结果给我报错 xff0c 出现这个报错信息 原因是编译的时候没有勾选这个按钮 xff1a 勾选上之后重新编译就不会报错了
  • Linux 安装 Node.js | NPM

    超级简单 yum y install nodejs 验证安装 安装node js 会自动一起安装npm 注意 python V 是大写字母V 错写为小写会进入python的编辑模式 执行exit 退出 执行node 启动node终端 两次C
  • 树莓派连接不上WIFi,VNC失效,SSH失效

    笔记 xff1a 树莓派连接不上wifi的解决方法 xff1a 1 xff0c usb连接手机 xff0c 手机设置中搜索 xff0c usb共享网络 xff0c 然后代开usb连接网络 2 xff0c 右键树莓派wifi标志符 xff0c
  • C++中类的运算符重载教程(一),内附完整代码与解析

    目录 xff1a 一 xff1a 加号运算符重载 对 43 重载函数的理解 xff1a xff08 个人理解 xff0c 仅供参考 xff09 二 xff1a 左移运算符的重载 对 lt lt 重载函数的理解 xff08 个人理解 xff0
  • 关于ros中pcl_ros和ros链接问题Makefile:140的一种解决方案

    本人在ros学习pcl和slam过程中 xff0c 使用catkin make进行编译 xff0c 最终只报了错误Makefile 140和make j4 l4错误 xff0c 诸如此类错误 xff0c 多为链接过程出现问题 坑多日 xff
  • rosbag播放过程ctrl+z暂停后继续播放的方法

    rviz 43 rosbag播放暂停与继续播放 rosbag播放暂停的方式可以在rosbag运行窗口 space按键进行控制 该方法用于进程管理的学习扩展 问题描述 xff1a rosbag包播放过程ctrl 43 z暂停播放恢复播放方法
  • github上docker镜像创建容器

    docker介绍 三个概念 1 镜像 xff1a 类似于模版 xff0c 在没有添加实例化前不能使用 2 容器 xff1a 镜像实例化 3 docker xff1a 放容器的一个载体 总结 xff1a docker就像一艘船 xff0c 上
  • vi/vim基本命令

    目录 打开创建文档模式介绍显示行号增删改查光标移动文档操作 打开创建文档 span class token function vim span hello txt 打开已存在hello txt文档或者创建一个不存在的hello txt文档
  • 关于leetcode刷题详细介绍

    虽然刷题一直饱受诟病 xff0c 不过不可否认刷题确实能锻炼我们的编程能力 xff0c 相信每个认真刷题的人都会有体会 现在提供在线编程评测的平台有很多 xff0c 比较有名的有 hihocoder xff0c LintCode xff0c
  • leetcode:13罗马数字转整数c++

    思路分析 两种情况 1 不同的罗马数字都是从左到右依次相加 2 不同的就是末尾数是4和9的情况 xff0c 也就是IV VIV xff08 if xff09 代码框架 整体过程 从题目中字符和数字的对应关系 xff0c 不难想到数据结构un
  • leetcode:20有效的括号——stack

    思路分析 题目匹配的情况有两中 xff1a 和 xff08 xff09 匹配成功的思路是每个 或者其他右包围结构都是和最近的 或者其他左包围结构匹配 最近 匹配的思想应该使用stack结构对数据进行操作 代码框架 1 遍历整个string
  • leetcode:21合并两个有序连表——slist

    思路分析 链表 xff1a 头节点为空 xff0c 每个节点有一个指针 xff0c 指向下一个节点的地址 俩链表节点之间比较 xff0c 用遍历 96 96 for xff0c 因为是list xff0c 可以直接通过迭代器 xff08 指
  • leetcode:53最大子数组和

    思路分析 有2个变量是一直变化的 1 最大集合的第一个元素 2 存放最大的变量 0 变量初始化 span class token keyword int span res span class token operator 61 span
  • Ubuntu安装docker及出现问题解决

    Ubuntu安装docker及出现问题解决 文章目录 Ubuntu安装docker及出现问题解决一 安装docker二 解决docker安装成功后 xff0c docker命令无法正常使用的问题 一 安装docker docker的安装可参
  • stl大全

    什么是STL xff1f 大佬 xff1a 为什么C 43 43 比C更受人欢迎呢 xff1f 除了C 43 43 的编译令人感到更舒适 xff0c C 43 43 的标准模板库 xff08 STL xff09 也占了很重要的原因 当你还在
  • input 图片上传

    使用 在vue项目中使用input上传图片给后台时 xff0c 需要对图片文件流和请求头进行一些处理 1 获取上传图片文件流 span class token tag span class token tag span class toke
  • Unix环境高级编程代码(实时更新)

    实例1 3 列出一个目录中所有文件 xff08 ls c xff09 include 34 apue h 34 include lt dirent h gt int main int argc char argv DIR dp struct