C/C++3C基础:结构体,格式化输出,/main函数参数,动态内存,/文件,目录,时间操作,/系统错误信息,编译预处理,/gdb调试,makefile

Posted 码农编程录

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C/C++3C基础:结构体,格式化输出,/main函数参数,动态内存,/文件,目录,时间操作,/系统错误信息,编译预处理,/gdb调试,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++标准库中的文件操作总结

重温C与C++之结构体大小计算

[C/C++笔试面试题] 程序设计基础 - 位操作函数数组篇

C/C++目录

网络编程基础,需要帮助理解 addrinfo / sockaddr_in 结构体的使用等

C语言中的main()函数返回值是啥?