C笔记_杂

  1. 文件管理系统

    a.文件存储路径——相对路径&绝对路径
    一般地,vs工程当前路径为工程文件名的下级目录。如创建helloworld工程,“.\1.txt”的全路径为“c:\helloworld\helloworld\1.txt”,如果操作某个目录下文件后,那么当前路径就变为上次操作文件所在的目录,不再是工程文件名的下级目录。

    b.fopen 和 fopen_s
    fopen :

    FILE *fp1;//建立一个文件操作指针

    fp1= fopen (“111.txt”, “a”); //将指向这个文件的文件流给fp1

    fprintf(fp1,“input format : %s \n”, name); //写入

    fclose(fp1);

    fopen_s :

    FILE *fp1;//建立一个文件操作指针

    errno_t err; //判断此文件流是否存在 存在返回1

    err = fopen_s(&fp1,“File Information.txt”, “a”); //若return 1 , 则将指向这个文件的文件流给fp1

    fprintf(fp1,“input format : %s \n”,name); //写入

    fclose(fp1);

    访问方式:

    “r”
    打开以进行读取。如果该文件不存在,或无法找到,fopen_s调用失败。
    “w”
    打开一个空文件以进行写入。如果该文件存在,其内容将被销毁。
    “a”
    打开以进行写入 (追加) 而不将新数据写入文件之前删除的 EOF 标记文件的末尾。如果它不存在,则创建该文件。
    “r+”
    将打开并读取和写入。 (该文件必须存在。
    “w+”
    打开一个空的文件进行读写。如果该文件存在,其内容将被销毁。
    “a+”
    将打开并读取文件和追加。追加操作包括删除 EOF 标记的新数据写入到文件并在编写完成后还原 EOF 标记之前。如果它不存在,则创建该文件。
    通过打开文件时"a"或"a+"访问类型,所有写操作出现在文件的结尾。可通过使用定位文件指针fseek或rewind,但其始终移回至该文件的末尾之前任何写入,因此无法覆盖现有数据执行操作。
    "a"模式下不会追加到该文件之前删除 EOF 标记。追加发生后,MS-DOS TYPE 命令仅显示最原始的 EOF 标记的数据和追加到文件中没有任何数据。"a+"模式不会追加到该文件之前删除的 EOF 标记。后追加,MS-DOS TYPE 命令在文件中显示所有数据。"a+“模式所需的追加到流文件,将终止通过使用 CTRL + Z EOF 标记。
    当"r+”,“w+”,或"a+"指定访问类型,允许读取和写入。 (就说是打开"更新"文件)。 但是,当从阅读切换到书写,输入的操作必须会遇到 EOF 标记。如果没有任何 EOF,则必须使用中间文件定位函数调用。文件定位函数是fsetpos,fseek,和rewind.从读数到写切换时,您必须使用中间调用fflush或文件定位函数。

2.const的作用:

1、可以定义const常量,具有不可变性。

例如:const int Max=100; Max++会产生错误;
https://zhidao.baidu.com/question/1046170816022128979.html

3.如何解决多个.C文件中添加相同的头文件导致重定义的问题,使得所有宏定义都放在同一个.h文件中。
解决办法:
使用图示宏定义。在这里插入图片描述
3.volatile的使用
C语言中*(volatile unsigned int *)0x500的解释:

如下;

(unsigned int *)0x500:将地址0x500强制转化为int型指针
*(unsigned int *)0x500=0x10:对地址为0x500赋值为0x10

其中volatile关键字有以下用途:

(1)用来同步,因为同一个东西可能在不同的存储介质中有多个副本,有些情

况下会使得这些副本中的值不同,这是不允许的,所以干脆用volatile,让它只

有一个,没有其他的副本,这样就不会发生不同步的问题。

如下所示:

volatile的意思是告诉编译器,在编程源代码时,对这个变量不要使用优化。
在一般的程序设计中,如:
int *a; int b;
b = (*a) * (*a);这种情况。
通常编译器为了减少存储器的读写时间,会把代码优化为:
int a; int b; int c;
c = a;
b = c * c;
如果把int a改为volatile int a编译器就不会自动把它优化掉了。在整个运算过程中,对变量
a的值又读取了一次。防止因变量
a的值在这一期间发生了改变,而导致程序结果的错误。

(2)防止编译器优化去掉某些语句,像我在arm中见到个寄存器非常奇怪,

当中断来的时候,相对应的位置1,而清0又不能向这位写0,向这位写1才是1才

是清中断(清0)

// 假设0x560012300 为寄存器地址
#define INTPAND *(volatile unsigned int *)0x560012300

INTPAND = INTPAND; // 清中断

像编译器如果看到有INTPAND = INTPAND;这种看似无用的操作,如果没有

volatile说明,编译器就很有可能会去掉INTPAND = INTPAND;实际上有用的东

西,却被编译器当没用的东西优化掉了。

(3)当地址是io端口的时候,读写这个地址是不能对它进行缓存的,这是相对

于某些嵌入式中有cache才有这个。比如写这个io端口的时候,如果没有这个

volatile,很可能由于编译器的优化,会先把值先写到一个缓冲区,到一定时候

再写到io端口,这样就不能使数据及时的写到io端口,有了volatile说明以后,

就不会再经过cache,write buffer这种,而是直接写到io端口,从而避免了读写

io端口的延时。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值