c++基础(6-8)

来源:互联网 发布:非线性最优化确定参数 编辑:程序博客网 时间:2024/05/01 14:59

第六章 编译预处理

预处理命令

l  文件包含:#include

l  条件编译:(#if   #ifndef    #ifdef    #endif    #undef 主要是编译时进行有选择的挑选,注释掉一些代码,达到版本控制、防止文件重复包含

l  布局控制:(#progma) 为编译程序提供非常规的控制流信息

l  宏替换:(#define)可以定义符号常量、函数功能、字符串拼接等功能

宏(macro)(带有参数和不带参数)

l  宏替换是简单的代换,不是说明也不是语句,行末不加分号。

l  宏定义在函数之外,作用域从宏命令开始直到源程序结束。

l  取消宏:命令#undef 如下:

#define pi 3.14

void main(){}

#undef pi

l  允许宏嵌套

内联函数(inline):主要解决程序的运行效率

l  如果把一个函数定义为内联函数,在程序编译阶段,编译器就会在每次调用该函数的地方都直接替换成该函数体的代码,省去了函数的调用、相应地保存现场。参数传递和返回操作等所需要的时间,加快程序执行速度。

l  事实上我们可以用内联函数完全取代预处理宏。内联函数和宏的区别在于,宏是由预处理器对宏进行替代,而内联函数是通过编译器控制来实现的。而且内联函数是真正的函数,只是在需要用到的时候,内联函数像宏一样的展开,所以取消了函数的参数压栈,减少了调用的开销。你可以象调用函数一样来调用内联函数,而不必担心会产生于处理宏的一些问题。

文件包含

一般来说,在软件开发中将符号常量、全局变量,函数声明包含在头文件(.h文件)中,并将其定义放在.cpp文件中。使用的时候,直接包含对应的头文件即可。

条件编译

l  #ifdef 标识符

程序段1;

#else

    程序段2;

#endif

含义:如果表示符已经被#define定义过了,对程序段1进行编译,否则编译程序段2

l  #ifndef和#ifdef形式一样,含义相反

l  #if 常量表达式

程序段1;

#else

    程序段2;

#endif

含义:如果常量表达式为非0,编译程序段1,否则编译程序段2。

其他命令 #error   #line

第七章 数组

C++字符串标准函数的原型在头文件string,h中,主要函数如下

l  strcpy()  复制字符串,调用形式:

cahr * strcpy(char destination[],   const char source[]);

l  strcat()  连接字符串,调用形式:

char * strcat(cahr destination[],  const char source[]);

l  strlen()求字符串的实际长度

注:

sizeof与strlen的区别与联系

ü  sizeof操作符的结果类型是size_t,它在头文件中typedef为unsigned int类型。

该类型保证能容纳实现所建立的最大对象的字节大小。

ü  sizeof是算符,strlen是函数。

ü  sizeof可以用类型做参数,strlen只能用char*做参数,且必须是以''\0''结尾的。

sizeof还可以用函数做参数,比如:

short f();

printf("%d\n", sizeof(f()));

输出的结果是sizeof(short),即2。

ü  数组做sizeof的参数不退化,传递给strlen就退化为指针了。

ü  大部分编译程序 在编译的时候就把sizeof计算过了 是类型或是变量的长度这就是sizeof(x)可以用来定义数组维数的原因

char str[20]="0123456789";

int a=strlen(str); //a=10;

int b=sizeof(str); //而b=20;

ü  strlen的结果要在运行的时候才能计算出来,时用来计算字符串的长度,不是类型占内存的大小。

 

ü  sizeof后如果是类型必须加括弧,如果是变量名可以不加括弧。这是因为sizeof是个操作符不是个函数。

 

ü  当适用了于一个结构类型时或变量, sizeof 返回实际的大小,

当适用一静态地空间数组, sizeof 归还全部数组的尺寸。

sizeof 操作符不能返回动态地被分派了的数组或外部的数组的尺寸

l  数组作为参数传给函数时传的是指针而不是数组,传递的是数组的首地址,

如:

fun(char [8])

fun(char [])

都等价于 fun(char *)

在C++里参数传递数组永远都是传递指向数组首元素的指针,编译器不知道数组的大小,如果想在函数内知道数组的大小, 需要这样做:

进入函数后用memcpy拷贝出来,长度由另一个形参传进去

fun(unsiged char *p1, int len)

{

    unsigned char* buf = new unsigned char[len+1]

    memcpy(buf, p1, len);

}

 

我们能常在用到 sizeof 和 strlen 的时候,通常是计算字符串数组的长度

看了上面的详细解释,发现两者的使用还是有区别的,从这个例子可以看得很清楚:

 

char str[20]="0123456789";

int a=strlen(str); //a=10; >>>> strlen 计算字符串的长度,以结束符 0x00 为字符串结束。

int b=sizeof(str); //而b=20; >>>> sizeof 计算的则是分配的数组 str[20] 所占的内存空间的大小,不受里面存储的内容改变。 

上面是对静态数组处理的结果,如果是对指针,结果就不一样了

char* ss = "0123456789";

sizeof(ss) 结果 4 ===》ss是指向字符串常量的字符指针,sizeof 获得的是一个指针的之所占的空间,应该是长整型的,所以是4

sizeof(*ss) 结果 1 ===》*ss是第一个字符 其实就是获得了字符串的第一位'0' 所占的内存空间,是char类型的,占了 1 位

strlen(ss)= 10 >>>> 如果要获得这个字符串的长度,则一定要使用 strlen

第八章 指针

指针的算术运算

指针的算术运算结果不是字节数,而是整体个数(根据数据类型)

const指针

l  const放在类型前,就声明了一个指向常量的指针

l  const放在* 和指针名之间,就是声明了一个指针常量(常指针)

l  综上,都加const,则变成了常量常指针

指针与数组

数组名只是一个符号,类似引用两个别名似的

函数指针

数据类型 (*函数指针名)(参数表)

先声明后使用

type func(type(*p)(type &, type &),type &,type &);

该函数func有3个参数,第一个参数为type(*p)(type &, type &),这就是一个函数指针,他指向一个带有两个type类型的参数并且返回type值的函数,另外两个参数都是type类型的引用。

0 0
原创粉丝点击