C编译系统自动调用
1. TKstudi C编译器怎么设置
VC就很了不起,因为使用这样傻瓜化的工具只能让你看不到事物的本质。接下来我们就来深入的认识Turbo C编译器。 广义的编译器,包括了代码编译器(compiler),目标文件链接器(linker),库文件管理工具(如tc的tlib,gcc的ar),编译驱动工具(如VC的NMake,gcc的make),ANSI c/c++标准的头文件和库文件,扩展的头文件和库文件,集成开发环境(IDE),等等与编译相关的工具,所有这些工具的集合,就组成了广义上的编译器。
狭义的编译器,则仅指compiler。compiler只负责将源代码,即.c/.cxx/.cpp文件编译成为目标文件.o/.obj。编译过程的输入是源文件,包括自己书写的.c和.h以及系统提供的.h文件,编译的输出是目标文件。需要强调的一点时,在compile阶段,只处理源文件,所以不需要库文件和额外的目标文件的参与,因此,只要代码在语法上没有错误,compile就一定能产生目标文件。
对于一个广义的编译器来说以下几个部分是必备的:1.compiler,2.linker,3.系统提供的头文件和库文件。前面已经介绍了compiler,接下来看linker。
linker的功能是将目标文件进行装配,将浮动的地址变为确定的地址,这个工作是通过修改目标文件的重定位项来实现的,其具体的过程可以参考"Linker & loader"这本书,这是一本详细介绍linker和loader的好书,在此做个推荐。总之,link这一阶段处理的输入是目标文件,其输出是可执行文件,或动态库。
任何一个编译器都会提供库文件和与之对应的头文件,C/C++编译器一般都提供ANSI C/C++的库和相应的头文件。
从现在起我们就需要建立起一个概念,就是广义的编译过程,实际上是由编译和链接两个基本步骤组成的,如果能深刻的理解这两个步骤,就是一大进步了。
在编译器里,有一些默认的规定,我们需要了解。在编译器中,bin目录用于存放compiler、linker等工具,include目录用于存放头文件,lib目录用存放库文件,大多数的编译器的目录就是按这个来组织的。
接下来看Turbo C为我们提供了些什么
bin目录中:
CPP.EXE 是一个c语言预处理工具,就是负责对源代码进行预编译处理,不要理解为c++编译器
TCC.EXE 是一个C语言的编译器,可以将代码编译为目标文件,并且能自动调用tlink链接生成可执行文件
TASM.exe 是一个汇编工具,可以将x86的汇编代码编译成为目标文件
TLink.exe 是一个链接器,负责对目标文件、库文件等进行链接
TLib.exe 是一个库文件管理工具,可以将多个目标文件打包到一个库文件里
BGIOBJ.exe 可以将BGI文件转换为.obj文件
make.exe 符合GNU标准的make工具,可用于代码编译的管理
TURBOC.CFG tcc默认的编译参数配置文件
以上所有的工具的使用方法都可以直接键入相应的命令进行查看,如键入tcc即可看到tcc的使用方法,因此这里不再讲解。
BGI目录中:
EGAVGA.BGI 是EGAVGA的bgi驱动
FONT目录中:存放了BGI所使用到的各种字体文件
INCLUDE目录中:是Turbo C的库函数的所有的头文件,当要使用某个库函数时可以在这个目录下搜索,找到其所在文件和原型,这里不在详细叙述。
重点讲一下Lib目录:
init.obj文件是C语言的启动代码,它负责建立C程序运行的堆栈、初始化内存、调用C入口函数等。这部分代码是使用汇编书写的,其源代码可以在TC(官方版)里找到,名称为Init.ASM。
c0t.obj、c0s.obj、c0m.obj、c0c.obj、c0l.obj和c0h.obj文件,都是c code的入口函数实现,入口函数将会读取环境变量,并调用c语言中的main函数,将命令行参数传入main函数中,之后的控制权就交给了main函数,也就是我们常说的C的主函数main。由于Turbo C中有不同的内存模式,因此以上6个文件分别对应TC中6种不同的内存模式。
cc.lib、ch.lib、cl.lib、cm.lib、cs.lib五个文件都是TC提供的ANSI C标准库的库文件,分别对用不同的内存模式:
cc compact模式
ch huge模式
cl large模式
cm medium模式
cs small模式
2. 构造方法何时被调用
问题一:java中构造方法何时被调用 新建一个对象时被调用。也就是new的时候;
如:
public class A{
int i;
String c;
public A(){ } 无参构造方法
public A(int i,String c)
{
this.i = i;
this.c = c;
}两参构造方法
public static void main(String[] args){
A a = new A() ;调用了无参构造方法;
A a1 = new A(5,vieri);调用了两参构造方法
}
}
问题二:java 构造函数什么时候被调用执行 在java语言 中,构造函数又称构造方法。特殊性在于,与普通方法的区别是,他与类名相同,不返回结果也不加void返回值。构造函数的作用是初始化对象,即在创建对象时被系统调用(与普通方法不同,程序不能显示调用构造函数)。构造函数还能够被重载,即可以传入参数,当程序中包含有带参的构造函数时,系统将不会再提供的无参构造函数。构造函数特点:没有函数返回值,构造函数名与类名相同;当创建类对象的时候调用其对应的构造方法去创建。每创建一个类的实例都去初始化它的所有变量是乏味的。如果一个对象在被创建时就完成了所有的初始工作,将是简单的和简洁的。因此,Java在类里提供了一个特殊的成员函数,叫做构造函数(Constructor)。 一个构造函数是对象被创建时初始对象的成员函数。它具有和它所在的类完全一样的名字。一旦定义好一个构造函数,创建对象时就会自动调用它。构造函数没有返回类型,即使是void类型也没有。这是因为一个类的构造函数的返回值的类型就是这个类本身。构造函数的任务是初始化一个对象的内部状态,所以用new操作符创建一个实例后,立刻就会得到一个清楚、可用的对象。 构造方法是一种特殊的方法,具有以下特点。 (1)构造方法的方法名必须与类名相同。 (2)构造方法没有返回类型,也不能定义为void,在方法名前面不声明方法类型。(3)构造方法的主要作用是完成对象的初始化工作,它能够把定义对象时的参数传给对象的域。 (4)构造方法不能由编程人员调用,而要系统调用。 (5)一个类可以定义多个构造方法,如果在定义类时没有定义构造方法,则编译系统会自动插入一个无参数的默认构造器,这个构造器不执行任何代码。 (6)构造方法可以重载,以参数的个数,类型,或排列顺序区分。
问题三:一个类的构造函数和析构函数什么时候被调用 在对象被创建的时候就会调用构造函数,比如 声明一个类class A{...},当你在main函数中
A a ; 定义一个对象a的时候, 就调用构造函数,默认构造函数都是无参数的 ,构造函数就相当给对象a初始化而已,就相当于c语言中 int a = 3 初始化a的值而已,因为你在类中是不能直接给private中的类成员赋值的,所以就靠构造函数,不过要注意有参构造和无参构造,默认都是无参的,比如你A a(1, 3)这样的就不对了 除非你在类中写一个带参数的构造函数。
当函数调用结束的时候,会自动调用析构函数,比如你在clsaa A { public:Add().....},
当你A a; a.Add();后 就自动调用析构,你可以在类中 ~A{cout。。。},你就会发现调用
a.Add() 后就打出你在析构函数中写的东西,是自动调用的,析构的作用就是释放对象占用的资源。以为默认析构什么也不打印,所以你不会直观看出析构函数什么时候执行,自己在析构中加上打印的语言你就会看到了。希望对你能有所帮助
问题四:为什么说构造方法是一种特殊的方法?构造方法什么时候执行?被调用? 构造方法没有返回值,方法名和类名一样,其作用是用于在NEW一个类的时候,会总先调用这个类的构造方法,构造方法内部可以作一些变量的初始化或在创建这个类时必须调用的一些方法和运算,他是不用特意去调用的方法,会随着类的创建而自动去调用
例如:我们需要做一个i+j的运算,在这期间我们用到了构造函数,让其改变了i和j的初始化值
public class Text {
int i = 0;
int j = 0;
/**
* Text 的构造函数 将i和J的值重新初始化赋值
*/
public Text() {
i = 1;
j = 2;
};
public static void main(String[] args) {
Text s = new Text();
此时当你NEW完Text()时程序已经自动执行了Text的构造 函数i和j的值已经是1和2
System.out.println(s.i + s.j);
}
}
问题五:构造函数何时被调用 问法还是有问题的,构造函数包括复制构造函数
对象被创建时构造函数被调用,关键词:创建时,A a; 这种形式,指针类型在new的时候才调用
复制构造函数,也是构造函数,用一个对象作为参数创建另一个对象时,或赋值(同样关注创建时)
如 A a(b);
A b;
A a = b;
以下的不是调用复制构造函数
A a,b; 默认(无参)构造被调用
a = b; 赋值
问题六:java中的构造方法到底有什么用?什么时候采用? 1.如果当用户没有定义构造方法时,编译器会为类自动添加形如类名() { } 的无参构造方法,但是一但自己定义了构造 方法,编译器将不再自动添加.
也就是说构造方法不是必须有的.如果你之前一直未自定义构造方法,当你new一个对象时,系统会自动调用默认的一个无伐构造方法,给你对象的实例变量赋初值,比如int型默认为0.但一旦你自己定义了构造方法并new一个对象后,你再new一个对象时系统将不再为你自动提供默认的无参构造方法,那么你必须自己定义一个构造方法,否则编译出错
2 构造器可以不只一个,这叫做方法的重载
3.构造方法不但是要给对象的实例变量赋初值,更重要的是还和new一起来创建对象 ,如果你的对象没有实例变量,当然不用给对象的实例变量赋初值,也就不需要有参的构造器.但这在实际应用中,是毫无意义的.因为没有实例变量的对象什么也干不了.
问题七:java中构造方法(类)有哪些条件,一般什么时候被调用 构造方法是类中比较特殊的方法、它有如下几个特点
1.方法没有返回值
2.方法名和类名相同
3.构造方法可以重载(包括参数类型不同的重载和参数个数不同的重载)
4.每个类默认会有一个无参的构造函数
例:
public Class User{
public User(){}
public User(String name,int age){
this.name = name;
this.age = age;
}
private String name;
private int age;
public String getName(){
return this.name;
}
public void setName(String name){
this.name = name;
}
public int getAge(){
return this.age;
}
public void setAge(int age){
this.age = age;
}
}
构造函数是在你New对象的时候被调用的
例: User user = new User();
问题八:构造方法和析构方法什么时候被调用 构造函数的作用是保证每个对象的数据成员都有何时的初始值。
析构函数的作用是回收内存和资源,通常用于释放在构造函数或对象生命期内获取的资源。
一般我们都知道构造和析构的次序:
构造从类层次的最根处开始,在每一层中,首先调用基类的构造函数,然后调用成员对象的构造函数。析构则严格按照与构造相反的次序执行,该次序是唯一的,否则编译器将无法自动执行析构过程。
构造函数和析构函数都是由编译器隐式调用的。这些函数的调用顺序取决于程序的执行进入和离开实例化对象时所在的那个作用域的顺序。一般而言,析构函数的调用顺序和构造函数的调用顺序相反,但是,对象的存储类可以改变析构函数的调用顺序。
对于在全局作用域中定义的对象,它们的构造函数是在文件中所有其他函数(包括main)开始执行之前被调用的(但无法保证不同文件的全局对象构造函数的执行顺序)。对应的析构函数是在终止main之后调用的。
exit函数会迫使程序立即终止,而不会执行自动对象的析构函数。这个函数经常用来在检测到输入错误或者程序所处理的文件无法打开时终止程序。
abort函数与exit函数功能相似,但它会迫使程序立即终止,而不允许调用任何对象的析构函数。abort函数通常用来表明程序的非正常终止。
自动局部变量的构造函数是在程序的执行到达定义这个对象的位置时调用的,而对应的析构函数是在程序离开这个对象的作用域时调用的(即定义这个对象的代码完成了执行)。每次执行进入和离开自动对象的作用域时,都会调用它的构造函数和析构函数。如果程序调用了exit或abort函数而终止,则不会调用自动对象的析构函数。
静态局部对象的析构函数只调用一次,即执行首次到达定义这个对象的位置时。对应的析构函数是在main终止或程序调用exit函数时调用的。
全局对象和静态对象是以创建它们时相反的顺序销毁的。如果程序由于调用了exit函数而终止,则不会调用静态对象的析构函数。
下面的demo演示了在几个作用域不同的存储类的CreateAndDestory的类的对象,它们的构造函数和析构函数的调用顺序。
[cpp] view plain
#include
#include
using namespace std;
class Demo
{
public:
Demo(int,string); 构造函数
~Demo(); 析构函数
private:
int objectID; ID number for object
string message; message describing object
};
Demo::Demo(int ID,string messagestring)
{
objectID = ID; set object's ID number
message = messagestring; set object's descriptive message
cout>
问题九:C++构造函数什么时候会被调用? Point的构造函数被调唬两次,你可以这么理解:
当你要构造一个Rect对象的时候,每个Rect对象是不是包含两个Point对象?
所以这就是为啥构造两次的原因了。
析构与构造是一样的,两次释放,每个Point分别被析构一次。
3. C语言中如何调用文件中的自定义函数
不知道你用的是什么开发工具。
用常规开发工具,通常情况下,有以下几种方法:
1、创建你的文件,include 你要调用的函数所在的文件,然后直接调用;
2、创建一个工程文件,将你所要调用函数的文件加载到工程文件中,然后,在你调用的文件中,声明你要调用的函数,然后调用即可;
3、将你要调用的函数所在的文件分离,让其不包含主函数,然后将其单独编译,生成obj文件,通过lib将其有obj文件转换为lib文件,建立单独的声明函数头文件,设置库文件目录,在你要调用的文件中include声明函数头文件,然后调用即可。
4. 如何用汇编实现C语言函数调用
1。对于“汇编调用”:
我知道你要调用func,而不是它本身,但如果这个函数比较复杂时是必须用逆向先分析func这个函数,然后再确定参数列表和返回值的……
2。对于你的内联汇编的代码:
这里到底要不要用add %3, %%rsp;还是一个问题,因为要看函数使用的是什么调用标准,有标准C的,VB的,Pascal的,包括fastcall,stdcall,cdecl等……
3。对于“知道函数参数的起始地址和长度”:
这个的话,除了参数中有字符数组和直接结构体什么的,所有的基本变量基本都是每8字节(64位)一个,并且Intel一般都用bigendian的,也就是说,在内存中 01 02 03 04 05 06 07 08 读入寄存器后会变为: 0x0807060504030201
所以说对于简单的函数,用8字节一个参数来做就好了……
而对于有字符数组什么的就必须用逆向分析了……
这个……只能进行逆向分析了……
反正你知道了函数的地址和长度……
就是你把编译为机器码的程序用反编译工具翻译成汇编,然后分析一下就好了,C语言的汇编还是比较简单……
比如这个函数:
int func(int a, int* b) {
// float要用到CPU的FPU,指令记不得,要查下
// 为了简单就改为int*
printf("a = %d, b = %d\n", a, *b);
return a;
}
编译成机器码后,反编译,如果不加优化,一般都会这样:
(假设函数入口地址为0400000h)
sub_0400000:
push rbp
mov rbp,rsp ; C函数参数度取使用堆栈式
; 参数在内存中这样: |...| a | b | ... |
; 由于是64位,故8字节对齐
mov rax,[rbp+8] ; rax = *(rbp+8) // 这里就是 rax = a
push rsi
mov rsi,[rbp+16] ; rsi = *(rbp+16) // rsi = b
; 调用C函数都是这样堆栈式,最后一个参数最先入栈
push [rsi]
push rax
push "a = %d, b = %d\n" ; 这里是便于理解,实际上是push这个字符串常量的指针
call printf ; printf("a = %d, b = %d\n",rax,*rsi)
add rsp,24 ; 平衡堆栈,用了3个参数,要还原3*8=24字节,但根据函数类型的不同去平衡,像调用VB的函数就不需要平衡堆栈……
; 还原数据
mov rsp,rbp
pop rsi
pop rbp
; 一般返回数据都用rax装载
mov rax,[rbp+8] ;rax=a
ret ; return rax
想调用未知参数列表的函数就是把以上过程倒过来,看着汇编把C的代码写出来……
破解注册码什么也是这样玩的……
实际上你可以直接用反编译的软件,比如IDA,直接自动分析,它反编译的虽然是汇编,但参数列表还是大部分都显示的……
但是,当编译器加优化大部分情况就必须自己分析了,因为:
int func(int a, int* b) {
printf("a = %d, b = %d\n", a, *b);
return a;
}
在优化情况下可能为(直接用寄存器传递数据):
sub_040000:
push rdx
mov rdx,rax
push rax
push rbx
push "a = %d, b = %d\n"
call printf
mov rax,rdx
pop rdx
ret
其实像www.pediy.com看雪学院有不少这方面的教程……
5. window内自带的C语言编译器怎么用
1、首先,输入【#include】。

注意事项:
尽管C语言提供了许多低级处理的功能,但仍然保持着跨平台的特性,以一个标准规格写出的C语言程序可在包括类似嵌入式处理器以及超级计算机等作业平台的许多计算机平台上进行编译。
6. windows怎么编译.c文件
(1)先用记事本编写如下所示的代码,并另存为hello.cpp,假设其保存路径为
C:\Users\Administrator\Desktop。
#include<iostream>
using namespace std;
int main()
{
cout<<"hello world!"<<endl;
return 0;
}
(2)用记事本写一段简单的批处理文件,内容如下所示,在保存文件时选择另存为,文件名
假设为batch.bat,bat是批处理文件的后缀,保存类型选择:所有文件(这个尤其需要注意),
假设其保存路径也是:C:\Users\Administrator\Desktop。
set path=D:\Softwares\en_Visual_Studio2010_Professional_x86_x16-81637\VC\bin
set include=D:\Softwares\en_Visual_Studio2010_Professional_x86_x16-81637\VC\include
set lib=D:\Softwares\en_Visual_Studio2010_Professional_x86_x16-81637\VC\lib
上面批处理文件的第一句话表示设置环境变量,这个也可以通过:计算机/属性/高级系统设置/
环境变量/用户变量,把D:\Softwares\en_Visual_Studio2010_Professional_x86_x16-81637\VC\bin
放到path的值里去,记得与之前已有值之间用";"隔开。这个path文件夹是我们装载VS2010时自
带的,在设置路径时要根据自己的安装路径进行修改,里面包含微软在Windows下给我们提供的
C/C++编译器cl.exe程序(编译器自身也是一个软件程序,只是它的作用是用来编译其它的程序),
当然还有link.exe链接程序,调用cl时,系统会自动调用link程序(后面将看到我们只用了cl命令就
可以进行C/C++程序的编译、链接)。后面两句话分别表示包含C++中自带的头文件库和静态链接
库,静态理解库包含了头文件中函数对应的实现部分,为了不让人们看到其中的源代码,它以二进
制文件形式编码,若要查看其内容需要进行反汇编。
(3)通过cmd命令进入DOS操作界面,输入cd C:\Users\Administrator\Desktop进入cpp文件和bat
批处理文件所在的位置,然后键入batch.bat进行批处理,这些操作在VS2010集成开发环境中都为我
设置好了,所以我们在里面写C/C++程序时并没有这样设置路径的繁琐操作,但是通过自己手动的
路径设置,我们会对程序的编译、链接、执行有更加深入的认识。
(4)键入cl hello.cpp,我们会看到计算机报出了“无法启动此程序,因为计算机中丢失mspdb100.dll。
尝试重新安装该程序以解决此问题”的系统储物,dll文件是动态链接库文件,其是在cl.exe程序运行时
才被加载进来的文件,这个静态链接库lib文件不同。这说明在D:\Softwares\en_Visual_Studio2010_
Professional_x86_x16-81637\VC\bin路径里没有找到mspdb100.dll,原来此文件在文件夹D:\Softwares\
en_Visual_Studio2010_Professional_x86_x16-81637\VC\Common7\IDE里,我们可以将此文件拷到bin
文件夹里,或将D:\Softwares\en_Visual_Studio2010_Professional_x86_x16-81637\Common7\IDE加到
批处理的path环境变量里,或者将其加到cpp文件所在的文件夹里,这只会引起在搜索顺序上的不同。
(5)再次键入cl hello.cpp,我们看到在C:\Users\Administrator\Desktop文件夹里得到了hello.obj文件,
这是编译后的输出文件,但是没有得到可执行exe文件,DOS界面里出现这样的错误“LINK:fatal error LNK
1104:cannot open file 'kernel32.lib' “这样的链接错误,kernel32.lib是Windows系统文件,通过Windows
自带的搜索工具,我们看到此文件在文件夹C:\Program Files\Microsoft SDKs\Windows\v7.0A\Lib里,我们
可以将其加到cpp文件所在的文件夹或bin文件里。再次键入cl hello.cpp,我们发现这次程序被成功编译链接
了,cpp文件所在的文件夹里多了两个文件:hello.obj和hello.exe。
(6)在DOS界面键入hello.exe,程序被执行,输出了我们预想的hello world!,至此,在Windows下模拟
linux命令行操作,编译C/C++文件全部完成了。
7. c语言的简单问题
首先确定你们老师建的文件是“c-file”还是“c-file.cpp”
给你提供一个无脑的方法吧:
新建文本文档,命名"1.txt",然后把这个文本文档改为“1.cpp”,然后双击这个文件,通常是默认用VC等编译器打开的。
在1.cpp里添加语句include"c-flie.cpp"(如果他建的文件是“c-file.cpp”)
在1.cpp里编写你的代码和main函数等等
然后编译一下1.cpp这个文件就可以了
通常情况下没有main函数是没法编译的,除非有的系统自动调用main,比如(MFC)这类东西;
8. c语言怎么调用dll文件
1、新建DLLTest文件夹,在该文件夹中新建source文件夹。

注意事项:
C语言能以简易的方式编译、处理低级存储器。C语言是仅产生少量的机器语言以及不需要任何运行环境支持便能运行的高效率程序设计语言。
9. vc2010怎么进行c语言编译
1,在windows桌面中Visual Studio打开软件并新建项目。

10. 函数C.一个类中可以有多个构造函数,多个析构函数
说法正确。
析构函数是自动调用的,不存在重载的可能,所以只有一个析构。
而构造和赋值,可以根据传入参数进行重载,所以可以有多个。
