1、
void main()
{
int a=1,b=0,c=-1,d=0;
d=++a||++b&&++c;
cout<;
return;
}
1. C/C++中,布尔值作为整型输出时,表现为:true输出1,false输出0;
2. 语句4为逻辑表达式,因此返回值d为1或0;
3. 短路原则:||或操作符左操作数为真,即可停止判断,返回1。
【解释】运算符优先级:&& > || > =
所以先计算++b&&++c,++c为0,所以整体是false=0,再计算++a||0,++a为true,
所以整体是true=1,所以d=1
2、
int a=0;
class someClass{
int b;
static int c;
};
int main(){
int d=0;
someClass *p=new someClass();
return 0;
}
变量a 全局变量 存放在全局变量区
变量b 类的成员变量 由类的定义决定 在main函数中类A动态分配 因此b在堆区(注意理解b,因为对象有动态分配空间时,里面已经包含了成员变量的空间,所以成员变量也存储在堆中。)
变量c 静态成员 静态存储区
变量d 局部变量 栈区
3、如下哪一段代码不能给地址0xaae0275c赋值为1?
volatile int *p=(int *)0xaae0275c; *p=1 //对
*(volatile int *)0xaae0275c=1 //对
volatile int *p=(int *)0xaae0275c; p[0]=1 //对
(volatile int *)0xaae0275c[0]=1 //错
【注】任何p[i]实质上都是*(p+i).
【解释】(volatile int *)0xaae0275c[0]=1为什么错?
[]运算符优先级较高,所以先0xaae0275c[0]取出这个地址的值,然后将值强制转换成int* 指针,再赋值,显然是错误的。
最后相当于int *p; p = 1,显然是行不通的
【修改成正确的-->加上一对括弧】( (volatile int *)0xaae0275c )[0]=1
4、
struct st_task
{
uint16_t id;
uint32_t value;
uint64_t timestamp;
};
void fool()
{
st_task task = {};
uint64_t a = 0x00010001;
memcpy(&task, &a, sizeof(uint64_t));
printf("%11u,%11u,%11u", task.id, task.value, task.timestamp);
}
上述fool()程序的执行结果为()
答:1,0,0
void test2() //题1
{
char string[10], str1[10];
int i;
for(i=0; i<10; i++)
{
str1 = 'a';
}
strcpy( string, str1 );
}
//数组名str1为 char *const类型的右值类型,根本不能赋值
//strcpy进行拷贝操作,strcpy会从源地址一直往后拷贝,直到遇到'\0'为止。
void test2()
{
char string[10], str1[10];
int i;
for(i=0; i<9; i++)
{
str1[i] = 'a';
}
str1[9] = '\0';
strcpy( string, str1 );
}
void GetMemory( char **p, int num ) //题2
{
*p = (char *) malloc( num );
}
void Test( void )
{
char *str = NULL;
GetMemory( &str, 100 );
strcpy( str, "hello" );
printf( str );
}
【答】malloc是否成功没判断;malloc的内存没释放;
void GetMemory( char **p, int num )
{
*p = (char *) malloc( num );
if(NULL == p) //判断
{
printf("申请失败!\n");
}
}
void main( void )
{
char *str = NULL;
GetMemory( &str, 100 );
strcpy( str, "hello" );
printf( str );
free(str); //释放
str == NULL; //置NULL
}
考点二:写出完整版的strcpy函数
//为了实现链式操作,将目的地址返回,加3分!
char * strcpy( char *strDest, const char *strSrc )
{
assert( (strDest != NULL) && (strSrc != NULL) );
char *address = strDest;
while( (*strDest++ = * strSrc++) != ‘\0’ );
return address;
}
考点三:已知类String的原型,编写类String的构造函数、析构函数和赋值函数
class String
{
public:
String(const char *str = NULL); // 普通构造函数
String(const String &other); // 拷贝构造函数
~ String(void); // 析构函数
String & operator =(const String &other); // 赋值函数
private:
char *m_data; // 用于保存字符串
};
6、请写一个C函数,若处理器是Big_endian的,则返回0;若是Little_endian的,则返回1
int checkCPU()
{
union w
{
int a;
char b;
} c;
c.a = 1;
return (c.b == 1);
}
7、请说出static和const关键字尽可能多的作用
static关键字至少有下列n个作用:
(1)函数体内static变量的作用范围为该函数体,不同于auto变量,该变量的内存只被分配一次,因此其值在下次调用时仍维持上次的值;
(2)在模块内的static全局变量可以被模块内所用函数访问,但不能被模块外其它函数访问;
(3)在模块内的static函数只可被这一模块内的其它函数调用,这个函数的使用范围被限制在声明它的模块内;
(4)在类中的static成员变量属于整个类所拥有,对类的所有对象只有一份拷贝;
(5)在类中的static成员函数属于整个类所拥有,这个函数不接收this指针,因而只能访问类的static成员变量。
const关键字至少有下列n个作用:
(1)欲阻止一个变量被改变,可以使用const关键字。在定义该const变量时,通常需要对它进行初始化,因为以后就没有机会再去改变它了;
(2)对指针来说,可以指定指针本身为const,也可以指定指针所指的数据为const,或二者同时指定为const;
(3)在一个函数声明中,const可以修饰形参,表明它是一个输入参数,在函数内部不能改变其值;
(4)对于类的成员函数,若指定其为const类型,则表明其是一个常函数,不能修改类的成员变量;
(5)对于类的成员函数,有时候必须指定其返回值为const类型,以使得其返回值不为“左值”。例如:
const classA operator*(const classA& a1,const classA& a2);
operator*的返回结果必须是一个const对象。如果不是,这样的变态代码也不会编译出错:
classA a, b, c;
(a * b) = c; // 对a*b的结果赋值
操作(a * b) = c显然不符合编程者的初衷,也没有任何意义。