帮我解释下!! 谢谢 这是求解有符号char类型的最值 char a=8*sizeof char(char)-1,b=1; b<<=a; 这两句不明白

第1-4章习题参考答案_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
第1-4章习题参考答案
上传于||文档简介
&&第-章​习​题​参​考​答​案
阅读已结束,如果下载本文需要使用0下载券
想免费下载更多文档?
定制HR最喜欢的简历
下载文档到电脑,查找使用更方便
还剩5页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢C语言题,求高手看看,最好能帮我详细解释下,谢谢了_百度知道设有定义:char p[]={'1','2','3'},*q=p;以下不能计算出一个char型数据所占自己数的表达式是A)sizeof(p) B)sizeof(char) C)sizeof(*q) D)sizeof(p[0])请详细解答,谢谢。
漫步联盟009E0
答案应该选A。对于B,计算的是char类型的字节大小,明显不对。C、D答案等价,计算的都是字符'1‘的所占字节数,所以也不对。
当然是A,sizeof(p)返回的是整个p数组占用的字节数.B返回一个char变量占的字节数C和D等价,*q和p[0]的数组类型都是char,所以返回的也是一个char变量占用的字节数.
A . P作为数组的名称,单独出现时也表示数组第一个元素所在的地址,即 p=&p[0],所以并不代表char类型
为您推荐:
扫描下载二维码C语言终极面试题【1】
C语言终极面试题【1】
4、设有以下说明和定义:typedef union { int k[5];} DATE;struct data { DATE}DATE则语句 printf(“%d”,sizeof(struct date)+sizeof(max));的执行结果是?答 、结果是:52。DATE是一个union, 变量公用空间. 里面最大的变量类型是int[5], 占用20个字节. 所以它的大小是20data是一个struct, 每个变量分开占用空间. 依次为int4 + DATE20 + double8 = 32.所以结果是 20 + 32 = 52.当然…在某些16位编辑器下, int可能是2字节,那么结果是 int2 + DATE10 + double8 = 20
5、请写出下列代码的输出内容#includemain(){int a,b,c,d;a=10;b=a++;c=++a;d=10*a++;printf(“b,c,d:%d,%d,%d”,b,c,d);return 0;}答:10,12,120
6、写出下列代码的输出内容#includeint inc(int a){return(++a);}int multi(int*a,int*b,int*c){return(*c=*a**b);}typedef int(FUNC1)(int in);typedef int(FUNC2) (int*,int*,int*);
void show(FUNC2 fun,int arg1, int*arg2){INCp=&int temp =p(arg1);fun(&temp,&arg1, arg2);printf(“%d\n”,*arg2);}
main(){show(multi,10,&a);return 0;}答:110
7、请找出下面代码中的所以错误说明:以下代码是把一个字符串倒序,如“abcd”倒序后变为“dcba”
1、#include”string.h”2、main()3、{4、 char*src=”hello,world”;5、 char* dest=NULL;6、 int len=strlen(src);7、 dest=(char*)malloc(len);8、 char* d=9、 char* s=src[len];10、 while(len–!=0)11、 d++=s–;12、 printf(“%s”,dest);13、 return 0;14、}答:方法1:int main(){char* src = “hello,world”;int len = strlen(src);char* dest = (char*)malloc(len+1);//要为\0分配一个空间char* d =char* s = &src[len-1];//指向最后一个字符while( len– != 0 )*d++=*s–;*d = 0;//尾部要加\0printf(“%s\n”,dest);free(dest);// 使用完,应当释放空间,以免造成内存汇泄露return 0;}方法2:#include #include main(){char str[]=”hello,world”;int len=strlen(str);for(int i=0; i<LEN 2; i++) {t=str[i];str[i]=str[len-i-1]; str[len-i-1]=t;}printf("%s",str);return 0;}
8、请问下面程序有什么错误?int a[60][250][1000],i,j,k;for(k=0;k&=1000;k++)for(j=0;j&250;j++)for(i=0;i&60;i++)a[i][j][k]=0;答案:把循环语句内外换一下
9、请问下面程序会出现什么情况?. #define Max_CB 500void LmiQueryCSmd(Struct MSgCB * pmsg){unsigned char ucCmdN......
for(ucCmdNum=0;ucCmdNum<MAX_CB;UCCMDNUM++) {......;}答案:死循环
12、以下代码中的两个sizeof用法有问题吗?void UpperCase( char str[] ) // 将 str 中的小写字母转换成大写字母{for( size_t i=0; i<SIZEOF(STR) sizeof(str[0]); ++i ) if( 'a'&=str[i] && str[i]&='z' )str[i] -= ('a'-'A' );}char str[] = "aBcDe";cout && "str字符长度为: " && sizeof(str)/sizeof(str[0]) &&UpperCase( str );cout && str &&答:函数内的sizeof有问题。根据语法,sizeof如用于数组,只能测出静态数组的大小,无法检测动态分配的或外部数组大小。函数外的str是一个静态定义的数组,因此其大小为6,函数内的str实际只是一个指向字符串的指针,没有任何额外的与数组相关的信息,因此sizeof作用于上只将其当指针看,一个指针为4个字节,因此返回4。
13、写出输出结果main(){int a[5]={1,2,3,4,5};int *ptr=(int *)(&a+1);printf("%d,%d",*(a+1),*(ptr-1));}输出:2,5*(a+1)就是a[1],*(ptr-1)就是a[4],执行结果是2,5&a+1不是首地址+1,系统会认为加一个a数组的偏移,是偏移了一个数组的大小(本例是5个int)int *ptr=(int *)(&a+1);则ptr实际是&(a[5]),也就是a+5原因如下:&a是数组指针,其类型为 int (*)[5];而指针加1要根据指针类型加上一定的值,不同类型的指针+1之后增加的大小不同a是长度为5的int数组指针,所以要加 5*sizeof(int)所以ptr实际是a[5]但是prt与(&a+1)类型是不一样的(这点很重要)所以prt-1只会减去sizeof(int*)a,&a的地址是一样的,但意思不一样,a是数组首地址,也就是a[0]的地址,&a是对象(数组)首地址,a+1是数组下一元素的地址,即a[1],&a+1是下一个对象的地址,即a[5].14、请问以下代码有什么问题:int main(){char *str=&a;strcpy(str,"hello");printf(str);return 0;}没有为str分配内存空间,将会发生异常问题出在将一个字符串复制进一个字符变量指针所指地址。虽然可以正确输出结果,但因为越界进行内在读写而导致程序崩溃。char* s="AAA";printf("%s",s);s[0]='B';printf("%s",s);有什么错?"AAA"是字符串常量。s是指针,指向这个字符串常量,所以声明s的时候就有问题。cosnt char* s="AAA";然后又因为是常量,所以对是s[0]的赋值操作是不合法的。
18、下面的语句会出现什么结果?char szstr[10];strcpy(szstr,”″);答案:长度不一样,会造成非法的OS,应该改为char szstr[11];
19、(void *)ptr 和 (*(void**))ptr的结果是否相同?答:其中ptr为同一个指针.(void *)ptr 和 (*(void**))ptr值是相同的
20、问函数既然不会被其它函数调用,为什么要返回1?int main(){int x=3;printf(“%d”,x);return 1;}答:mian中,c标准认为0表示成功,非0表示错误。具体的值是某中具体出错信息24、char a[10],strlen(a)为什么等于15?运行的结果#include “stdio.h”#include “string.h”
void main(){char aa[10];printf(“%d”,strlen(aa));}
sizeof()和初不初始化,没有关系;strlen()和初始化有关。
char (*str)[20];/*str是一个数组指针,即指向数组的指针.*/char *str[20];/*str是一个指针数组,其元素为指针型数据.*/
25、long a=0×801010;a+5=?答:0×801010用二进制表示为:“01 00”,十进制的值为8392720,再加上5就是8392725
26、给定结构struct A{char t::4;char k:4;unsigned short i:8;};问sizeof(A) = ?给定结构struct A{char t:4; 4位char k:4; 4位unsigned short i:8; 8位 // 偏移2字节保证4字节对齐}; // 共8字节
27、下面的函数实现在一个数上加一个数,有什么错误?请改正。int add_n ( int n ){static int i = 100;i +=}当你第二次调用时得不到正确的结果,难道你写个函数就是为了调用一次?问题就出在 static上28、给出下面程序的答案#include#include #include #include #include #include typedef struct AA{int b1:5;int b2:2;}AA;void main(){AAchar cc[100];strcpy(cc,”abcdefghijklmnopqrstuvwxyz”);memcpy(&aa,cc,sizeof(AA));cout && aa.b1 &<ENDL; cout && aa.b2 &<ENDL; }答案是 -16和1首先sizeof(AA)的大小为4,b1和b2分别占5bit和2bit.经过strcpy和memcpy后,aa的4个字节所存放的值是:0,1,2,3的ASC码,即10,所以,最后一步:显示的是这4个字节的前5位,和之后的2位分别为:10000,和01因为int是有正负之分  所以:答案是-16和1
29、求函数返回值,输入x=9999;int func ( x ){int countx = 0;while ( x ){countx ++;x = x&(x-1);}}结果呢?知道了这是统计9999的二进制数值中有多少个1的函数,且有24+512+256+15
9×1024中含有1的个数为2;512中含有1的个数为1;256中含有1的个数为1;15中含有1的个数为4;故共有1的个数为8,结果为8。1000 - 1 = 0111,正好是原数取反。这就是原理。用这种方法来求1的个数是很效率很高的。不必去一个一个地移位。循环次数最少。
30、分析:struct bit{ int a:3;int b:2;int c:3;};int main(){char *c=(char*)&s;cout&<SIZEOF(BIT)<<ENDL; *c=0x99;cout && s.a &<ENDL <<s.b<<endl<<s.c<< int a=-1;printf("%x",a);return 0;}输出为什么是41-1-4ffffffff因为0x99在内存中表示为 100 11 001 , a = 001, b = 11, c = 100当c为有符合数时, c = 100, 最高1为表示c为负数,负数在计算机用补码表示,所以c = -4;同理b = -1;当c为有符合数时, c = 100,即 c = 4,同理 b = 3
31、下面这个程序执行后会有什么错误或者效果:#define MAX 255int main(){unsigned char A[MAX],i;//i被定义为unsigned charfor (i=0;i&=MAX;i++)A[i]=i;}解答:死循环加数组越界访问(C/C++不进行数组越界检查)MAX=255数组A的下标范围为:0..MAX-1,这是其一..其二.当i循环到255时,循环内执行:A[255]=255;这句本身没有问题..但是返回for (i=0;i&=MAX;i++)语句时,由于unsigned char的取值范围在(0..255),i++以后i又为0了..无限循环下去.
32、写出sizeof(struct name1)=,sizeof(struct name2)=的结果struct name1{}
struct name2{}
sizeof(struct name1)=8,sizeof(struct name2)=12在第二个结构中,为保证num按四个字节对齐,char后必须留出3字节的空间;同时为保证整个结构的自然对齐(这里是4字节对齐),在x后还要补齐2个字节,这样就是12字节。
33、struct s1{int i: 8;int j: 4;int a: 3;};
struct s2{int i: 8;int j: 4;int a:3;};
printf("sizeof(s1)= %d\n", sizeof(s1));printf("sizeof(s2)= %d\n", sizeof(s2));result: 16, 24第一个struct s1{int i: 8;int j: 4;int a: 3;};理论上是这样的,首先是i在相对0的位置,占8位一个字节,然后,j就在相对一个字节的位置,由于一个位置的字节数是4位的倍数,因此不用对齐,就放在那里了,然后是a,要在3位的倍数关系的位置上,因此要移一位,在15位的位置上放下,目前总共是18位,折算过来是2字节2位的样子,由于double是8字节的,因此要在相对0要是8个字节的位置上放下,因此从18位开始到8个字节之间的位置被忽略,直接放在8字节的位置了,因此,总共是16字节。第二个最后会对照是不是结构体内最大数据的倍数,不是的话,会补成是最大数据的倍数
34、在对齐为4的情况下struct BBB{long num;char *short ba[5];}*p;p=0x1000000;p+0x200=____;(Ulong)p+0x200=____;(char*)p+0x200=____;希望各位达人给出答案和原因,谢谢拉解答:假设在32位CPU上,sizeof(long) = 4 bytessizeof(char *) = 4 bytessizeof(short int) = sizeof(short) = 2 bytessizeof(char) = 1 bytes
由于是4字节对齐,sizeof(struct BBB) = sizeof(*p)= 4 + 4 + 2 + 1 + 1/*补齐*/ + 2*5 + 2/*补齐*/ = 24 bytes (经Dev-C++验证)
p=0x1000000;p+0x200=____;= 0x1000000 + 0x200*24
(Ulong)p+0x200=____;= 0x1000000 + 0x200
(char*)p+0x200=____;= 0x1000000 + 0x200*4
35、找错Void test1(){char string[10];char* str1="";strcpy(string, str1);// 溢出,应该包括一个存放'\0'的字符string[11]}
Void test2(){char string[10], str1[10];for(I=0; I&10;I++){str1[i] ='a';}strcpy(string, str1);// I,i没有声明。}
Void test3(char* str1){char string[10];if(strlen(str1)&=10)// 改成&10,字符溢出,将strlen改为sizeof也可以{strcpy(string, str1);}}
36、写出输出结果void g(int**);int main(){int line[10],i;int *p= //p是地址的地址for (i=0;i&10;i++){*p=i;g(&p);//数组对应的值加1}for(i=0;i&10;i++)printf("%d\n",line[i]);return 0;}
void g(int**p){(**p)++;(*p)++;// 无效}输出:12345678910
37、写出程序运行结果int sum(int a){auto int c=0;static int b=3;c+=1;b+=2;return(a+b+c);}
void main(){int I;int a=2;for(I=0;I&5;I++){printf("%d,", sum(a));}}// static会保存上次结果,记住这一点,剩下的自己写输出:8,10,12,14,16,
38、评价代码int func(int a){switch(a){case 1: 30;case 2: 20;case 3: 16;default: 0}}则func(1)=?// b定义后就没有赋值
int a[3];a[0]=0; a[1]=1; a[2]=2;int *p, *q;p=a;q=&a[2];则a[q-p]=a[2]解释:指针一次移动一个int但计数为1
39、请问一下程序将输出什么结果?char *RetMenory(void){char p[] = “hellow world”;}void Test(void){char *str = NULL;str = RetMemory();printf(str);}RetMenory执行完毕,p资源被回收,指向未知地址。返回地址,str的内容应是不可预测的, 打印的应该是str的地址
40、写出输出结果typedef struct{int a:2;int b:2;int c:1;}
t.a = 1;t.b = 3;t.c = 1;
printf("%d",t.a);printf("%d",t.b);printf("%d",t.c);
t.a为01,输出就是1t.b为11,输出就是-1t.c为1,输出也是-13个都是有符号数int嘛。这是位扩展问题01111编译器进行符号扩展
41、对下面程序进行分析void test2(){char string[10], str1[10];for(i=0; i&10; i++){str1[i] = 'a';}strcpy( string, str1 );}解答:如果面试者指出字符数组str1不能在数组内结束可以给3分;如果面试者指出strcpy(string, str1)调用使得从str1内存起复制到string内存起所复制的字节数具有不确定性可以给7分,在此基础上指出库函数strcpy工作方式的给10分;str1不能在数组内结束:因为str1的存储为:{a,a,a,a,a,a,a,a,a,a},没有'\0'(字符串结束符),所以不能结束strcpy( char *s1,char *s2)他的工作原理是,扫描s2指向的内存,逐个字符付到s1所指向的内存,直到碰到'\0',因为str1结尾没有'\0',所以具有不确定性,不知道他后面还会付什么东东。正确应如下void test2(){char string[10], str1[10];for(i=0; i&9; i++){str1[i] = 'a'+i; //把abcdefghi赋值给字符数组}str[i]='\0';//加上结束符strcpy( string, str1 );}
发表评论:
馆藏&17343
TA的推荐TA的最新馆藏[转]&[转]&[转]&1 #include&iostream& 2 using namespace 3 int main() 4 { 5
unsigned int a = 0xFFFFFFF7; 6
unsigned char i = (unsigned char)a; 7
char* b = (char*)&a; 8
printf("%08x, %08x\n", i, *b);10
}程序结果输出 :fffffff7,《宝典》中解释为1 unsigned int* p = &a; // p中的内容是的地址,即p指向a
2 char* b = (char*)p; // 此处的强制转换只是使b也指向a而已
3 // 这里是char类型的指针转换,而不是char类型的转换,影响的只是指针的寻址 《宝典》认为最终b的指向和&a一样,所以程序输出就是&a指向的:fffffff7,这个解释显然是不对的,如果我们把a的值改为0x,程序也会输出fffffff7,而按照《宝典》的说法,应该输出才对。正确的解释是怎样的呢?首先我们要有这么一个认识:在X86系列的机器中,数据的存储是“小端存储”,小端存储的意思就是,对于一个跨多个字节的数据,其低位存放在低地址单元,其高位放在高地址单元。比如一个 int 型的数据ox,假如存放在0xxxx这四个内存单元中,那么ox中放的是低位的ox78,而ox中放的是高位的0x12,以此类推。有了以上的认识,我们可以继续分析上面的程序为什么输出fffffff7:char* b = (char*)&a;这句话到底干了什么事呢?其实说来也简单,&a可以认为是个指向 unsigned int类型数据的指针对吧,(char *)&a则把&a强制转换成 char *类型的指针,并且这个时候发生了截断!截断后,指针b只指向oxf7这个数据(为什么b指向最低位的oxf7而不是最高位的oxff?想想上面刚刚讲过的"小端存储"吧,低地址单元存放低位数据,),又由于指针b是 char *型的,属于有符号数,所以有符号数0xf7在printf()的作用下输出fffffff7( 这个过程中其实发生了参数类型提升default argumentpromotions),因为我对C语言不是很了解,所以看这里,/%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0/clanguage/ctypetransfer/讲的比较清楚了。参考:http://blog.csdn.net/race604/article/details/6725475或者我们可以通过汇编代码更直观的看内部的情况:int main()
edi,[ebp-0E4h]
eax,0CCCCCCCCh
dword ptr es:[edi]
unsigned int a = 0xFFFFFF65;0132139E
dword ptr [a],0FFFFFFF7h
unsigned char i = (unsigned char)a;
al,byte ptr [a]
byte ptr [i],al
char* b = (char*)&a;013213AB
//取a的地址:0x0018FD70013213AE
dword ptr [b],eax
//指针b的值为:0x0018FD70,该位置放着0xF7;
printf("%08x, %08x\n", i, *b);
eax,dword ptr [b]
//把b的值,也就是0x0018FD70放到EAX中;
ecx,byte ptr [eax]
//这句话最关键,byte ptr [eax]就是把0xF7取出来,注意命令是byte ptr哦。然后movsx指令是按符号扩展,放到ecx中,按符号扩展其实就是将char扩展成int,然后printf中格式说明的‘x’则说明将这个int按16进制输出,也就是fffffff7了,而如果将‘x’变成‘d’,按整数输出,那么程序就会输出-9
//上一句的byte ptr 就反映了我们上面说的 char* b = (char*)&a 截取的问题
edx,byte ptr [i]
//注意因为i是unsigned char(无符号) ,所以按0扩展成unsigned int013213BE
offset string "%08x, %08x\n" (1325830h)
dword ptr [__imp__printf (13282B0h)]
@ILT+295(__RTC_CheckEsp) (132112Ch)
2930123456789101112131415161718192021222526272931123456789
阅读排行榜
评论排行榜

我要回帖

更多关于 sizeof char 的文章

 

随机推荐