??xml version="1.0" encoding="utf-8" standalone="yes"?>#include <iostream>
#include <fcntl.h>
using namespace std;
int main()
{
int fd = open("demo.txt", O_RDWR, 0);
close(fd);
int fd1 = open("demo1.txt", O_RDWR, 0);
char *szMsg = "hello";
int size = write(fd, szMsg, strlen(szMsg)+1);
if (-1 == size)
{
cerr << "error!" << endl;
}
close(fd1);
return 0;
}猜一下上面程序的执行l果?br />在writeӞfd和fd1的值是一LQwrite fdӞ实际是write fd1?br />Z避免自己在程序中误操作,可以在close(fd)之后Q加上fd = -1;
[文章] 有关char指针的文章一?/strong> |
作?/strong>Q未?span class=Apple-converted-space> 来源Q月光Y件站 加入旉Q?005-2-28 月光软g?/p> |
[文章] 有关char指针的文章一(转自:http://www.moon-soft.com/doc/9040.htm) 先看以下代码: PHP源码: 看出差别了吗Q上一DASM用offset?abc"的地址Q然后赋l[ebp-4]Q也是pQ下同)?span class=Apple-converted-space> 而下一DASM却{了一个弯Q先?abc"的地址转到寄存器eaxQ然后再转赋lp?span class=Apple-converted-space> 有疑问了Qؓ什么不和上面的一P直接用offsetQVC是很聪明的(废话QM$的东西呀Q,不用offsetQ恐怕就是用不了了?span class=Apple-converted-space> offset是一条伪指oQ在~译的时候就已经把偏U量好了。offset是无法执行间接寻址的计的?span class=Apple-converted-space> 说明了什么? const char *p="abc"中的"abc"Q在~译期间已l处理好Q要了一块内存,存v来了Q在把地址赋给p的时候,可以直接用offset计算?span class=Apple-converted-space> 而char p[]="abc"中的"abc"Q是在运行期间动态分配内存给"abc"Q然后再出地址Q赋lp。heheQ这同时也说明了数组和指针的{h性?span class=Apple-converted-space> 我们再做一ơ实验,q一ơ我们把char p[]="abc"攑֜main()外,q在main()内用一个指针再指向p看看?span class=Apple-converted-space> PHP源码: q回p[]的声明放在main()外,变成了全局变量。结果main()内的t取p的指针的时候,直接用offset可以计算出来?span class=Apple-converted-space> 据小矛_所_字面|constQstaticQinlineQ全局变量都是攑֜静态数据区的。(但我感觉g不是如此Q只是全局变量和字W串在编译时处理好攑֜一P 不难发现Qp[]被声明成全局变量后,可以直接用offset计算地址Q说明静态数据区是编译时已l处理好的?br>再对照const char *p="abc"的ASMQ我们马上想刎ͼ"abc"是被C/C++存在静态数据区中的Q它的地址是"abc"在静态数据区的地址Q?span class=Apple-converted-space> 弄清了这个,有些问题也就可以惛_通了。下面这U用法,看来不能说是错误的了Q因?abc"是在静态数据区的,生存期可以说是整个程序: PHP源码: 看ASMQ?span class=Apple-converted-space> PHP源码: 一样也是用offset计算地址?span class=Apple-converted-space> C/C++l字W串的待遇真是太好了。ؓ了一个字W串Q几乎可以打破所有的指针规则。晕~~~~Q完Q?span class=Apple-converted-space> 附:W一ơ写q么长的文章Q写得挺晕的。本来我的C/C++也不是很U熟的,ASM也是一知半解,今天在CSDN上ؓq个问题郁闷了半天,和几个h讨论了一下,最后就写了q么一文章。希望大家赏脸看看~~~有错一定要指正啊!最后特别感谢小矛_Q想飞的菜鸟Q骄傲的矛_Q菜菜,都是他咯Q,q有阿哥(是Kingzeus咯)的帮忙~~~~~~谢谢咯~~~~~~
__________________ 骄傲的石头回复: 堆几盘积木,心情好些了,所以再重新写一遍?span class=Apple-converted-space> PHP源码:
PHP源码:
PHP源码:
__________________ |
class Test
{
public:
int a;
int b;
void print();
void s();
void ss();
void fs();
};
void Test::print()
{
//cout << "hello" << endl;
}
void Test::s()
{
}
void Test::ss()
{
}
void Test::fs()
{
}
void f()
{
int s = 3;
cout << "&s" << &s << endl;
cout << "f" << endl;
}
class B:Test
{
};
int main()
{
Test t;
cout << sizeof(t) << endl;
cout << &t.a << endl;
cout << &t.b << endl;
Test tt;
cout << &tt.a << endl;
cout << &tt.b << endl;
typedef void (Test::*p)(void);
////Test t;
////t.print();
p fun = &Test::print;
printf("%p\n",fun);
fun = &Test::s;
printf("%p\n",fun);
fun = &Test::ss;
printf("%p\n",fun);
fun = &Test::fs;
printf("%p\n",fun);
f();
cout << "--------" << endl;
B b;
cout << sizeof(b) << endl;
////((Test::*print)fun)();
//Test *p4;
//fun(p4);
// Test t;
// (t.*fun)();
// Test d;
// (d.*fun)();
}
cȝ成员函数不是在类实例化的时候蝲入内存的。应该是~译链接的时候就在程序文件中定了相对地址。然后程序蝲入的时候,所有的函数都蝲入到内存的代码区。所以实例化对象的时候,只是甌了对象的成员变量的地址Q成员函数对于所有的cd象来_应该只有一份,在代码区q。而且cȝ成员变量和成员函C是存攑֜一P地址不是q箋的,是分开存放的)
TestcM的a,b变量地址是连l的Q每个占4字节。但是s(),ss(),fs()不是和a,bq箋的,而且Q这些函C_好像也ƈ不是严格q箋的,改一下函数名Q地址有可能会变化
public class Singleton
{
protected Singleton() { }
private static volatile Singleton instance = null;
/// Lazy方式创徏唯一实例的过E?br> public static Singleton Instance()
{
if (instance == null) // 外层if
lock (typeof(Singleton)) // 多线E中׃n资源同步
if (instance == null) // 内层if
instance = new Singleton();
return instance;
}
}
q应该是比较l典的线E安全的Singleton创徏方式Q但是还是一个更加简单也很Cool的线E安全的SingletonQ?/p>
class Singleton
{
private Singleton() { }
public static readonly Singleton Instance = new Singleton();
}
它省M上面CZ中那个laze构造过E,׃Instance是类的公共静态成员,因此相当于它会在cȝ一ơ被用到的时候被构造,同样的原因也可以省L它放在静态构造函数里的过E?/p>
q里实例构造函数被d定义为私有的Q所以客L序和子类无法额外构造新的实例,所有的讉K通过公共静态成员Instance获得唯一实例的引用,W合Singleton的设计意图?/p>
(2) all writes to volatile data are “observable” so they must be executed religiously, and
(3) all operations on volatile data are executed in the sequence in which they appear in the source code.
1.被声明ؓvolatile的变量其内容是不E_?unstable),它的值有可能q译器所不能知晓的情冉|改变?br>2.所有对声明为volatile的变量的写操作都是可见的Q必M格执行be executed religiously?br>3.所有对声明为volatile的变量的操作Q读写)都必M格按照源代码的顺序执行?br>volatile保每次直接从内存读取变量的倹{java中的volatile是跨U程保证上述三个条g的,而C++只是单一U程内保证?br>但是即是JAVA能够跨越U程保证Q仍然是不够的因为volatile和非volatile操作之间的顺序仍然是未定义的Q有可能产生问题Q考虑下面的代码:
volatile int vi;
void bar(void) {
vi = 1;
foo();
vi = 0;
}
我们一般会认ؓvi会在调用foo之前讄?,调用完后会被|ؓ0。然而编译器不会对你保证q一点,它会很高兴的你的foo()UMQ比如跑到vi = 1前面Q只要它知道在foo()里不会涉及到其它的volatile操作。所以安全的Ҏ是用栅栏memory barrier例如“asm volatile (”" ::: “memory”)加到foo的前面和后面 来保证严格的执行序?span style="COLOR: red">内存屏障保证代码执行时严格按照源代码的的序?br>
一U解?/p>
实际上,在可执行文g被加载之后,控制权立即交l由~译器插入的Start函数Q它对后面q些全局变量q行准备Q?br> _osver 操作pȝ的构件编?br> _winmajor 操作pȝ的主版本?br> _winminor 操作pȝ的次版本?br> _winver 操作pȝ完全版本?br> __argc 命o行参C?br> __argv 指向参数字符串的指针数组
_environ 指向环境变量字符串的指针数组
Start函数初始化堆q调用main函数Qmian函数q回之后,Start函数调用Exit函数l束该进E.
启动函数Start的源代码在:
crt0.c Microsoft Visual C++
c0w.asm Borladn C++
另一U解?/p>
Some of the stuff that has to happen before main():
set up initial stack pointer
initialize static and global data
zero out uninitialized data
run global constructors
Some of this comes with the runtime library's crt0.o file or its __start() function. Some of it you need to do yourself.
Crt0 is a synonym for the C runtime library.
Depending on the system you're using the follwing may be incomplete, but it should give you an idea. Using newlib-1.9.0/libgloss/m68k/crt0.S as an outline, the steps are:
1. Set stack pointer to value of __STACK if set
2. Set the initial value of the frame pointer
3. Clear .bss (where all the values that start at zero go)
4. Call indirect of hardware_init_hook if set to initialize hardware
5. Call indirect of software_init_hook if set to initialize software
6. Add __do_global_dtors and __FINI_SECTION__ to the atexit function so destructors and other cleanup functions are called when the program exits by either returning from main, or calling exit
7. setup the paramters for argc, argv, argp and call main
8. call exit if main returns
W三U解释:囫囵C语言Q三Q:谁调用了我的 mainQ?br>
现在最重要的是要跟得上潮流Q所以套用比较时髦的话,谁动了我的奶酪。谁调用了我?mainQ不q作机工作者,我劝大家q是不要赶时髦,今天Java热,明天 .net 行Q什么时髦就学什么。我的意思是先花几年把基本功学好Q等你赶旉的时候也好事半功倍。废话不多说了?br>
我们都听说过一句话Q?#8220;main是C语言的入?#8221;。我至今不明白ؓ什么这么说。就好像如果有h_“挣钱是?#8221;Q肯定无数砖头拍q来。这句话应该?#8220;挣钱是妞的一个条Ӟ只不q这个条件特别重?#8221;。那么上面那句话应该?“main是C语言中一个符P只不q这个符h较特别?#8221;
我们看下面的例子Q?br>
/* file name test00.c */
int main(int argc, char* argv)
{
return 0;
}
~译链接它:
cc test00.c -o test.exe
会生?test.exe
但是我们加上q个选项Q?-nostdlib (不链接标准库)
cc test00.c -nostdlib -o test.exe
链接器会报错Q?br> undefined symbol: __start
也就是说Q?br> 1. ~译器缺省是?__start W号Q而不?main
2. __start q个W号是程序的起始?br> 3. main 是被标准库调用的一个符?br>
再来思考一个问题:
我们写程序,比如一个模块,通常要有 initialize ?de-initializeQ但是我们写 C E序的时候ؓ什么有些模块没有这两个q程么呢Q比如我们程序从 main 开始就可以 mallocQfreeQ但是我们在 main 里面却没有初始化堆。再比如?main 里面可以直接 printfQ可是我们ƈ没有打开标准输出文g啊?不知道什么是 stdinQstdoutQstderr 以及 printf ?stdout 关系的群众请先看?C 语言中文件的概念)?br>
有h_q些东西不需要初始化。如果您真得q么惻Ih不要再往下看了,我个机软g不适合您?br>
聪明的h民群众会惻I一定是?main 之前q了些什么。ɘq些函数可以直接调用而不用初始化。通常Q我们会在编译器的环境中扑ֈ一个名字类g crt0.o 的文Ӟq个文g中包含了我们刚才所说的 __start W号。(crt 大概?C Runtime 的羃写,请大家帮助确认一下。)
那么真正?crt0.s 是什么样子呢Q下面我们给出部分伪代码Q?br>
///////////////////////////////////////////////////////
section .text:
__start:
:
init stack;
init heap;
open stdin;
open stdout;
open stderr;
:
push argv;
push argc;
call _main; (调用 main)
:
destory heap;
close stdin;
close stdout;
close stderr;
:
call __exit;
////////////////////////////////////////////////////
实际上可能还有很多初始化工作Q因为都是和操作pȝ相关的,W者就不一一列出了?br>
注意Q?br> 1. 不同的编译器Q不一定缺省得W号都是 __start?br> 2. 汇编里面?_main 是 C 语言里面?mainQ是因ؓ汇编器和C~译器对W号的命名有差异Q通常是差一个下划线'_'Q?br> 3. 目前操作pȝl构有两个主要的分支Q微内核和宏内核。微内核的优ҎQ结构清晎ͼ单,内核lg较少Q便于维护;~点是,q程间通信较多Q程序频J进出内核,效率较低。宏内核正好相反。我说这个是什么目的是Q没办法保证每个lg都在用户I间Q标准库函数Q中初始化,有些lg实可能不要初始化,操作pȝ在创E的时候在内核I间做的。这依赖于操作系l的具体实现Q比如堆Q宏内核l构可能在内核初始化Q微内核l构在用L_即同样是微内核Q这个东东也可能会被拿到内核I间初始化?br>
随着 CPU 技术的发展Q存储量的迅速扩展,代码复杂E度的增加,微内核被来多的采用。你会ؓ?10% 的效率代码复杂度增加么Q要知道每隔 18 个月 CPU 的速度׃M番。所以我对程序员的要求是Q我首先不要你的代码效率高,我首先要你的代码能让 80% 的hq速看懂ƈ可以l护?/p>
ȝQ?/p>
main函数执行之前Q主要就是初始化pȝ相关资源Q?/p>
1.讄栈指?/p>
2.初始化static静态和global全局变量Q即dataD늚内容
3.未初始化部分的赋初|数值型shortQintQlong{ؓ0Qbool为FALSEQ指针ؓNULLQ等{,?bssD늚内容
4.q行全局构造器Q估计是C++中构造函Ccȝ?/p>
5.main函数的参敎ͼargcQargv{传递给main函数Q然后才真正q行main函数