在C语言中,所有传递给函数的参数都是按值传递的。
#include <iostream>
using namespace std;
void Out(int* p)
{
int j = 11;
p = &j;
*p = 12;
cout<<*p<<endl;
}
int main(int argc,char*argv[])
{
int i = 10;
Out(&i);
cout<<"i="<<i<<endl;
cin>>i;
} ......
1.引言
C++语言的创建初衷是“a better
C”,但是这并不意味着C++中类似C语言的全局变量和函数所采用的编译和连接方式与C语言完全相同。作为一种欲与C兼容的语言,C++保留了一部分过程式语言的特点(被世人称为“不彻底地面向对象”),因而它可以定义不属于任何类的全局变量和函数。但是,C++毕竟是一种面向对象的程序设计语言,为了支持函数的重载,C++对全局函数的处理方式与C有明显的不同。
2.从标准头文件说起
某企业曾经给出如下的一道面试题:
为什么标准头文件都有类似以下的结构?
#ifndef __INCvxWorksh
#define
__INCvxWorksh
#ifdef __cplusplus
extern "C" {
#endif
/*...*/
#ifdef __cplusplus
}
#endif
#endif /* __INCvxWorksh */
显然,头文件中的编译宏“#ifndef __INCvxWorksh、#define
__INCvxWorksh、#end ......
简单的函数调用,通过简单的函数调用反汇编可以清楚了解如下
1.栈到底是什么,如何操纵栈的?
2.参数和临时变量是以什么形式在哪存放?
3.如何传递返回值?
举例:
#include <stdio.h>
int add(int a,int b)
{
int c=0;
c=a+b;
return c;
}
int main(void)
{
int x=0;
int y=3;
int z=4;
x=add(y,z);
return 0;
}
这是一个简单的通过调用函数计算两数之和的程序
VC6.0生成的汇编代码如下:
add函数
{
0040D750 push ebp
//把main函数的ebp压栈,ebp=1000,esp=896
0040D751 mov ebp,esp
//得到“新”栈基址,这里的新的意思是每个函数访问属于自己的一块栈区域,其实是相邻的内存区域,或者说栈只有一个。ebp=896,esp=896
0040D753 sub &nbs ......
1.scanf格式符 p9
ld long
lf double
2.三字母词 p22
为了表示一些特殊的字符,在老式的机器键盘中可能没有的字符,特别约定了一种三字母词,三字母词都以??开始,如下:
??( [ ??< { ??= # ??! | ??- ~
??) ] ??> } ??/ \ ??' ^
3.特殊字符 p23
\a 警告音,在我电脑上不能发音。
\v 垂直制表符
\ddd 八进制转义
\xddd 十六进制转义,注意:如果超过范围,那么结果是未定义的。(国内教科书直接告诉我们是\xdd ......
在函数体中添加以下代码:注:memcpy中的bitmap为bmp生成的c文件数组名
int width = 533;
int height = 615;
BYTE* DDBdata=new BYTE[width*height*2];
BYTE* DIBdata;
memcpy(DDBdata,(void *)bitmap,width*height*2);
CDC *pDC=GetDC();
CDC memDC ;
memDC.CreateCompatibleDC(pDC) ;
CBitmap nBitmap,*pOldBitmap;
nBitmap.CreateBitmap(width,height,1,16,DDBdata);
pOldBitmap = memDC.SelectObject(&nBitmap);
pDC->BitBlt(0,0,width,height, &memDC, 0, 0, SRCCOPY ) ;
memDC.SelectObject(pOldBitmap) ;
memDC.DeleteDC() ;
pDC->DeleteDC();
delete []DDBdata; ......
typedef 声明,简称 typedef,为现有类型创建一个新的名字。比如人们常常使用 typedef 来编写更美观和可读的代码。所谓美观,意指 typedef 能隐藏笨拙的语法构造以及平台相关的数据类型,从而增强可移植性和以及未来的可维护性。
第一、四个用途
用途一:
定义一种类型的别名,而不只是简单的宏替换。可以用作同时声明指针型的多个对象。比如:
char* pa, pb; // 这多数不符合我们的意图,它只声明了一个指向字符变量的指针,
// 和一个字符变量;
以下则可行:
typedef char* PCHAR; // 一般用大写
PCHAR pa, pb; // 可行,同时声明了两个指向字符变量的指针
虽然:
char *pa, *pb;
也可行,但相对来说没有用typedef的形式直观,尤其在需要大量指针的地方,typedef的方式更省事。
用途二:
用在旧的C的代码中(具体多旧没有查),帮助struct。以前的代码中,声明struct新对象时,必须要带上struct,即形式为: struct 结构名 对象名,如:
struct tagPOINT1
{
int x;
int y;
};
struct tagPOINT1 p1;
而在C++中,则可以直接写:结构名 对象名,即:
tagPOINT1 p1;
估计某人觉得经常多写一个struct太麻烦了,于是就发明了:
typedef struct tagP ......