题目1 (&=的含义)
我们先设x=1,x-1=-0,1&0
我们再设x=2,x-1=1,2&1
我们需要关注的是原来的x和现在的x发生了什么改变
得出的结论是:结果是丢弃二进制最右边的1
所以这个函数的作用就是统计二进制数x中1的个数
题目2(指针++)
前置++,先+
后置++,先不+
参数入栈:绝大多数情况下是从右向左入栈(不确定的)。在不同的模式下,不同的编译器下,结果是不确定的。
题目3(强制转换)
%x是16进制输出,08就是输出8个位,
char是一个字节,取(小端)
0xF7
无符号扩充:左边补充0
有符号数扩充:左边补符号位
题目4(输出)
//255:二进制 8个1; -1的二进制全1
//char:-128~127 ;unsigned char:0~255
int main()
{
char a = 255; //1111 1111 ->有符号则为负数 ->0000 0001-> -1
unsigned char b = 255;//255
char c = -1;//-1
unsigned char d = -1;//1111 1111->无符号 255
int e = a;
int f = b;
int g = c;
int h = d;
printf("%d,%d,%d,%d\n",e,f,g,h);//-1,255,-1,255
//printf("%08x,%08x\n",-1>>1,-1<<1);//11111111 11111111 11111111 1111 1111
return 0;
}
题目5
只要是运算,我们都是转成整型起!!!
答案是250 因为b是一个字节,取最后8位
题目6(指针的大小)
void Fun(int arr[10])//数组放在参数列表中已经退化为指针
{
printf("%d\n",sizeof(arr));
}
//指针的大小
int main()
{
printf("%d\n",sizeof(char *));
printf("%d\n",sizeof(int *));
printf("%d\n",sizeof(long *));
printf("%d\n",sizeof(unsigned long long *));
printf("%d\n",sizeof(double *));
printf("%d\n",sizeof(char *****));
printf("%d\n",sizeof(void *));
int arr[10];
Fun(arr);
return 0;
}
数组放在参数列表中已经退化为指针
下面换成64位平台
题目7(结构体大小)
在C++中(包罗万象)
在C语言中(不兼容,不允许离谱的)
空类的1是占位用的而已
题目8(优先级)
int*g()返回指针的函数
int(*h) ()返回函数的指针
题目9(指针和引用)
指针
int main1()//指针
{
int a = 10;
int b;
int *p;
p = &a;
int *q = &b;
q = p;
int **pp = &p;
//pp = &&a;//error
return 0;
}
引用
int main()//引用:外号
{
int a = 10;
int b = 20;
int &c = a;//c就是a
//变量可以有多个别名吗? 可以
int &d = a;//ok
//引用可以有引用吗? 可以
int &e = d;//ok
//int &f;//error,不能出现空引用
return 0;
}
题目10(有关内存)
左图:GetMemory不可以获取str内存,程序崩溃,因为内存带不出来,要传二级指针解引用。还是空指针。程序崩溃。
右图:不能接收,因为不能返回局部变量的地址。局部变量的生命周期只在所在的函数里面有效。打印出随机值。
左图:传二级指针内部解引用。正常输出。但是有内存泄漏。
右图:free之后,str是野指针,没有置空啊,判断不了。非法访问内存。
题目11(生命周期)
题目12(指针)
最后一行崩溃,解引用到地址1的空间去。
解1次引用是一行,解2次引用是第一个格子。
题目13(按要求写出)
指针和数组的算术运算
数组名arr表示整数数组只有如下情况:
1.在定义数组的同一个函数中,求sizeof(arr),表示整个数组的大小
2.在定义数组的同一个函数中,&arr+1,表示加真个数组的大小
int main()
{
int arr[5] = {1,2,3,4,5};
int *p = (int *)(&arr+1);
printf("%d\n",p[-1]);//5
return 0;
}