c++基础,c风格的字符串处理,短类型向长类型转换unsigned和signed的处理

下面说明不正确的是()。

正确答案: D   你的答案: B (错误)

char a[10]="china";
char a[10],*p=a;p="china"
char *a;a="china";
char a[10],*p;p=a="china"

 

知识点:D中错误的原因是直接把字符串付给数组a,只能一个一个赋值,不能一起赋值,除非是声明变量的初始化时可以一起赋值。

另外,B我开始以为是*p=a,这当然是类型不对,但实际这里正是在初始化p,所以实际是是char *p=a,即相当于p=a,所以类型没有错。

其他,“china”如果赋值给指针,则该指针无论之前是否指向某个地方,现在都要指向静态常量区的该字符串,因为字符串赋值给指针会保存到静态常量区,所以也不能通过该指针的索引修改该字符串(如char *p;p=“aaaa”;p[1]='b'就不行),因为是常量,不允许修改。(不报错,但是会运行异常)。然而如果保存到数组中看,如第一个选项那样,则不会保存到常量区,此时可以下标索引进行读写都行。

特别的:char a[10]="china";char *p=a;p="1231",这时注意a不变,因为指针会改变指向的位置到静态常量区,此时a和p已经没有关系了,p指向的“1231”不可修改,但是a所指向的“china”是可以修改的。

 

 

 

int a[3][4],下面哪个不能表示 a[1][1]?

正确答案: C   你的答案: D (错误)

*(&a[0][0]+5)
*(*(a+1)+1)
*(&a[1]+1)
*(a[1]+1)

知识点:多维数组只有当所有维度的index都给定才会通过*或者【】取到内容,否则最优有维度还没有给定则是取到该维度的某一个子数组的首地址,比如二维数组则a[1]和*(a+1)都是取到第一行的第一个地址,而非第一行的第一个数字,只有两个维度都给定时才是取到值。所以2和4正确,3错误,因为3中的a[1]本身是地址,再取地址就不知道是啥东西了。

&a[0][0]是第一个元素的首地址,然后再加5取内容,即第一行有4个行元素,到第二列再第二个行元素,即为a[1][1],但是注意虽然&a[0][0]和a都表示第一个元素的首地址,但是*(a+5)取不到内容,因为如上一个知识点所述,这里没有给出两个维度,真正a+5取到的是行偏移了5的值,比如a地址c0,a+5地址则为e8,因为int是4字节,每行两个元素,总共偏移了5*4为20字节,所以c0+20=e8.即*(a+5)表示第5行首地址,但是实际上此时第5行已经越界了。这里也可以直接看第二个选项,里面的*(a+1)表示第一行的首地址

 

一个函数定义的返回值是float,它不能在return语句中返回的值的类型是: 

正确答案: F   你的答案: A (错误)

char
int
float
long
double
以上皆可以

 

我以为char不可以,但实际上char可以先到int再到float,所以是可以的。

 

 

signed char a=0xe0;

unsigned int b=a;

unsigned char c=a;

下面说法正确的是:

正确答案: C   你的答案: A (错误)

(a>0 )&&(b>0)为真
c==a 为真
b的16进制为0xffffffe0
都不对
 


当短类型向长类型转换时,如果原始类型为unsigned,进行零扩展,如果原始类型为signed,进行符号位扩展

所以a=1110 0000,为有符号的char(char只有1字节,8位,所以最高位已经给出来是1),实际是一个负数,因为符号位为1,所以这是一个补码,原码即除符号位以外取反加1得1010 0000,即-32,

a赋值给b时,由char到int,先扩展a到32位,由于a是unsigned,所以扩展符号位为1111,,,1110 0000(共32位),即b=0xffffffe0为无符号int型,即c选项正确

a赋值给c时,由char到char,不需扩展位数,此时得到c=1110 0000,即为无符号的224。

对于a选项:a>0是和int比较,即a扩展成int,为0xffffffe0是个负数所以小于0,b是无符号,变成有符号与0比较,当然是大于0,所以a选项错误。

b选项:c为无符号,a为有符号,在表达式计算时,应该扩展成int进行计算,这是c语言规定  实际上上面a选项也是扩展到int再计算的,扩展之后a=0xffffffe0为负数,c=0x000000e0,因为c为无符号扩展。所以有a<c

 

在一个64位的操作系统中定义如下结构体:

1

2

3

4

5

6

struct st_task

{

  uint16_t id;

  uint32_t value;

  uint64 / -t timestamp;

};

同时定义fool函数如下:

1

2

3

4

5

6

7

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函数()程序的执行结果为:

正确答案: A   你的答案: B (错误)

1,0,0
1,1,0
0,1,1
0,0,1

 

知识点:c语言采取的是小端存储策略,即先从低位往高位存,所以0x0000 0000 0001 0001存储到内存中是0001到id,0001到空位置,0000 0000到value中,最终结果即为A

 

下面的代码输出是()

 

正确答案: D   你的答案: A (错误)

1 4
4 4
1 2
4 8

 

union中的所有成员相对于基地址的偏移量都为零。d.x,d.y和d.s.x的起始地址都相同,共享内存空间,给任意一个变量赋值,其他两个变量也会赋相同的值。

 

 

注:由于d是局部变量, d.s.y未初始化之前输出应该是个随机值,而不是0.

上面第一个表格也体现了小端存储的概念,因为开始位置都是从小端开始的,即小端在右边,即上一题提到的情况,看如果要往内存中写数据,是要先尽量把低位往小端写,写不下的高位再储存在大端。

 

 

 

将一个字符串"abc"赋给字符串变量 str 的方法是 str="abc"。请问这句话的说法是正确的吗?

正确答案: B   你的答案: A (错误)

正确
错误

知识点:1 私有变量也会被继承只是不能直接使用而已,

2 使用父类私有变量或者函数的方式:a:把子类申明为父类的友元类,或者子类相应的函数申明为父类的友元函数,即在父类中写一句friend class ChildCalssName,此时可以直接访问私有变量和方法; b 父类自己提供相应的非private的方法,从而子类通过方法获取父类私有属性值,但是这种方式仍然不可以直接访问该属性,除非相应方法返回的是指针或者引用。

3 通过测试发现,我自己认为的可以写一个virtual然后子类重写该方法来获取父类私有属性是不可以的。这是错误的一定记住。

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值