第一题
以下代码的输出结果
int main() {
int arr[] = {1, 2, 3, 4, 5};
short *p = (short *) arr;
for (int i = 0; i < 4; i++) {
*(p + i) = 0;
}
for (int i = 0; i < 5; i++) {
printf("%d ", arr[i]);
}
return 0;
}
解析:这里的重难点就是short *p = (short *) arr;因为short只有2字节,所以他每次只能操作两个字节的地址。这样的话第一个for循环就可以将两个int的内容变为0。输出的时候就前两个值为0后面的不变。
第二题
以下代码的输出结果
int main() {
int a = 0x11223344;
char *pc = (char*)&a;
*pc = 0;
printf("%x \n",a);//十六进制的输出形式
return 0;
}
解析:0x11223344在内存中存储内容是44332211,char* 每次只能操作一个字节的内容。所以44->0,输出的时候再逆序输出就是11223300。
第三题
以下代码的输出结果
int i;
int main() {
i--;
if(i> sizeof(i)){
printf("> \n");
} else{
printf("<\n");
}
return 0;
}
解析:全局变量没有初始化的时候默认是0;
sizeof()计算变量/变量所占内存的大小。大小>=0,是无符号数。
当无符号数与正常数字进行比较时先将正常数转化为无符号数。-1转化为无符号数是一个很大的值。所以结果就是 “>”。
第四题
以下代码的输出结果
int main() {
int a=0,b=0,c=0;
a = 5;
c = ++a;
b = ++c,c++,++a,a++;
b += a++ + c;
printf("a = %d b = %d c = %d\n",a,b,c);
return 0;
}
解析:"=“的优先级高于”,",1. a = 5;c = 6;c = 7;b = 7;c = 8;a = 6;a = 7; “+“的优先级高于”=” 2. 计算b += a++ + c; -> a = 8, c = 8 b = 7->>b = 23
第五题
统计一个数二级制中1的个数
写一个函数返回参数二级制中1的个数。
方法一:
int Count_1(unsigned int n) {
int count = 0;
while (n) {
if (n % 2 == 1) {
count++;
}
n = n / 2;
}
return count;
}
int main() {
int n = 0;
scanf("%d", &n);
//函数 a的二级制补码中的1的个数
int count = Count_1(n);
printf("count = %d", count);
return 0;
}
解析:计算二进制为1的位数时每次对2取余就是获取最后一位的数字。除以二就是将这个数最后一位删去。对于负数只需要将其按照无符号数来对待就可以了。
方法二:
int Count_1( int n) {
int count = 0;
for(int i = 0;i<32;i++){
if(((n>>i)&1)==1){
count++;
}
}
return count;
}
解析:使用移位的方式,和位计算且的原理,只要和1与运算的结果为一说明当前数的最后一位为1,每次多移一位进行运算。出现1count+1。32次运算,结果就是答案。
方法三:
int Count_1( int n) {
int count = 0;
while(n){
n = n&(n-1);
count++;
}
return count;
}
解析:一个数的二进制可以通过(n)&(n-1)将n最右边的1消除掉。这样计算时间复杂度是最低的。
第六题
题目:求二进制中不同位的个数
内容: 两个int(32位)整数m和n的二进制表达式中,有多少个位(bit)不同。
int Count_1( int n) {
int count = 0;
while(n){
n = n&(n-1);
count++;
}
return count;
}
int GetDiff(int m,int n){
int count=0;
count = Count_1(m^n);
return count;
}
int main(){
int m=0,n=0;
scanf("%d %d",&m,&n);
int count = GetDiff(m,n);
printf("count=%d",count);
return 0;
}
解析:先将两数进行异或计算。这样不相同的位数就可以由异或后的值进行表达,然后再将此值进行位为1的个数统计。
第七题
题目:打印二进制的奇数位和偶数位(从低位往高位数)
获取一个整数的二进制序列中所有的偶数位和奇数位,分别打印出二进制序列。
void Print(int m){
for (int i = 30; i >= 0; i-=2) {
printf("%d",(m>>i)&1);
}
printf("\n");
for (int i = 31; i >= 0; i-=2) {
printf("%d",(m>>i)&1);
}
}
int main(){
int m = 0;
scanf("%d",&m);
Print(m);
return 0;
}
解析:从最高位开始右移每次只要最后一位。通过奇数位偶数位的控制进行打印。
第八题
题目:交换两个变量(不创建临时变量)
方法一 思路 (加减法可能会溢出)
代码实现
int a = 2;
int b = 3;
a = a+b;
b = a-b;
a = a-b;
方法二 (思路) 一个数对同一个数两次异或回到本身。而且异或运算有交换律
代码实现
int a = 2;
int b = 3;
a = a^b;
b = a^b;
a = a^b;
printf("%d ",a);
printf("%d ",b);
函数传参
第一题
字符串逆序(递归实现)
编写一个函数reverse_string(char* string)。
非递归:
void reverse_string(char* arr,int sz){
int left= 0;
int right = sz-2;
int temp;
while (left<right){
temp = arr[left];
arr[left] = arr[right];
arr[right] = temp;
left++;
right--;
}
}
int main(){
char arr[] = "abcdef";
int sz = sizeof(arr)/ sizeof(arr[0]);
// printf("%d",sz);
reverse_string(arr,sz);
printf("%s",arr);
}
递归:
int my_strlen(char *str) {
char *start = str;
char *end = str;
while (*end != '\0') {
end++;
}
return (int)(end - start);
}
void reverse_string(char arr[]) {
char temp = arr[0];
int len = my_strlen(arr);
arr[0] = arr[len - 1];
arr[len - 1] = '\0';
if (my_strlen(arr + 1) >= 2)
reverse_string(arr + 1);
arr[len - 1] = temp;
}
int main() {
char arr[] = "abcdefg";
printf("%d\n", my_strlen(arr));
reverse_string(arr);
printf("%s\n", arr);
return 0;
}
解析:问题分解。交换最外层的两个值,当当前字符串长度大于等于2时递归。
实现步骤:1.将数组第一个值传给临时变量temp,将最后一个值传给第一个值。2.将最后一个位置先修改为’\0’用来表示字符串暂时结束。3.将数组下标从第二个开始reverse_string()。4.递归完之后将临时变量的值传给最后一个位置。
第二题
计算一个数的每位之和(递归实现)
写一个递归函数DigitSum(a),输入一个非负整数,返回组成他的数字之和。
int DigitSum(unsigned int num){
if(num/10 == 0){
return num;
}
return num % 10 +DigitSum(num/10);
}
int main(){
unsigned int num = 0;
scanf("%d",&num);
int res = DigitSum(num);
printf("res = %d",res);
return 0;
}
解析:终止条件就剩下一位数的的时候。举例1234的每位之和等于4+123的每位之和。
第三题
递归实现n的k次方
double Pow(int n,int k){
if (k==0) return 1;
else if (k>0) return n* Pow(n,k-1);
else return (1.0/n)* Pow(n,k+1);
}
int main(){
int n = 2;
int k = -3;
double res = Pow(n,k);
printf("res = %lf \n",res);
return 0;
}
解析:Pow(n,k) = n * Pow(n,k-1)。终止条件,k == 0的时候等于1。
第四题
计算斐波那契数列(递归实现)
int Fib(int first,int second,int n){ //---->>>需要修改参数的量
if (n<=2) return 1;
if (n==3) return first+second;
else return Fib(second,first+second,n-1);
}
int main(){
int n;
scanf("%d",&n);
int res = Fib(1,1,n);
printf("%d",res);
return 0;
}
解析:经过优化的斐波那契数列。
w(n,k-1)。终止条件,k == 0的时候等于1。
第四题
计算斐波那契数列(递归实现)
int Fib(int first,int second,int n){ //---->>>需要修改参数的量
if (n<=2) return 1;
if (n==3) return first+second;
else return Fib(second,first+second,n-1);
}
int main(){
int n;
scanf("%d",&n);
int res = Fib(1,1,n);
printf("%d",res);
return 0;
}
解析:经过优化的斐波那契数列。