C/C++ - 小语法集锦

本文探讨了C++编程中的多种实用技巧,包括全局变量与局部变量的区别、指针与整型间的转换、宏与内联函数的区别等,并介绍了如何打印vtbl中的函数地址等高级主题。

开头 "::" 的作用

//开头就是两个冒号用于引用全局变量 

int count = 0; //全局变量 

int main(void) { 
int count = 0; //局部变量 
::count = 1; //设全局变量 count 为 1 
count = 2; //设局部变量 count 为 2 
return 0; 
} 


 指针和int之间的转换

 

int main(){
	char a[8] = {0};
	memcpy(a, "abcdefg", 7);
	int b = (int)a;
	printf("%d\n", b);
	b = (int)(a+1);
	printf("%d\n", b);

	*((char *)b) = '1';
	printf("%s\n", a);
}

结果

-1078211756
-1078211755
a1cdefg

b两次获得的值,即a和a+1的地址相差1、通过将b的值转为地址后修改对应地址的值。

 #include <>与#include""区别

<>先去系统目录中找头文件,如果没有在到当前目录下找。所以像标准的头文件 stdio.h、stdlib.h等用这个方法。 
而""首先在当前目录下寻找,如果找不到,再到系统目录中寻找。这个用于include自定义的头文件,让系统优先使用当前目录中定义的。 

new []

 new一个类的数组,只能调用该类的默认构造函数或者无参数的构造函数。

C类型限定词

const:表示指定的变量初始化后将不能改变。

volatile:表示变量可能被其他程序改变,如

val1 = x;
/*一些不使用x的代码,也就是x不会改变*/
val2 = x;
有些编辑器,为了优化,则将x存在寄存器中,这样第二次使用时会很快,但是,x可能会被其他程序甚至硬件改变,所以val2获得的值还是原来的旧值。

这个时候,如果使用volatile将会避免这个问题。

注意const可以和volatile合用,因为const规定的是程序不能修改变量,但是变量可以被硬件改变。

restiict:表明某块内存只能由某个指针操作,memcpy为了保证两块地址不同,就使用了restrict。

Register变量

表明变量是存在寄存器中,而非内存中,这样操作该内存时会比较快,但是也就使得我们无法获得该变量的地址,因为地址是对内存而言的。

另外,即使将某个变量声明为Register,这个变量也不一定是Register,因为可能寄存器不够用,或者寄存器无法存储某个类型的变量,那么该变量将会变为auto变量,但是我们依然无法使用该变量的地址。


如何打印vtbl中的函数地址

#include <iostream>
using namespace std;

class Point2
{
public:
	void x(){printf("Point2::x\n");}
	virtual void y(){printf("Point2::y\n");}
	virtual void z(){printf("Point2::z\n");}
};

int main(){
	typedef void(*Fun)(void);
	Fun fun = NULL;

	Point2 p;
	int *pint=(int *)&p;//得到对象地址
	int *vtbl=(int *)pint[0];//第一个为vptr地址,vptr保存的是vtbl地址
	
	//打印出vtbl中的函数地址
	printf("%.8x\n",vtbl[0]);
	printf("%.8x\n",vtbl[1]);
	printf("%.8x\n",vtbl[2]);
	//执行vtbl中的虚函数
	fun = (Fun)vtbl[0];
	fun();
	fun = (Fun)vtbl[1];
	fun();
}
结果:
00411055
004110cd
00000000
Point2::y

Point2::z


宏和inline函数区别

使用宏和内联函数都可以节省在函数调用方面的时间和空间开销。二者都是为了提高效率,但是却有着显著的区别:
(1)、在使用时,宏只做简单的预处理器符号表(字符串)中的简单替换。而内联函数可以进行参数类型检查,且具有返回值(也能被强制转换为可转换的合适类型)。
(2)、内联函数首先是函数,函数的许多性质都适用于内联函数(如内联函数可以重载)。
(3)、内联函数可以作为某个类的成员函数,这样可以使用类的保护成员和私有成员。而当一个表达式涉及到类保护成员或私有成员时,宏就不能实现了(无法将this指针放在合适位置)。


可以用内联函数完全替代宏。
但是在使用内联函数时也要注意:作为内联函数,函数体必须十分简单,不能包含循环,条件,选择等复杂结构,否则不能作为内联函数。
实际上,编译器的优化系统会自动将一些简单函数变成内联函数。而一些复杂的函数,即使指定为内联,编译器也会自动当作普通函数。


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值