牛客 C++刷题day47

1.++不能认为是原子操作,a是全局变量,在内存中,则++a一般被分为从内存取a到寄存器、+、回写到内存三步.

两个线程并发执行以下代码,假设a是全局变量,那么以下输出_哪个是可能的?
int a=1;
void foo(){
++a;
printf("%d",a);
}
解析
假设线程x和y同时执行,x和y可随时被抢占,a的初始值为1

A:3, 2
y先执行++a,a为2;
y再执行printf,a入栈,在打印到终端之前切换到x
x执行++a,a为3;
x执行printf,输出3;再切换到y
y执行打印,输出2

B:2 3
x先执行++a,a为2;
x再执行printf,输出2;切换到y
y执行++a,a为3;
y执行printf,输出3;

C:3 3
x先执行++a,a为2;切换到y
y执行++a,a为3;
y执行printf,输出3;切换到x
x执行printf,输出3

D:2 2
类似C, 执行++a操作但没有写回到内存

这里关键有两点:
(1)两个线程可随时被抢占
(2)++a和printf不是原子指令,可随时被打断;特别注意函数printf,a作为参数压栈后,a再变化则不会影响输出(printf实际打印的是压栈的参数,是值拷贝的栈变量)
2.

char *strcpy(char* dest, const char *src)   把从src地址开始且含有NULL结束符的字符串复制到以dest开始的  地址空间
void *memcpy(void *dest, const void *src, size_t n);    从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中 
void *memmove( void* dest, const void* src, size_t count );   由src所指内存区域复制count个字节到dest所指内存区域。
void *memset(void *s, int ch,   size_t  n);   将s中当前位置后面的n个字节 (typedef unsigned int size_t )用 ch 替换并返回 s
 

memcpy与memmove的目的都是将N个字节的源内存地址的内容拷贝到目标内存地址中。

但当源内存和目标内存存在重叠时,memcpy会出现错误,而memmove能正确地实施拷贝,但这也增加了一点点开销。

3.模板的好处

(1)可用来创建动态增长和减小的数据结构 (2)它是类型无关的,因此具有很高的可复用性。 (3)它在编译时而不是运行时检查数据类型,保证了类型安全 (4)它是平台无关的,可移植性 (5)可用于基本数据类型
4.

合法的浮点数有两种表示形式:

扫描二维码关注公众号,回复: 7510038 查看本文章
  1. 十进制小数形式。他有数字和小数点组成,必须有小数点。例如(123.)(123.0)(.123)。

  2. 指数形式。如123e3。字母e(或E)之前必须有数字,e后面的指数必须为整数。

  3. 规范化的指数形式里面,小数点前面有且只有一位非零的数字。如1.2345e8

5.

mode有以下几种方式:

打开方式 说明
r 以只读方式打开文件,该文件必须存在。
r+ 以读/写方式打开文件,该文件必须存在。
rb+ 以读/写方式打开一个二进制文件,只允许读/写数据。
rt+ 以读/写方式打开一个文本文件,允许读和写。
w 打开只写文件,若文件存在则长度清为0,即该文件内容消失,若不存在则创建该文件。
w+ 打开可读/写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件。
a 以附加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留(EOF符保留)。
a+ 以附加方式打开可读/写的文件。若文件不存在,则会建立该文件,如果文件存在,则写入的数据会被加到文件尾后,即文件原先的内容会被保留(原来的EOF符 不保留)。
wb 以只写方式打开或新建一个二进制文件,只允许写数据。
wb+ 以读/写方式打开或建立一个二进制文件,允许读和写。
wt+ 以读/写方式打开或建立一个文本文件,允许读写。
at+ 以读/写方式打开一个文本文件,允许读或在文本末追加数据。
ab+ 以读/写方式打开一个二进制文件,允许读或在文件末追加数据。

猜你喜欢

转载自www.cnblogs.com/Tonarinototoro/p/11704309.html