目录
易错点
1:index=index++
#include <stdio.h>
int main(){
int index=1;
for(int i=0;i<10;i++){
index=index++;
}
printf("%d\n",index);
return 0;
}
index==1;因为index=index++的过程是
temp=index;index=index+1;index=temp;
所以index=index++执行结束后,index==1
index=++index的过程是
index=index+1;temp=index;index=temp;
所以index=++index执行结束后,index==2
2:
*p++ 和 *(p++) 等价
3:判断指针数组和数组指针
int *pa[5] :指针数组,数组大小为5,数组内的元素为int类型指针
int(*pa)[5]: 数组指针,指针,指向一个数组,数组存放5个int类型的元素
4:函数指针和指针函数
int (*p)(int):函数指针,一个指针指向返回值为int,函数参数为int的函数
int * p(int): 指针函数,p为一个函数,参数为一个int类型的数,返回值为一个int类型的指针
5:\ddd
\ddd(d为任意数字)在转义字符中表示三位八进制,因为八进制中的数只有0-7,因此\018不能表示三位八进制,所以取\01。而\t在转义字符中表示制表符,所以\t算一次。然后a一次,\01一次,8一次,b一次,c一次。所以是6次。
6:
*(a + 1):直接用数组名a代表数组首元素的地址,+1再解引用是数组第二个元素的内容
(&a + 1):对整个数组取地址代表数组的地址,对数组的地址+1,可以将整个数组看成一个数据类型,+1则地址往后便宜该数据类型的大小,则ptr指向5的后一位,由于ptr为int类型的指针,-1往前偏移4个字节(即偏移一位),指向5,再解引用结果为5
相同类型的题:
1 2 3
4 5 6
首先把二维数组看成一个一维数组,其中每一行为一个元素,即
123 456 (123和456各为一的整体)
则对 *(*(A+1)+1)进行刨析
A为(一维数组)首元素地址,即元素 123 的地址。所以(A+1)为元素 456 的地址
*(A+1)解引用为数组 4 5 6
*(A+1)为数组名,也是首元素地址,而 *(A+1)+1 为元素 5 的地址
解引用 *(*(A+1)+1)为 5
7:
这个题目考虑两个点…1、位域,x,y,z分别是3bit(位),4bit,5bit,但首先需要注意,8bit对齐一个字节(Byte),所以x,y属于int的第一个字节,z是int的第二个字节,该int还有两个字节没有使用。2、在没有说明的情况下,结构体中的字节对齐按最大长度的变量的字节数对齐,也就是这里的double,8字节对齐,一共16字节。
8:
1Byte|1Byte|1Byte|1Byte|
| short | char | char |
| long |
| char | 填充| 填充| 填充|
| int |
共计4 * 4 = 16 Byte,选A
原因:
1. 在32位机中,
char 1字节
short 2字节
int 4字节
long 4字节
2. 数据在计算机中按“边界对齐”方式存储,支持按字寻址、按半字寻址、按字寻址,
半字地址必为2的整数倍,字地址必为4的整数倍,
所以半字长和一个字长的数据在存储时,就算前面有“空位”,为了保持地址的“一致性”,机器会对空位进行填充。
3. 比如:
|1Byte|1Byte|1Byte|1Byte|
| char | char | char | 填充 |
| short | short |
| short | 填充 |
| int |
| long |
9:
就近原则,int const *p = &n;修饰的是*p,即指针类型,能修改指针指向的地址,但是不能修改指针指向地址的值。
存放p的地址假设是0Xff01; p = &n, *p = 10;
p++ 后指针指向的地址 + 1,(由于是int类型,实际是加4) p = 0Xff05;
10
10
首先_x5是静态变量可以不用管它,其次是要考虑字节对齐的问题。对于结构体中没有含有结构体变量的情况,有两条原则:1)结构体变量中成员的偏移量必须是成员大小的整数倍;2)结构体的最终大小必须是结构体最大简单类型的整数倍。x1的偏移量是0,长度是8,符合;x2的偏移量是8,长度是1,符合;x3的偏移量是9,长度是4,不符合,需要在x2之后填充3字节使得x3的偏移量达到12;x4的偏移量是16,长度是2,符合;此时总长度为(8)+(1+3)+(4)+(2)=18,而最大简单类型为long long长度为8,因此需要在x4之后再填充6字节,使得总长度达到24可被8整除。因此sizeof(xx)的结果为24。
11
'a'-1
和'a'-'1'
是两个不同的表达式,具有不同的含义。
'a'-1
表示将字符'a'的ASCII码值减去1,即96,它对应于字符'`'。
而'a'-'1'
表示将字符'a'的ASCII码值减去字符'1'的ASCII码值,即'a'的ASCII码值97减去'1'的ASCII码值49,结果为46,它对应于字符'.'。
因此,这两个表达式的结果不同。
'a'+'2'-'0'
是一个字符运算表达式,按照 ASCII 码进行计算。
首先,字符'a'的 ASCII 码值为97,字符'2'的 ASCII 码值为50,字符'0'的 ASCII 码值为48。
所以,'a'+'2'-'0'
可以转化为 (97 + 50 - 48)
,结果为99,对应于字符'c'。
因此,'a'+'2'-'0'
的结果是字符'c'
字符数字减去‘0’,相当于变成整数
11
逗号表达式取尾
当一个语句是由多个被逗号运算符隔开的表达式组成时,此语句的值为最后一个表达式的值。
逗号表达式值为逗号右边的值,先算括号里的x=20,括号内的逗号表达式的值为100,但整个表达式的值是20+25=45
12
一个数与这个数减1的结果进行'&'按位与运算,结果为:这个数二进制数最右边的1变为0;
举例说明如下:
X=5;
5&(5-1) = 010 1 & (0100) = 010 0
经过上述计算,5的二进制最右边的1变为了0,由此可知,题目中count是用以统计x的二进制中1的个数的
9999的二进制表示为:10011100001111 共有8个1,显然,答案为A。
13
fgetc函数——读1个成功,带回所读的字符,失败返回文件结束标志EOF(-1);
fputc函数——输出1个成果,返回值就是输出的字符,失败返回EOF;
fgets函数——读指定长度的大小成功,返回地址str,失败返回NULL;
fputs函数——输出一个字符串成果,返回0,失败返回非0;
14
2. 多个-alloc的比较:
alloc:唯一在栈上申请内存的,无需释放;
malloc:在堆上申请内存,最常用;
calloc:malloc+初始化为0;
realloc:将原本申请的内存区域扩容,参数size大小即为扩容后大小,因此此函数要求size大小必须大于ptr内存大小。
15
%md 以宽度m输出整型数,不足m时,左补空格,如果超出,则按实际输出
%0md 以宽度m输出整型数,不足m时,左补零,如果超出,则按实际输出
%m.nf 以宽度m输出实型小数,小数位为n位
需要注意的是:当指定数据宽度小于数据的实际宽度时,对整数,按该数的实际数据宽度输出,对浮点数,相应小数位的数四舍五入。
16
\b
代表退格符,相当于删除前一个字符。\r
代表回车符,将光标移至行首。\'
表示单引号字符。\\
表示反斜杠字符。\n
代表换行符,将光标移行的行首。
17
无符号号整数和有符号整数相加,有符号整数转化为无符号整数,signed int b 变成了一个很大的数,所以a + b是>0的,选A
18
该题目中的表达式应该看为a =( (5) ? 0 : 1),虽然5不是一个判断表达式,但是也符合非0,构成判断为真,所以a=0
持续更新。。。