1、C/C++ 中 ,printf()函数计算参数时是从右到左进行压栈的,由于可变参数长度,所以右边的参数相对于左边是必须已知的;
2、
(1)cout<<(int &)a<< endl; //将a地址里面4个字节的存储内容以int 型的数据格式打印出来
(2)cout<<(int)a <<endl; //强制类型转化
(3)浮点数存储格式与普通的存储不太一样,是以近似相等的形式存储的;
3、无符号与有符号的转换
(1)无符号变量的最高位不是1 : unsign int 2 ==> sign int 2 0x0000 0010;
(2)无符号变量的最高位是1 :
unsign int 130 ==> sign int == 0x1000 0010 ==>0x1111 1110(变成原来的补码)
(3)无符号与有符号的加法:系统会将有符号的强制性转化为无符号的,所得得到的有符号负数会非常大(在负数比较小的情况下),利用补码进行相加;而printf是默认以有符号进行输出的;
4、判断一个数是不是2的N次方(2,4,8,16,...)
!x*(x-1) 二进制10,100,1000;01,011,0111; 结果为1则为是,否则为不是;
判断一个数有几个1:
while( x ){
count ++;
x &= x-1;
}
5、求平均值:
int fun(int x,int y){
return (x&y)+((x^y)>>1);
}
6、求两者中的较大者:
(a+b+abs(a-b))/2 //在不适用其他判断语句的时候;
7、在C++程序中调用被C编译器编译的函数,为什么要加extern “C” ?
答案:C++语言支持函数重载,C语言不支持函数重载。函数被C++编译后在库中的文件名字与C中的不一样。例如某个函数的原型是 void foo(int x,int y) ,C编译器编译后的在库中的文件名变为_foo,而C++编译器则会产生向_foo_int_int之类的文件名,解决名字匹配问题。
1、const修饰指针的情况:
int b = 500;
(1)const int *a = &b;
//上面的表示*a 的值不可改变(*a = 0 错误)但是可以通过改变b的值改变*a的值;
(2)int const *a = &b;
//上面的表达式与第一个一样;
(3)int * const a = &b;
//表示指针a的值是不允许改变的,(a++ 则错误);指针本身是常量,而指向的内容不是常量
(4)const int * const a = &b;
//表示指针本身和指针指向的内容也是常量,都是不可改变的。
2、const成员函数
在C++ 中任何不修改成员数据的函数都应该声明为const函数,有助于提高可读性,可以理解为只读函数,同时定义成const的成员函数,一旦企图修改数据成员的值,则编译器按出错处理,可以提高程序的可靠性;
在类中定义: int GetY() const; //定义与声明函数功能的时候const的位置要放在同一个地方,否则按不同函数处理;*如果把const放在最前面则表示函数的返回值是常量,意义就完全不一样了。
3、const与#define相比有什么不同:
(1)const常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查,而对于后者只进行字符替换,没有进行类型安全检查,并且在字符替换的时候可能会产生意想不到的错误(边际效应);
(2)有些集成化的调试工具可以对const常量进行调试,但是不能对宏常量进行调试。在C++程序中只使用const常量而不使用宏常量,即const常量完全取代宏常量
4、在const成员函数中要修改类中的成员变量的时候怎么办?
C++程序中,类里面的数据成员加上mutable后,修饰为const的成员函数;
private: mutable int count;
5、内存对其 与sizeof():内存对其是为了更快地读取数据,有可能带来内存浪费,是以空间换取时间的一种做法:例如不对齐int数据,可能要读取两次。
1:数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小或者成员的子成员大小(只要该成员有子成员,比如说是数组,结构体等)的整数倍开始(比如int在32位机为4字节,则要从4的整数倍地址开始存储。
2:结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储.(struct a里存有struct b,b里有char,int ,double等元素,那b应该从8的整数倍开始存储.)
3:收尾工作:结构体的总大小,也就是sizeof的结果,.必须是其内部最大成员的整数倍.不足的要补齐s
char *ch = “helloadf”; sizeof(ch) = 4; 这是因为ch是一个指针,指针的大小是一个定值,就是4(在gcc编译器下32位系统,指针的大小为4)
求指针字符串的长度:strlen(ch); sizeof(*ch) = 1;//求的是指针指向的首个字节内容的大小;
4:在C++类中:计算类中数据成员的大小,静态变量是存放在全局数据区的,而sizeof计算栈中分配的大小,是不会计算静态变量在内的;空类的占用的空间为1;虚继承的空类涉及到虚表,占用的空间为4(指针);
6、sizeof()与strlen()的区别
(1)sizeof 是运算符,可以用类型做参数;而strlen是函数,strlen的参数必须为char*,且必须以’\0’ 结尾;
(2)sizeof的结果要在运行的时候才能计算出来,用来计算字符串的长度,而不是类型占内存的大小;
(3)....
7、以下代码的输出的结果是多少?
char var[10];
int test(char var[])
{
return sizeof(var); 0
}
//此时输出的结果为4,因为这个时候的var已经退化为一个指针了;
那么如何改进呢?
int test (char var[]) //或者int test(char *var)
{
char ch[];
strcpy(ch,var);
return sizeof(ch);
}
更常见的方法是将var的长度len当做一个参数传进函数的形参里面;
8、内联函数与宏定义???
9、这个函数有什么问题?该如何修改?
char *strA()
{
char str[] = “hello”;
return str;
}
//这个函数在调用完了之后,str[]的空间就被回收了;所以返回的结果是不确定的且不安全的,随时都有可能被回收;
1)修改://这是因为局部数组是局部变量,它对应的是内存中的栈。指针变量是全局变量,它所对应的地内存的全局变量。字符串常量保存在只读数据区域而不是像全局变量一样存储在静态存储区;
const char *strA()
{
char *str = “hello”;
return str;
}
2)或者://通过static开辟一段静态存储空间
const char *strA()
{
static char str[] = “hello”;
return str;
}
10、指针数组与数组指针?????
拓展:int a[10] //(&a +1) 表示a[11] 这是因为数组是一个指针,&指针表示指针的指针;就是&a直接表示数组a整体在内存中的首地址,此时再加一表示跳向整个数组a,指向下一个地址
11、this指针????
12、
堆、栈、堆栈的区别与联系:https://www.cnblogs.com/guoxiaoyan/p/8664150.html