当前位置: 首页 > news >正文

【c/c++1】数据类型/指针/结构体,static/extern/makefile/文件

文章目录

  • 1.数据类型:中文里的汉字和标点符号是两个字节,不能算一个字符(单引号)
    • 1.1 float是如何在计算机中存储:d(十进制),o(八进制),x(十六进制)
    • 1.2 数组:存数据类型相同的数据,数组下标越界导致段错误
  • 2.指针:指针数组(这个数组的所有元素都是指针类型),数组指针(这个指针存放着一个数组的首地址)
  • 3.结构体:存放一组不同数据类型的数据
  • 4.static/extern:宏在编译预处理时用文本形式复制过来,inline内联函数先编译成二进制再插入调用的地方,不用跳转到原函数执行
  • 5.makefile文件:make是一个解释makefile中指令的命令工具
  • 6.文件:fgets和fprintf以行方式读写文本文件,但不能读写二进制文件。用fread和fwrite可以读写文本文件和二进制文件
    • 6.1 文本文件:返回FILE结构体
    • 6.2 二进制文件:没有行概念
    • 6.3 文件定位:文件内部有一个位置指针,用来指向当前读写的位置,也就是读到第几个字节。在文件打开时,如果打开模式是r和w,位置指针指向文件的第一个字节。如果打开模式是a,位置指针指向文件的尾部,每当从文件里读n个字节或文件里写入n个字节后,位置指针会后移n个字节


1.数据类型:中文里的汉字和标点符号是两个字节,不能算一个字符(单引号)

编译型compiler语言:C/C++:编译将源码编译成二进制文件,可直接运行该文件,因为是机器码,所以运行效率很高。缺点是不够灵活,改代码要重新编译,此外平台依赖,linux平台编译出来的二进制文件无法在windows运行,跨平台还需借助交叉编译
解释型interpreter语言:python/js:不需要生成二进制文件,改了代码功能直接生效,但运行效率低。
半解释半编译型语言:java:JIT将运行到的代码块在运行时编译成机器码,既可保证跨平台性,又能使热代码高效运行。

C库函数声明头文件(.h):存放在/usr/include目录中,如果 #include <facebook/cJSON.h>,则cJSON.h在/usr/include/facebook/目录里。如下github上软件包,在image.bb中添加hiredis在yocto或common或meta-aspeed或meta-phosphor文件夹中查找hiredis.bb文件【内容有git网址】,hiredis.h文件会在/usr/include/中,但rootfs中看不到。

drivers/hwmon/Makefile:obj-y += fcbcpld.o
drivers/i2c/Makefile:obj-y	+= i2c_dev_sysfs.o

在这里插入图片描述
C库函数定义(具体实现)文件(.c):gcc编译不用包含libgcc.a(缺省包含/usr/lib/gcc/x86_64…/4.4.4/libgcc.a)。

gcc main.c -o main  -Wall(显示所有警告)  -I../include(-I后面没空格,不加-I就在main.c中指定头文件的相对路径)   -L../lib   -lsum(有库文件/lib/libsum.so就只要main.c就行)

1.1 float是如何在计算机中存储:d(十进制),o(八进制),x(十六进制)

2个字节的-480在计算机中为0xfe20,ipmitool发指令即低位在前即0x20 0xfe。先确定字节数,再将最高位1固定。
在这里插入图片描述
如下没有用补码表示,-2+1应该=-1,但是下面变成了-3,所以负数存储用补码,方便计算机加减法。
在这里插入图片描述
如下用补码表示。
在这里插入图片描述
int是4字节即32bit,int的最大最小值如下。
在这里插入图片描述
如下10.625存储:符号位只占一位,指数存的是移动的位数+127。
在这里插入图片描述

num=5 # 0000 0101
result=$((~num))  # 得到: 1111 1010
echo $result  # -6  # 上面负数在计算机中存储是取反加1,1000 0101 + 1 = 1000 0110(-6)num=-5 # 负数存储是补码即取反加1 :1111 1011
result=$((~num))  # 得到: 0000 0100
echo $result  # 4# 所以~作用:原数加1后再将符号取反

在这里插入图片描述
在这里插入图片描述
sizeof运算符(不是函数)计算某一个变量在当前系统的内存中所需占用的字节数:sizeof结果类型是size_t(typedef unsigned int/long size_t):
1.用于数据类型:sizeof(int)) = 4,sizeof(指针)大小永远是8字节。
2.用于变量:sizeof(var_name)。
在这里插入图片描述
while(真)执行,continue跳到循环首部,break跳出循环。switch case语句里定义了新的变量 , case里加{}。
在这里插入图片描述
在这里插入图片描述
如下do-while先执行一次循环。
在这里插入图片描述

1.2 数组:存数据类型相同的数据,数组下标越界导致段错误

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
如下不能用c=,用c[0]=。运行时才会将 i 赋值为3。
在这里插入图片描述
如下如果用msg[1],虽然越界了,但是系统给结构体分配很多字节,所以不报错。可用msg[0]到msg[n-1]。
在这里插入图片描述

int main()
{int value = 1;char str[10] = "-q1"; // NA:0 , -1:-1 , 1:1 , q1:0value = atoi(str);    //字符串转换为整数(不是ascii码), strtolprintf("%d\n",value); //0
}#define PLATFORM_NAME_PATH      "./a.py"
void get_machine_ver(char * result)
{char buffer[32] = {0};char cmd[128] = {0};strcpy(cmd, "python3 ");strcat(cmd, PLATFORM_NAME_PATH);FILE* file = popen(cmd, "r");if (file == NULL) {return;}// memset(buffer, '\0', sizeof(buffer));fgets(buffer, sizeof(buffer), file);printf("111,%ld\n",sizeof(buffer));  // 32   // char buffer[32] = {0};printf("222,%ld\n",strlen(buffer));  // 14 连换行符strncat(result, buffer, strlen(buffer)-1); // 去除换行符  // memcpy(result, buffer, strlen(buffer)-1); result长度不知,请确保 result 缓冲区足够大,以容纳 buffer 中的数据,并且不会发生缓冲区溢出的情况。// while (fgets(buffer, 10, file) != NULL) {//     strcat(result, buffer);// }pclose(file);return;
}int main(){char result[32] = {0};get_machine_ver(result);printf("333,%s",result); // 333, HP1-2C4F-0..
}char name[21];
memset(name,0,sizeof(name));
strcpy(name, "豫让");
printf("我的姓名是%s。\n",name);int main()
{char *names = "PSU";if(strcmp(names,"PSU")==0){puts("aaaa");  // 打印出}
}int main() {   // error: expected ‘)’ before string constant    少了int main()char name_str[30];char name_str1[30];strcpy(name_str,"/sys/bus/i2c/devices/");strcpy(name_str1,"17-0064");strcat(name_str,name_str1);printf("is : %s\n", name_str);   // /sys/bus/i2c/devices/17-0064  // printf("[%s]__%4d__[%s]  %s \n", __FILE__, __LINE__, __FUNCTION__, n->name);
}int main ()
{char str1[15];char str2[15];int ret;strcpy(str1, "abcdef");strcpy(str2, "ABCDEF");ret = strcmp(str1, str2);if(ret < 0){printf("str1 小于 str2");}else if(ret > 0) {printf("str1 大于 str2");}else {printf("str1 等于 str2");}return(0);    //str1 大于 str2
}void cp (char *path_from, char *path_to)
{FILE *fp_read = NULL;FILE *fp_write = NULL;char ch = !EOF;fp_read = fopen(path_from, "r");// if (fp_read == NULL)// {//     printf("您没有这个(%s)文件\n", path_from);// }fp_write = fopen(path_to, "w");while ((ch = fgetc(fp_read)) != EOF) // 读{fputc(ch,fp_write);   // 写}fclose(fp_read);fclose(fp_write);
}int main(void)
{char path_from[50];char path_to[50];printf("输入文件名:"); // D:\1.txtscanf("%s", path_from);printf("\n输入文件名:"); // D:\2.txt,不存在会自动创建scanf("%s", path_to);cp(path_from,path_to);return 0;
}
#include<stdio.h>char str[10];
char strbuf[10];
char *a(void)
{FILE *fp=0;if ((fp=fopen("a","rt")) ==0)  //a文件里写了 333aaa{printf("111");}if (fgets(strbuf, 10, fp) == NULL) {printf("222");fclose(fp);}strcpy(str,"B");strcat(str,strbuf);fclose(fp);return str;
}int main()
{char *b=a();printf("%s\n", b);  // B333aaa
}int main()
{FILE *fp=0;if ((fp = fopen("/tmp/bbb","r")) == 0){printf("file do not exist\n");fclose(fp); // Segmentation fault (core dumped),fp不存在不能close,上行没打印出是因为fclose报错早于printfreturn -1;}fclose(fp); // 走不到return 0;
}int main()
{int len,i=0;char * pid_name_config_1[] = {"GPU111111110","CPU0_DIMM0","MOC2.5_CPU"};printf("000,%s\n",pid_name_config_1[0]);  // 000,GPU111111110printf("111,%ld\n",sizeof(pid_name_config_1[0])); // 111,8(指针大小)printf("222,%ld\n",sizeof(pid_name_config_1)); // 222,24(3*8)len = (sizeof(pid_name_config_1)/sizeof(pid_name_config_1[0]));printf("333,%d\n",len); // 333,3printf("444,%ld\n",sizeof("GPU0")); // 444,5(最后\0结束符)printf("555,%ld\n",strlen("GPU0")); // 555,4char pid_name[20]={0};  // char pid_name[20][20]={0}; 可以,每一行用来存字符串,不是字符for(i=0; i<len; i++){strcpy(pid_name[i], pid_name_config_1[i]); // 错误,strcpy参数expected ‘char * restrict’ but argument is of type ‘charmemcpy(pid_name[i], pid_name_config_1[i], strlen(pid_name_config_1[i])); // 同上printf("666,%s\n", pid_name[i]);}
}#include <stdio.h>struct KeyValue {char *key;int value;
}__attribute__((packed)) scsi;typedef enum {TYPE_UNKNOWN=-1,ACBEL_R1CA,GW_CRPS800N2WA,GW_CRPS2000DWA,GW_CRPS1300D2WA,GW_CRPS1600D2,GW_CRPS2400D2
}vendor_t;const struct KeyValue KeyValueTable[] = {{"R1CA2302A", ACBEL_R1CA},{"GW-CRPS800N2WA", GW_CRPS800N2WA},{"GW-CRPS2000DWA", GW_CRPS2000DWA},{"GW-CRPS1300D2WA", GW_CRPS1300D2WA},{"CRPS1600D2", GW_CRPS1600D2},{"CRPS2400D2", GW_CRPS2400D2}
};int main() {printf("%s\n", KeyValueTable[0].key);printf("%d\n", KeyValueTable[0].value);printf("%p\n", KeyValueTable[0].key);printf("%p\n", KeyValueTable[0]);// printf("%s\n", KeyValueTable[1]);printf("000000000000\n");printf("%d\n", sizeof("R1CA2302A"));printf("%d\n", sizeof(char *));printf("%d\n", sizeof(int));printf("%d\n", sizeof(KeyValueTable[0]));printf("%d\n", sizeof(KeyValueTable[88888888]));printf("111111111111\n");printf("%d\n", sizeof(KeyValueTable));int length = sizeof(KeyValueTable) / sizeof(KeyValueTable[0]);printf("%d\n",length);return 0;
}

在这里插入图片描述

char temp_log_0[100] = {0};
sprintf(temp_log_0, " '%d' ", a);
char temp_log_1[100] = "echo ";
strcat(temp_log_1, temp_log_0);
char temp_log_2[100] = " >> /var/log/a.log";
strcat(temp_log_1, temp_log_2);
system(temp_log_1);   // C
if(-1 == std::system(temp_log_1)){};   // CPP
if(-1 == std::system("echo 'aaa' >> /var/log/a.log")){};std::ofstream outputFile01("a.txt", std::ios::out | std::ios::app); 
if (outputFile01.is_open()) {outputFile01 << "111" << std::endl; outputFile01.close(); 
}

2.指针:指针数组(这个数组的所有元素都是指针类型),数组指针(这个指针存放着一个数组的首地址)

空指针int *p=NULL/0防止未赋值即野指针。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
如下复制a。
在这里插入图片描述
如下用到指针,increament运行结束后指针销毁。
在这里插入图片描述
如下当调用move_p功能是p要往右移一位:move_p参数定义虽是指针,但调用时传入也是指针,复制一份。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
如下用双指针。
在这里插入图片描述
在这里插入图片描述

3.结构体:存放一组不同数据类型的数据

在这里插入图片描述
如下最后一行*pst就是queen结构体变量。
在这里插入图片描述
结构体复制:基本类型用=,字符串用strcpy,结构体memcpy。
在这里插入图片描述
结构体作为函数的参数:结构体成员较多,函数参数的初始化和赋值的开销很大,最好的办法就是传递结构体变量的地址。
在这里插入图片描述
在这里插入图片描述

#include <stdio.h>
int main(int argc, char **argv) {char *stty, *dev;dev = argv[1];stty = argv[2];printf("%s\n%s\n",dev,stty);
}

在这里插入图片描述

// a.c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>extern int h_errno;
int main(int argc, char **argv)
{char   *ptr, **pptr;char    str[INET_ADDRSTRLEN];struct hostent *hptr;  //while (--argc> 0) {ptr = *++argv;  //传入的域名if ( (hptr = gethostbyname (ptr) ) == NULL)   //完成域名解析{printf("gethostbyname error for host: %s: %s",ptr, hstrerror (h_errno) );continue;}printf ("official hostname: %s\n", hptr->h_name);for (pptr=hptr->h_aliases; *pptr!= NULL; pptr++)printf ("\talias: %s\n", *pptr);switch (hptr->h_addrtype) {case AF_INET:pptr = hptr->h_addr_list;for ( ; *pptr != NULL; pptr++)printf ("\taddress: %s\n",inet_ntop (hptr->h_addrtype, *pptr, str, sizeof (str)));  //hptr->h_addrtype我们获取的IP地址break;default:printf("unknown address type");break;}}exit(0);
}$ gcc a.c -o a
$ ./a www.baidu.com
official hostname: www.a.shifen.comalias: www.baidu.comaddress: 180.101.50.188  (浏览器输入都会跳转到百度)address: 180.101.50.242

4.static/extern:宏在编译预处理时用文本形式复制过来,inline内联函数先编译成二进制再插入调用的地方,不用跳转到原函数执行

什么函数被定义成内联函数呢?1.经常被调用(如果不经常被调用,节省一点时间也没意义),2.函数体里代码少(如果函数体里代码多,执行时间远大于跳转时间)。

如下static表示2(内部链接)。
在这里插入图片描述
如下extern表示引用外部的变量,从外面来的。
在这里插入图片描述

struct __person
{char    name[20];uint8_t age;
}
typedef __person person_t;// define仅仅是简单的字符串的替换,而typedef则给这个类型新起了一个名
// 以上两段代码也可合并为一段:
typedef struct __person
{...
}person_t;

5.makefile文件:make是一个解释makefile中指令的命令工具

C源程序 -> 编译预处理【#开头指令和特殊符号进行处理,删除程序中注释和多余空白行】-> 编译。
在这里插入图片描述
条件编译:最常用的两种格式#ifdef和#ifndef 。#undef :取消已定义的标识符
在这里插入图片描述
如下book145.c和_public.c都有 #include"_public.h",会重复包含。
在这里插入图片描述
在_public.c中如下这样写,_public.h就不会被重复包含。
在这里插入图片描述
如下$前一个tab键不能8个空格。make默认是make all,如果将all这行book3删除,则make不会编译book3,可指定make book3,book3相当于标签。-欧2是让编译效率最高,一般正式发布用。gcc命令选项 :-c编译不链接。
在这里插入图片描述

6.文件:fgets和fprintf以行方式读写文本文件,但不能读写二进制文件。用fread和fwrite可以读写文本文件和二进制文件

6.1 文本文件:返回FILE结构体

在这里插入图片描述
在这里插入图片描述
vi /tmp/test1.txt,可见有5行记录,不管执行多少次都是5行记录,因为文件打开方式是w,每次打开文件时都会清空原文件中的记录。
在这里插入图片描述
如下301可换成sizeof(strbuf),300字符(字符串结束符\0)+1个换行符。
在这里插入图片描述

int main() {int fd;char buffer[5] = {0};ssize_t bytesRead;fd = open("/home_a/abcd", O_RDONLY, 0444);bytesRead = read(fd, buffer, 4);if (bytesRead == -1) {printf("read error");return 1;}printf("Read %zd bytes: %s\n", bytesRead, buffer);  //Read 4 bytes: 0xffreturn 0;
}
#include <stdio.h>
int main() { // a.cchar str[100];printf("请输入一行字符串: ");if (fgets(str, sizeof(str), stdin) != NULL) {char *newline = strchr(str, '\n'); // strchr: 查找\n以及后面字符printf("换行符:%s\n", newline);if (newline != NULL) {*newline = '\0'; //替换为结束符}printf("你输入的字符串是: %s\n", str);return 0;}
}

在这里插入图片描述

6.2 二进制文件:没有行概念

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

6.3 文件定位:文件内部有一个位置指针,用来指向当前读写的位置,也就是读到第几个字节。在文件打开时,如果打开模式是r和w,位置指针指向文件的第一个字节。如果打开模式是a,位置指针指向文件的尾部,每当从文件里读n个字节或文件里写入n个字节后,位置指针会后移n个字节

文件位置指针与C中指针不是一回事,位置指针仅仅是一个标志,表示文件读写到的位置即读写到第几个字节,不表示地址。文件每读写一次,位置指针就会移动一次,不需要你在程序中定义和赋值,由系统自动设置。
在这里插入图片描述

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);FILE *fpLedColor=fopen(led_color,"w");
fseek(fpLedColor,0,SEEK_SET);  // SEEK_SET:从文件开头开始计算偏移量
fprintf(fpLedColor,"%s",sensor_flag?LED_GREEN_CODE:LED_YELLOW_CODE);
fprintf(stderr,"11\n"); // 打印在控制台,cpp也可用
fflush(fpLedColor);
fclose(fpLedColor);
http://www.xdnf.cn/news/1074709.html

相关文章:

  • 机器学习9——决策树
  • 新生代潜力股刘小北:演艺路上的璀璨新星
  • ROS常用的路径规划算法介绍
  • 面试复盘6.0
  • Java面试宝典:基础四
  • SpringSecurity6-oauth2-三方gitee授权-授权码模式
  • 详解快速排序
  • 宏任务与微任务和Dom渲染的关系
  • 左神算法之螺旋打印
  • Redis Cluster Gossip 协议
  • 在Linux系统中部署Java项目
  • 设计模式之装饰者模式
  • 2.安装Docker
  • 怎样学习STM32
  • 暴力风扇方案介绍
  • HarmonyOS实战:自定义表情键盘
  • FPGA实现CameraLink视频解码,基于Xilinx ISERDES2原语,提供4套工程源码和技术支持
  • llama.cpp学习笔记:后端加载
  • 图书管理系统练习项目源码-前后端分离-使用node.js来做后端开发
  • Conda 环境配置之 -- Mamba安装(causal-conv1d、mamba_ssm 最简单配置方法)-- 不需要重新配置CDUA
  • 领域驱动设计(DDD)【26】之CQRS模式初探
  • AlpineLinux安装部署elasticsearch
  • Kafka4.0初体验
  • Python爬虫:Requests与Beautiful Soup库详解
  • 重写(Override)与重载(Overload)深度解析
  • 【C++】C++中的友元函数和友元类
  • 71. 简化路径 —day94
  • Bugku——WEB篇(持续更新ing)
  • documents4j导出pdf
  • Ubuntu服务器(公网)- Ubuntu客户端(内网)的FRP内网穿透配置教程