c语言复习第二部分

421 阅读7分钟

26.求结构体字节数

struct A 
{
  char t:4;
  char k:4;
  unsigned short i:8;
  unsigned long m;
};共8字节 1+1+4+2(偏移两个字节保证4字节对齐)

28 得出结果

#include<iostream.h>
#include <string.h>
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
typedef struct AA
{
int b1:5;
int b2:2;
}AA;
void main()
{
AA aa;
char cc[100];
strcpy(cc,"0123456789abcdefghijklmnopqrstuvwxyz");
memcpy(&aa,cc,sizeof(AA));
cout << aa.b1 <<endl;
cout << aa.b2 <<endl;
}

结果:

一个字节8位表示
首先 sizeof(AA)的大小为 4,b1 和 b2 分别占 5bit 和 2bit.
经过 strcpymemcpy 后,aa 的 4 个字节所存放的值是:
0,1,2,3 的 ASC 码,即 00110000,00110001,00110010,00110011
所以,最后一步:显示的是这4个字节的前5位,和之后的2位
分别为: 10000,和 01
因为 int 是有正负之分 所以:答案是-16 和1

29.求1的个数

int func ( x )
{
 int countx = 0;
 while ( x )
{
 countx ++;
 x = x&(x-1);
}return countx;
}
结果呢?
知道了这是统计 9999 的二进制数值中有多少个 1 的函数,且有
99999×102451225615
9×1024 中含有 1 的个数为 2512 中含有 1 的个数为 1256 中含有 1 的个数为 115 中含有 1 的个数为 4故共有 1 的个数为 8,结果为 81000 - 1 = 0111,正好是原数取反。这就是原理。
用这种方法来求 1 的个数是很效率很高的。
不必去一个一个地移位。循环次数最少。

30.分析

struct bit
{ int a:3;
int b:2;
int c:3;
};
int main()
{
bit s;
char *c=(char*)&s;
cout<<sizeof(bit)<<endl;
*c=0x99;
cout << s.a <<endl <<s.b<<endl<<s.c<<endl;
int a=-1;
printf("%x",a);
return 0;
}

输出结果:

4 1 -
1
-4
ffffffff
因为 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

-1的补码为11111111 详细过程 1.通常把一个数的最高为定义为符号位,用“0”表示正,用“1”表示负。 因为【-1】为负,所以【-1】的原码=10000001 2.反码:对于负数,数符位为1,数符位不变,将数值位诸位取反为反码。 【-1】的反码=11111110 3.补码:对于负数,数符位为1,数符位不变,将反码+1=补码。 【-1】的补码=11111111 扩展资料 计算机中的符号数有三种...

31.程序运行错误

#define MAX 255
int main()
{
unsigned char A[MAX],i;//i 被定义为 unsigned char
for (i=0;i<=MAX;i++)
A[i]=i;}

错误地方:数组A的范围为0..MAX-1,i的范围为(0~255),i++一行又变为0了,无线循环

32.写出结果

struct name1{
char str;
short x;
int num;
}
struct name2{
char str;
int num;
short x;
}
sizeof(struct name1)=8 (1+2+4)=8
sizeof(struct name2)=12 4+4+4(最大参数的倍数)

33 struct s1

struct s1
{
int i: 8;
int j: 4;
int a: 3;
double b;
};
struct s2
{
int i: 8;
int j: 4;
double b;
int a:3;
};
printf("sizeof(s1)= %d\n", sizeof(s1));
printf("sizeof(s2)= %d\n", sizeof(s2));

result: 16, 24

34.对齐为4的条件下

struct BBB
{
  long num;
  char *name;
  short int data;
  char ha;
  short ba[5];
}*p;
  p=0x1000000;
  p+0x200=____;
  (Ulong)p+0x200=____;
(  25222char*)p+0x200=____;

p=0x1000000;
p+0x200=____;
= 0x1000000 + 0x200*24
(Ulong)p+0x200=____;
= 0x1000000 + 0x200
(char*)p+0x200=____;
= 0x1000000 + 0x200*4

35.sizeof与strlen

strlen是用来计算字符串的长度,遇到第一个NULL('\0')为止,不包括‘\0’。

sizeof是用来计算变量或者对象、类型所占字节的多少。

char str[20]="0123456789";
int   a=strlen(str); /*a=10;strlen 计算字符串的长度,以\0'为字符串结束标记。
int   b=sizeof(str); /*b=20;sizeof 计算的则是分配的数组str[20] 所占的内存空间的大小,不受里面存储的内容影响
============================================================================================

char *str1="absde";
char str2[]="absde";
char str3[8]={'a',};
char ss[] = "0123456789";

输出:

sizeof(str1)=4
sizeof(str2)=6;
sizeof(str3)=8;
sizeof(ss)=11

36 写出输出结果?

void g(int**);
int main()
{
  int line[10],i;
  int *p=line; //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)++;// 无效
}

38 评价代码

int func(int a)
{
int b;
switch(a)
{
 case 1: 30;
 case 2: 20;
 case 3: 16;
default: 0
}
return b;
} 则
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‛;
return p;
}
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;
}test;
test t;
t.a = 1;
t.b = 3;
t.c = 1;
printf("%d",t.a);
printf("%d",t.b);
printf("%d",t.c);

t.a 为 01,输出就是 1
t.b 为 11,输出就是-1
t.c 为 1,输出也是-1
3 个都是有符号数 int 嘛。
这是位扩展问题
01
11
1
编译器进行符号扩展

41 对下面程序进行分析

void test2()
{
char string[10], str1[10];
int i;
for(i=0; i<10; i++)
{
str1[i] = 'a';
}strcpy( string, str1 );
}

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];
int i;
for(i=0; i<9; i++)
{
str1[i] = 'a'+i; //把 abcdefghi 赋值给字符数组
}
str[i]='\0';//加上结束符
strcpy( string, str1 );
}

42分析

int arr[] = {6,7,8,9,10};
int *ptr = arr;
*(ptr++)+=123;
printf(‚ %d %d ‛, *ptr, *(++ptr));
输出: 8 8
过程:对于*(ptr++)+=123;先做加法 6+123,然后++,指针指向 7;对于 printf(‚ %d %d ‛, *ptr, *(++ptr));
从后往前执行,指针先++,指向 8,然后输出 8,紧接着再输出 8

43分析

#include <stdio.h>
void foo(int m, int n)
{
printf("m=%d, n=%d\n", m, n);
}
int main(){
int b = 3;
foo(b+=3, ++b);
printf("b=%d\n", b);
return 0;
}
输出: m=7,n=4,b=7(VC6.0)
这种方式和编译器中得函数调用关系相关即先后入栈顺序。不过不同
编译器得处理不同。也是因为 C 标准中对这种方式说明为未定义,所以
各个编译器厂商都有自己得理解,所以最后产生得结果完全不同。
因为这样,所以遇见这种函数,我们首先要考虑我们得编译器会如何处理
这样得函数,其次看函数得调用方式,不同得调用方式,可能产生不同得
结果。最后是看编译器优化。

44找错误

#include string.h
main(void)
{ char *src="hello,world";
char *dest=NULL;
dest=(char *)malloc(strlen(src));
int len=strlen(str);
char *d=dest;
char *s=src[len];
while(len--!=0)
d++=s--;
printf("%s",dest);
}
找出错误!!
#include "string.h"
#include "stdio.h"
#include "malloc.h"
main(void)
{
char *src="hello,world";
char *dest=NULL;
dest=(char *)malloc(sizeof(char)*(strlen(src)+1));
int len=strlen(src);
char *d=dest;
char *s=src+len-1;
while(len--!=0)
*d++=*s--;
*d='\0';
printf("%s",dest);
}

本文使用 mdnice 排版