1. 评价下面的代码片段:

    unsigned int zero = 0;
    unsigned int compzero = 0xFFFF;
    对于一个int型不是16位的处理器来说,上面的代码是不正确的,应编写为:
    unsigned int compzero = ~0;

    1. C 语言同意一些令人震惊的结构,下面的结构是合法的吗,如果是,它最终结果是什么?

    int a = 5,b = 7,c;
    c = a+++b;
    答:是;c = 12;

    1. 设有一下说明和定义:

    typedef union{long i; int k[5]; char c;} DATE;
    struct data { int cat; DATE cow; double dog; }too;
    DATE max;
    则语句 printf(“%d”,sizeof(struct date) + sizeof(max)); 的执行结果是?
    答:结果是:52(32位编辑器);20(16位编辑器);
    在32位编辑器下:DATE是一个union,变量公用空间,里面最大的变量类型是int[5],占用20个字节,所以它的大小是20;data是一个struct,每个变量分开占用空间,依次为int 4 + DATE 20 + double 8 = 32;
    结果是:20+32 = 52;
    在某些16位编辑器下, int 可能是2字节,那么结果是 int 2 + DATE 10 + double 8 = 20

    4.写出下列代码的输出内容

    1. #include <iostream>
    2. int inc(int a)
    3. {
    4. return(++a);
    5. }
    6. int multi(int*a, int*b, int*c)
    7. {
    8. return(*c = *a**b);
    9. }
    10. typedef int(FUNC1)(int in);
    11. typedef int(FUNC2)(int*, int*, int*);
    12. void show(FUNC2 fun, int arg1, int*arg2)
    13. {
    14. int (*p)(int) = &inc;
    15. int temp = p(arg1);
    16. fun(&temp, &arg1, arg2);
    17. printf("%d\n", *arg2);
    18. }
    19. int main()
    20. {
    21. int a;
    22. show(multi, 10, &a);
    23. return 0;
    24. }

    image.png
    5.请找出下面代码中的所有错误
    说明:以下代码是把一个字符串倒序,如“abcd”倒序后变为“dcba”

    1. #include "string.h"
    2. int main()
    3. {
    4. char *src = "hello,world";
    5. char *dest = NULL;
    6. int len = strlen(src);
    7. dest = (char*)malloc(len);
    8. char* d = dest;
    9. char* s = src[len];
    10. while (len - != 0)
    11. d++ = s - ;
    12. printf("%s", dest);
    13. return 0;
    14. }

    修改后:

    1. #include "string.h"
    2. #include <stdlib.h>
    3. #include <stdio.h>
    4. int main()
    5. {
    6. char str[] = "hello,world";
    7. int len = strlen(str);
    8. char t;
    9. for (int i = 0;i < len/2; i++)
    10. {
    11. t = str[i];
    12. str[i] = str[len - i - 1];
    13. str[len - i - 1] = t;
    14. }
    15. printf("%s", str);
    16. return 0;
    17. }

    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.下面的程序输出什么?

    1. #include <iostream>
    2. using namespace std;
    3. int main()
    4. {
    5. char str1[] = "abc";
    6. char str2[] = "abc";
    7. const char str3[] = "abc";
    8. const char str4[] = "abc";
    9. const char *str5 = "abc";
    10. const char *str6 = "abc";
    11. char *str7 = "abc";
    12. char *str8 = "abc";
    13. cout << (str1 == str2) << endl; //false
    14. cout << (str3 == str4) << endl; //false
    15. cout << (str5 == str6) << endl; //true
    16. cout << (str7 == str8) << endl; //true
    17. }

    image.png
    解答:str1,str2,str3,str4是数组变量,它们有各自的内存空间;
    而 str5,str6,str7,str8是指针,它们指向相同的常量区域。
    10.以下代码中的两个sizeof用法有问题吗?

    1. #include <iostream>
    2. using namespace std;
    3. void uppercase(char str[]) //将str中的小写字母转换成大写字母
    4. {
    5. for (size_t i = 0; i < 32; i++)
    6. if ('a' <= str[i] && str[i] <= 'z')
    7. str[i] -= ('a' - 'A');
    8. }
    9. int main()
    10. {
    11. char str[] = "aBcDe";
    12. cout << "str字符长度为:" << sizeof(str)/sizeof(str[0]) << endl;
    13. uppercase(str);
    14. cout << str << endl;
    15. }

    image.png
    答:函数内的 sizeof 有问题。根据语法,sizeof 如用于数组,只能测出静态数组的大小,无法检测动态分配的或外部数组大小。
    sizeof(str)是测出静态定义数组的大小,后面还有\n,所以大小为6;
    sizeof(str[0]),str[0]是指向字符串的指针,所以sizeof(str[0]) == sizeof(char) ==1 ;

    11.写出输出结果

    1. int main()
    2. {
    3. int a[5] = { 1,2,3,4,5 };
    4. int *ptr = (int *)(&a + 1 );
    5. printf("%d,%d\n", *(a + 1), *(ptr - 1 ));
    6. printf("%p\n", (ptr - 1));
    7. }

    image.png
    &a是整个数组的首地址,而a是数组首元素的首地址。&a是数组指针,其类型为int()[5];而指针+1要根据指针类型加上一定的值,不同类型的指针+1之后增加的大小不同,a是长度为5的int数组指针,所以要加5sizeof(int),
    &a+1就是相当于整个数组指针加1,执行&a+1后,ptr的偏移量相当于 a + sizeof(int) 5 1 .
    &a+2就是相当于整个数组指针加2,执行&a+2后,ptr的偏移量相当于 a + sizeof(int) 5 2 .
    所以p实际是a[5],但是p与(&a + 1)类型是不一样的,这点非常重要,所以p - 1只会减去sizeof(int);a,&a的地址是一样的,但意思就不一样了,a是数组首地址,也就是a[0]的地址,&a是对象(数组)首地址,a+1是数组下一元素的地址,即a[1],&a + 1是下一个对象的地址,即a[5]。所以(ptr - 1)是a[4]的值,而(ptr - 1)是a[4]的地址值。

    12.(void )ptr 和 ((void))ptr 的结果是否相同?
    答:其中 ptr 为同一个指针,(void )ptr 和 ((void
    ))ptr 值是相同的。

    13.下面的语句会出现什么结果?
    char szstr[10];
    strcpy(szstr,”0123456789″);
    答:长度不一样,会造成非法的 OS,应该改为 char szstr[11];

    14.函数既然不会被其它函数调用,为什么要返回1?

    1. int main()
    2. {
    3. int x=3;
    4. printf(“%d”,x);
    5. return 1;
    6. }

    答:mian 中,c 标准认为0表示成功,非0表示错误。具体的值是某中具体出错信息

    15.对绝对地址0×100000赋值且想让程序跳转到绝对地址是0×100000去执行
    (unsigned int)0×100000 = 1234;
    首先要将0×100000强制转换成函数指针,即:
    (void (
    )())0×100000
    然后再调用它:
    ((void ()())0×100000)();
    用 typedef 可以看得更直观些:
    typedef void()() voidFuncPtr;
    ((voidFuncPtr)0×100000)();

    16.、输出多少?并分析过程

    1. unsigned short A = 10;
    2. printf(“~A = %u\n”, ~A);
    3. char c=128;
    4. printf(“c=%d\n”,c);

    image.png
    解答:2^32=4294967296,
    A=10,为无符号型,转换为二进制为0000 0000 0000 0000 0000 0000 0000 1010
    所以~A的二进制位1111 1111 1111 1111 1111 1111 1111 0101即0xFFFFFFF5,如果转换为符号整型的话则为-11,因为输出的是无符号整型,无符号整型的范围为0~4294967295,而0xFFFFFFF5转换为无符号十进制整型为4294967285
    第二题,发生溢出,因为有符号字符型其范围为-128~127
    127用二进制表示为:0111 1111,128表示为1000 0000,这里发生溢出,因为第一位为1,为符号位,表示负数,即-128

    17.找错**

    1. Void test1()
    2. {
    3. char string[10];
    4. char* str1="0123456789";
    5. strcpy(string, str1);// 溢出,应该包括一个存放'\0'的字符 string[11]
    6. }
    7. Void test2()
    8. {
    9. char string[10], str1[10];
    10. for(I=0; I<10;I++)
    11. {
    12. str1[i] ='a';
    13. }
    14. strcpy(string, str1);// I,i 没有声明。
    15. }
    16. Void test3(char* str1)
    17. {
    18. char string[10];
    19. if(strlen(str1)<=10)// 改成<10,字符溢出,将 strlen 改为 sizeof 也可以
    20. {
    21. strcpy(string, str1);
    22. }
    23. }