0
点赞
收藏
分享

微信扫一扫

《C语言深度解剖》20题手把手教学

夏天的枫_ 2022-04-29 阅读 40

目录

1.下面代码输出什么?为什么?

2.下面代码会有什么问题,为什么?

3.下面的代码i和j的值分别是什么?为什么?

4.下面代码里,假设在32位系统下,各sizeof计算的结果分别是多少?

5.下面代码的结果是多少?为什么?

6.下面的代码,哪些内容可以被改写,哪些不可以被改写

7.下面的两段代码有什么区别?什么时候需要使用代码(2)?

8.在32位的X86系统下,输出的值是多少?

9.0x01<<2+3的值为多少?为什么?

10.定义一个函数宏,求x的平方

11.下面的两段代码有什么区别?

12.写代码向内存0x12ff7c地址上存入一个整型数0x100

13.下面代码的值是多少?

14.假设p的值为0x100000,如下表达式的值分别为多少?

15.下面代码输出结果是多少?

16.下面的代码有什么问题,为什么?

17.下面代码有什么问题?为什么?

18.下面的代码输出结果是多少?

19.下面的代码有什么问题?

20.请写一个C函数,若当前系统是Big_endian,则返回0;若是Little_endian的,则返回1


1.下面代码输出什么?为什么?

void foo(void)
{
	unsigned int a = 6;
  //00000101 
  //00000000 00000000 00000000 00000101
	int b = -20;
 //10010100
 //00000000 00000000 00000000 00010100
	(a + b > 6) ? puts(">6") : puts("<=6");
 //00000000 0000000 00000000 00011001  25
}

2.下面代码会有什么问题,为什么?

void foo(void)
{
	char string[10], str1[10];
	int i;
	for (i = 0; i < 10; i++)
	{
		str1[i] = 'a';
	}
	strcpy(string, str1);
	printf("%s ", string);

}

3.下面的代码i和j的值分别是什么?为什么?

static int j;
int k = 0;

void fun1(void)
{
	static int i = 0;
	i++;
}

void fun2(void)
{
	j = 0;
	j++;
}

int main()
{
	for (k = 0; k < 10; k++)
	{
		fun1();
		fun2();
	}
	return 0;
}

4.下面代码里,假设在32位系统下,各sizeof计算的结果分别是多少?

//sizeof计算的是对象所占内存大小,单位是字节

int main()
{
	int* p = NULL;

	printf("%d\n", sizeof(p));//4  相当于sizeof(int*),求指针占用几个字节
	printf("%d\n", sizeof(*p));//4  相当于sizeof(int),求整型占几个字节

	return 0;
}
int main()
{
	int a[100];

	printf("%d\n", sizeof(a));//400  4*100=400
	printf("%d\n", sizeof(a[100]));//4 计算第101个元素大小,
	printf("%d\n", sizeof(&a));//4   &a取出的是整个数组的地址,数组的地址也是地址,是地址大小就是4个字节
	printf("%d\n", sizeof(&a[0]));//4  取出的是数组第一个元素的地址

	return 0;
}
	int b[100];

	void fun(int b[100])
	{
       sizeof(b);//4  C语言的bug,数组在有些条件下会隐式转变成指针
	}

5.下面代码的结果是多少?为什么?

int main()
{
	signed char a[1000];
	int i;
	for (i = 0; i < 1000; i++)
	{
		a[i] = -1 - i;
	}
	printf("%d", strlen(a));

	return 0;
}

strlen 库函数

求字符串长度,从给定的地址向后访问字符,统计\0之前出现的字符个数

6.下面的代码,哪些内容可以被改写,哪些不可以被改写

const int* p;//p可变,p指向的对象不能变
int const* p;//p可变,p指向的对象不可变
int* const p;//p不可变,p指向的对象可变
const int* const p;//指针p和p指向的对象都不可变

const是一个C语言的关键字

常属性(不能被修改)

7.下面的两段代码有什么区别?什么时候需要使用代码(2)?

//1
int i = 10;
int j = i;
int k = i;


//2
volatile int i = 10;
int j = i;
int k = i;

8.在32位的X86系统下,输出的值是多少?

#include <stdio.h>

int main()
{
    int a[5] = {1,2,3,4,5};
    int *ptr1 = (int *)(&a+1);
    int *ptr2 = (int *)((int)a+1);//注意这里被强制类型转换成为整型int
    
    printf("%x,%x",ptr1[-1],*ptr2);//5,2000000
    return 0;
}

 

9.0x01<<2+3的值为多少?为什么?

10.定义一个函数宏,求x的平方

#include <stdio.h>

#define (x) SQUARE(x) ((x)*(x))

int main()
{
    int a = 4;
    int s = SQUARE(a);
    printf("%d\n",s);
    return 0;
}

但是该语句有缺陷传入++a这样的内容函数宏会失效

11.下面的两段代码有什么区别?

//1
struct TestSTruct1
{
    char c1;
    short s;
    char c2;
    int i;
};

//2
struct TestStruct2
{
    char c1;
    char c2;
    short s;
    int i;
};

 

 

12.写代码向内存0x12ff7c地址上存入一个整型数0x100

//1
int *p = (int *)0x12ff7c;
*p = 0x100;
//注意:将地址0x12ff7c赋值给指针变量p的时候必须强制类型转换



//2
*(int *)0x12ff7c = 0x100;
//需要存入整型就要强制转换为整型变量

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是指数组首元素的地址,那么a+1就是往后走一个,就是数组第二个元素的地址,就是2

ptr中存的是5之后的地址,ptr-1就是往前走一个,4之后就是5

 

14.假设p的值为0x100000,如下表达式的值分别为多少?

struct Test
{
    int Num;
    char *pcName;
    short sDate;
    char cha[2];
    short sBa[4];
}*p;

 

十六进制由0-9,A-F组成与10进制的对应关系是:0-9对应0-9;A-F对应10-15;N进制的数可以用0~(N-1)的数表示,超过9的用字母A-F。

15.下面代码输出结果是多少?

#include <stdio.h>
int main(int argc,char * argv[])
{
    int a[3][2] = {(0,1),(2,3),(4,5)};
    int *p;
    p = a[0];
    printf("%d",p[0]);//1
}

16.下面的代码有什么问题,为什么?

void fun(char a[10])
{
    char c = a[3];
}

int main()
{
    char b[10] = "abcdefg";
    fun(b[10]);
    return 0;
}

代码问题:

 

17.下面代码有什么问题?为什么?

struct student
{
    char *name;
    int score;
}stu,*pstu;

int main()
{
    pstu = (struct student*)malloc(sizeof(struct student));//只为为指针变量ptsu分配了内存
    strcpy(pstu->name,"Jimy");
    pstu->score = 99;
    free(pstu);
    return 0;
}

所以正确的写法应该也使用malloc给name指针一块合法空间

struct student
{
    char *name;
    int score;
}stu,*pstu;

int main()
{
    pstu = (struct student*)malloc(sizeof(struct student));//只为为指针变量ptsu分配了内存
    pstu->name = (char*)malloc(20);
    
    strcpy(pstu->name,"Jimy");
    pstu->score = 99;
    
    //释放
    free(pstu->name);
    pstu->name = NULL;
    
    free(pstu);
    pstu = NULL;//每个malloc都要对应一个free
    
    return 0;
}

在为结构体指针分配内存时是从外向里,即先分配结构体的指针再分配成员指针

释放时则反过来,从里向外,先释放成员指针再释放结构体指针。

18.下面的代码输出结果是多少?

void fun(int i)
{
    if(i>0)
    {
        fun(i/2);
    }
    printf("%d\n",i);
}

int main()
{
    fun(10);
    return 0;
}

递归:函数自己调用自己

先调用完之后才开始打印,当走到i=0的时候,不再进入if中的函数,直接打印出0

fun函数走的流程的正常顺序,但打印是反过来

fun函数的计算结果:10 5 2 1 0

打印的结果是:0 1 2 5 10

递归流程图:

 

19.下面的代码有什么问题?

char c;
c = getchar();
if(EOF == c)
{
    ...
}

getchar函数是从键盘中读取字符,返回类型是int(返回的是字符的ASCII码值)错误返回-1

20.请写一个C函数,若当前系统是Big_endian,则返回0;若是Little_endian的,则返回1

题目意思:测试当前编译器是否是大端还是小端

//1.指针
int main()
{
	int a = 1;
	char* p = (char*)&a;
	if (*p == 1)
	{
		printf("小端\n");
	}
	else
	{
		printf("大端\n");
	}
	return 0;
}


//2.联合体
int check_sys()
{
	union check;
 {
     int i;
     char ch;
 }c;
 c.i = 1;
 
 return (c.ch == 1);
}

举报

相关推荐

0 条评论