一、关于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.