C语言_刷题

一、关于printf函数

1.printf函数是有返回值的,printf返回输出字符的个数。

#include<stdio.h>
int main()
{
	int i = 43;
	printf("%d\n", printf("%d",printf("%d",i)));//printf函数返回值为输出字符的个数//4321
	return 0;
}

2.下面这题来自牛客网,考察知识点为函数参数传递方式,但是因为用到了printf函数,就放到这里一并说。

求下列程序的输出结果

#include<stdio.h>

int f(int a, int b, int c)
{
	return 0;
}

int main()
{
	return f(printf("a"), printf("b"), printf("c"));
	return 0;
}
答案给的是abc,但是我在VS中运行出来是cba,看了一下其他网友的解释。有说函数的参数是通过栈传递的,因此参数从右往左入栈,输出结果是cba。有说函数是通过寄存器传递的,输出结果是abc。这样的题目真没劲。知道点意思就可以了。

二、智力题

1.寝室有6个同学打dota,分为对立的两方,一方是天灾军团,一方是近卫军团。现请你设置赛程以及每场的对阵(每方最少1人、最多5人),请问至少得进行多少场比赛,才能使得赛程结束后每位同学都和其他同学做过对手(3)

解答:这题当时做对了,是试出来的。看了一下网友的解答,感觉很不错。

用0,1来表示每个同学位于哪一方,0表示天灾军团,1表示近卫军团。000表示这个同学3次都处于天灾军团,001表示两次处于天灾,一次处于近卫。000,001,010,011,100,101,110,111,八个二进制最少有一个数不同,表示处于对抗。这题相当于几位二进制,可以表示5个不同的数。

2.从一副标准扑克牌中抽牌,抽到黑色牌就继续抽(不取出),直至抽到红色牌,则停止。按照概率算,平均下来每次能抽到多少张黑牌?(也就是三国杀中甄姬的洛神技能,得到牌数的期望值)

1
1.2
0.8
0.9

解答:做的时候,2了,没有看到抽到的黑色牌继续放回牌堆。其实这题很简单,只不过我也玩三国杀,觉得很有意思就放在这里了。

E=1/4+2/8+3/16+4/32+...+n/(2^n+1)

=1

三、C语言中结构体占用内存问题

转载:https://www.cnblogs.com/kl2blog/p/6908048.html

之前对结构体占用内存一直很混乱,到底是按照哪个变量类型计算内存?还是怎么计算?下面先看一个例子:

struct str1
{
	char a;
	int b;
	float c;
	double d;
};

str1这个结构体占用的内存是多少呢?如果用变量类型直接想加,得到的结果是17,但显然不是这样的。这个程序运行的正确结果是24.为什么呢?

  因为为了CPU能够快速访问,提高访问效率,变量的起始地址应该具有某些特性,这就是所谓的“对齐”。比如4字节的int型变量,那它的起始地址就应该在4字节的边界上,即起始地址可以被4整除。

  内存对齐的规则很简单:

  1.起始地址为该变量类型所占内存的整数倍,若不足则不足部分用数据填充至所占内存的整数倍。

  2.该结构体所占总内存为结构体成员变量中最大数据类型的整数倍。

  接下来我们分析上面的例子:

  char型变量占一个字节,所以它的起始地址为0,而int类型占4个字节,它的起始地址应该是4(的整数倍),那么内存地址1、2、3就需要被填充。同样,float占用4个字节,而结构体中a,b两个成员变量占了0~7内存地址,c的地址从8开始,符合规则一,占用内存地址为8~11。double类型占8个字节,所以d的起始地址就应该从16开始,那么12、13、14、15内存地址就需要被填充。d从16地址开始,占用8个字节。整个结构体占用字节数为24,符合规则二。内存分配如图:红色区域为填充部分



下面再举一个例子,进一步说明:

struct str2
    {
        double a;
        int b;
        char c;
        double d;
    };

str2这个结构体占用的内存空间是多少呢?是24!怎么分析呢?

首先double类型的a占用内存地址为0~7,int类型的b起始地址为8,符合规则一,占用地址为8~11,char类型的c占一个字节,地址为12.那么double类型的d,起始地址为13吗?显然不是,满足规则一的地址是16,所以d起始地址为16,占用16~23。结构体总共24个字节,满足规则二。如果这个结构体最后再加一个成员变量 char e,那这个结构体占用的内存是多少?char类型的e起始地址为24,占用地址为24,但是结构体一种有25个字节,就不满足规则二了,怎么办呢?为了满足规则二,我们将25~31进行填充,因此整个结构体占用32个字节。

下面再看一个牛客网上例子:

以下代码打印的结果是(假设运行在 64 位计算机上):

struct st_t {
    int status;
    short *pdata;
    char errstr[32];
};
st_t st[16];
char *p=(char *)(st[2].esstr+32);
printf(“%d”,(p-(char *)(st)));

status占4个字节,字节补齐4个字节,

64位系统,指针占8个字节,pdata占8个字节

errster占32个字节

整个结构体占48个字节。

最后答案为144.




猜你喜欢

转载自blog.csdn.net/hhhhhyyyyy8/article/details/79965850