C/C++3C基础:结构体,格式化输出,/main函数参数,动态内存,/文件,目录,时间操作,/系统错误信息,编译预处理,/gdb调试,makefile
Posted 码农编程录
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C/C++3C基础:结构体,格式化输出,/main函数参数,动态内存,/文件,目录,时间操作,/系统错误信息,编译预处理,/gdb调试,makefile相关的知识,希望对你有一定的参考价值。
文章目录
- 1.结构体:struct,memcpy,memset
- 2.格式化输出:%d(十),%c(字符),%s(字符串),%lf(double),snprintf
- 3.main函数的参数:*argv[]
- 4.动态内存管理:空指针,malloc,free
- 5.文件操作:FILE结构体,fprint/fgets,fwrite/fread,ftell/rewind/fseek,fflush
- 6.目录操作:getcwd/chdir/opendir/readdir/closedir
- 7.时间操作:time_t数据类型,time(),tm结构体,localtime()/mktime()。timeval,timezone,gettimeofday()
- 8.系统错误信息:strerror()
- 9.编译预处理:汇编程序-链接程序-可执行文件,-E,宏
- 10.gdb调试:set args,b/r,n/s
- 11.makefile文件:依赖文件功能
1.结构体:struct,memcpy,memset
int a=4,int b=3,double dd。
C语言用结构体(struct)数据类型
存放一组不同数据类型
的数据。
如下结构体变量名queen不是地址
,不像数组。printf(“%p\\n”,&queen);这才是结构体的地址。如下结构体指针。
结构体复制:基本类型用=,字符串用strcpy,结构体memcpy。
结构体作为函数的参数:结构体成员较多,函数参数的初始化和赋值的开销很大,最好的办法就是传递结构体变量的地址。
2.格式化输出:%d(十),%c(字符),%s(字符串),%lf(double),snprintf
如下012不加0,输出就是空格填充。
格式化输出到字符串。
\\:续行,忽略行尾换行符。
3.main函数的参数:*argv[]
main函数的参数是从命令提示符下执行程序时传入。
envp参数存放了当前程序运行环境的参数(env命令)。
4.动态内存管理:空指针,malloc,free
1.
指针变量初始化:int *pi=0; 或 int i ; int *pi=&i 。2.
指针释放之后置空:free(pi); pi=0;
5.文件操作:FILE结构体,fprint/fgets,fwrite/fread,ftell/rewind/fseek,fflush
参数mode也是字符串,表示打开文件的模式,打开模式可以是下列值中一个。
vi /tmp/test1.txt,可见有5行记录,不管执行多少次都是5行记录,因为文件打开方式是w,每次打开文件时都会清空原文件中的记录。
5.1 二进制文件的读写:没有行概念
5.2 文件定位:linux下文本文件模式和二进制文件模式没有区别。fgets和fprintf以行方式读写文本文件,但不能读写二进制文件。用fread和fwrite可以读写文本文件和二进制文件
文件内部有一个位置指针,用来指向当前读写的位置,也就是读到第几个字节。在文件打开时,如果打开模式是r和w
,位置指针指向文件的第一个字节。如果打开模式是a
,位置指针指向文件的尾部,每当从文件里读n个字节或文件里写入n个字节后,位置指针会后移n个字节。
文件位置指针与C中指针不是一回事,位置指针仅仅是一个标志,表示文件读写到的位置即读写到第几个字节,不表示地址。文件每读写一次,位置指针就会移动一次,不需要你在程序中定义和赋值,由系统自动设置。
os中存在内存缓冲区,调用fprintf、fwrite等函数往文件写入数据时,数据并不会立马写入磁盘文件,而是先写入缓冲区,等缓冲区满了后再写入文件,还有程序调用了fclose或fflush库函数时会把缓冲区数据写入文件。
#include <stdio.h>
int main(int argc, char **argv)
FILE *fp=fopen("/sys/bus/i2c/devices/20-0048/hwmon/hwmon1/in0_input","w");
if(!fp)
puts("fail");
fclose(fp);
FILE *fptime;
fptime=fopen("/tmp/time","w");
time_t time_log = time(NULL);
struct tm* tm_log = localtime(&time_log);
fprintf(fptime, "flag[%d] LINE[%d] %04d-%02d-%02d %02d:%02d:%02d\\r\\n",sensor_flag, __LINE__, tm_log->tm_year + 1900, tm_log->tm_mon + 1, tm_log->tm_mday, tm_log->tm_hour, tm_log->tm_min, tm_log->tm_sec);
fflush(fptime);
fclose(fptime);
if(rc<0)
FILE *fpLedLog=fopen("/tmp/error","a");
fprintf(fpLedLog,"error__%u__\\r\\n",__LINE__);
fclose(fpLedLog);
goto err;
FILE *fpLedColor=fopen(led_color,"w");
fseek(fpLedColor,0,SEEK_SET);
fprintf(fpLedColor,"%s",sensor_flag?LED_GREEN_CODE:LED_YELLOW_CODE);
fflush(fpLedColor);
fclose(fpLedColor);
int main(int argc, char **argv)
if(2 == argc)
FILE *fpLedCtrl=fopen("/sys/bus/i2c/devices/0-000d/sys_led_ctrl","w");
FILE *fpLedColor=fopen("/sys/bus/i2c/devices/0-000d/sys_led_color","w");
FILE *fpLedLog=fopen("/var/log/sensorMon.log","w");
fprintf(fpLedCtrl,"0x1");
fprintf(fpLedColor,"%s",argv[1]);
fprintf(fpLedLog,"%s\\r\\n",argv[1]);
fclose(fpLedCtrl);
fclose(fpLedLog);
fclose(fpLedColor);
int mysprintf(char *outBuffer, char *format, ...)
va_list aptr;
int ret;
va_start(aptr, format);
ret = vsprintf(outBuffer, format, aptr);
va_end(aptr);
return(ret);
if( realvalue >= 0 )
CompareValueThreshold(realvalue,&node[i]);
strcat(node[i].path,node[i].node);
if(0==strcmp("P1V8_VDDO(SWITCH)",node[i].name) || 0==strcmp("P1V2(SWITCH)",node[i].name))
RecordEventLog(LOG_ERR,"\\n [%d] throw a %s\\n",i,sta?"SENSOR_ABNORMAL":"SENSOR_NORMAL");
FILE *fright=fopen("/tmp/right","w");
for(i=0;i<arraysize;i++)
fprintf(fright,"[%d] %s (%s)\\r\\n",i,node[i].path,node[i].desc);
fclose(fright);
6.目录操作:getcwd/chdir/opendir/readdir/closedir
7.时间操作:time_t数据类型,time(),tm结构体,localtime()/mktime()。timeval,timezone,gettimeofday()
如下C语言提供了一系列函数和结构体解决上面需要计算天数,哪一年等等问题,.h文件中可以定义结构体。
精确到微秒的计时器。
sys/time.h是linux系统头文件。
8.系统错误信息:strerror()
关注error目的是为了获取更详细错误信息,这些错误信息对程序员诊断程序可能有帮助,但不是必须的。
9.编译预处理:汇编程序-链接程序-可执行文件,-E,宏
C源程序 - 编译预处理
【对预处理指令即以#开头指令和特殊符号进行处理,删除程序中注释和多余空白行】 - 编译 。
-E参数就是预处理,#include那些头文件内容可以在book.E文件中看见。
预处理指令:1.包含文件。
2.宏定义指令:#define。
vi book.E。宏就是起别名和typedef差不多。
3.条件编译:最常用的两种格式#ifdef和#ifndef 。#undef :取消已定义的标识符
执行预编译指令gcc -E -o book153.E book153.c,得到book153.E文件,如下:
如下book145.c和_public.c都有 #include"_public.h",会重复包含。
在_public.h中如下这样写,_public.h就不会被重复包含。
10.gdb调试:set args,b/r,n/s
多进/线程中无法用gdb调试,还是用printf,但不会把结果显示到界面,写入日志文件中。root 用户:yum -y install gdb,gdb -v。
11.makefile文件:依赖文件功能
make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说大多数编译器都有这个命令,使用make可以是重新编译的次数达到最小化。文件名makefile。vi gcc.sh 如下,sh gcc.sh。gcc -o 目标 依赖1 依赖2。makefile命令能被执行条件有两个:1.目标不存在,2.依赖已更新。
如上若只需要编译book2,单个文件改变不重复编译其他文件即增量编译。vi makefile,$前一个tab键不能8个空格。make默认是make all
,如果将all这行book3删除,则make不会编译book3,可以指定make book3,book3相当于标签。-欧2是让编译效率最高,一般正式发布用。gcc命令选项 :-c编译不链接。
以上是关于C/C++3C基础:结构体,格式化输出,/main函数参数,动态内存,/文件,目录,时间操作,/系统错误信息,编译预处理,/gdb调试,makefile的主要内容,如果未能解决你的问题,请参考以下文章
[C/C++笔试面试题] 程序设计基础 - 位操作函数数组篇