(C语言进阶)笔试题详解

news/2025/2/15 22:06:36/

一.要点回顾

1.一维整形数组 

(1)sizeof()对一维整形数组的应用

#include<stdio.h>
int main()
{int a[] = {1,2,3,4};printf("%d\n", sizeof(a));//16
//sizeof(数组名),数组名表示整个数组,计算的是整个数组的大小,单位是字节printf("%d\n", sizeof(a+0));//  4/8
//a不是单独放在sizeof内部,也没有取地址,所以a就是首元素的地址,故a+0也是首元素的地址
//地址的大小为4/8个字节printf("%d\n", sizeof(*a));//4
//*a中的a是数组中首元素的地址,*a就是对首元素的地址解引用,找到的就是首元素
//首元素的大小为4个字节printf("%d\n", sizeof(a+1));//  4/8
//这里的a是数组首元素的地址,a+1为第二个元素的地址
//sizeof(a+1)就是地址的大小printf("%d\n", sizeof(a[1])); //4
//                sizeof(*(a+1));
//计算的是第二个元素的大小printf("%d\n", sizeof(&a)); // 4/8
//&a取出的是整个数组的地址,计算的也是地址printf("%d\n", sizeof(*&a));//16
//&a---->int(*)[4]
//&a拿到的是整个数组的地址,解引用后获得整个数组的元素
//故求的是整个数组所占内存的大小printf("%d\n", sizeof(&a+1));//  4/8
//&a拿到的是整个数组的地址,+1后跳过一整个数组的大小(16个字节)
//&a+1也是地址,故为4/8个字节printf("%d\n", sizeof(&a[0]));//   4/8
//                   sizeof(&*(a+0))
//a[0]是第一个数组元素,取地址后得到的是第一个元素的地址printf("%d\n", sizeof(&a[0]+1)); //  4/8
//&a[0]是数组首元素的地址,+1后得到第二个元素的地址return 0;
}

2.一维字符型数组 

(1) sizeof()对一维字符型数组的应用

#include<stdio.h>
int main()
{char arr[] = { 'a','b','c','d','e','f'};printf("%d\n", sizeof(arr));//6
//sizeof(数组名),数组名表示整个数组,计算的是整个数组的大小,单位是字节printf("%d\n", sizeof(arr+0));//  4/8
//arr+0是数组首元素的地址printf("%d\n", sizeof(*arr));//1
//*arr是数组的首元素,大小为1字节printf("%d\n", sizeof(arr[1]));//1
//                  sizeof(*(arr+1))
//为数组的第二个元素printf("%d\n", sizeof(&arr));//  4/8
//&arr取出的是整个数组的地址,是地址就是4/8个字节printf("%d\n", sizeof(&arr+1)); //  4/8
//&arr+1也是地址,故为4/8个字节printf("%d\n", sizeof(&arr[0]+1));// 4/8
//&arr[0]是数组首元素的地址,+1后得到第二个元素的地址return 0;
}

(2)strlen()函数对一维字符型数组的应用 

#include<stdio.h>
#include<string.h>
int main()
{char arr[] = { 'a','b','c','d','e','f' };printf("%d\n", strlen(arr));//随机值//strlen函数从指定地址进入后,需要遇到\0才会停止计数//字符数组中没有\0,故其会一直向后读取,直到在内存中遇到\0printf("%d\n", strlen(arr + 0));//随机值//arr+0表示的是数组的首元素地址printf("%d\n", strlen(*arr));//错误//*arr表示的是数组的首元素'a'//strlen需要的参数为指针类型,报错printf("%d\n", strlen(arr[1]));//错误//arr[1]表示数组的首元素//strlen需要的参数为指针类型,报错printf("%d\n", strlen(&arr));//随机值//&arr取出的是整个数组的地址,而整个数组地址的起始点为首元素地址printf("%d\n", strlen(&arr + 1));//随机值-6//&arr拿到的是整个数组的地址,+1后跳过一整个数组的大小(6个字节)printf("%d\n", strlen(&arr[0] + 1));//随机值-1//&arr[0]是数组首元素的地址,+1后得到第二个元素的地址return 0;
}

3.字符串 

(1)sizeof()对字符串的应用

#include<stdio.h>    
int main()
{char arr[] = "abcdef";//[a b c d e f \0]printf("%d\n", sizeof(arr));  //7
//arr在sizeof函数中表示全部元素,\0也会计数printf("%d\n", sizeof(arr+0));  //  4/8
//第一个元素的地址printf("%d\n", sizeof(*arr));  //1
//第一个元素printf("%d\n", sizeof(arr[1]));  //1
//第二个元素printf("%d\n", sizeof(&arr));  //  4/8
//整个字符串的地址printf("%d\n", sizeof(&arr+1));//  4/8
//从首元素地址跳过一整个字符串长度的地址printf("%d\n", sizeof(&arr[0]+1)); //  4/8
//第二个元素的地址return 0;
}

(2)strlen()对字符串的应用

#include<stdio.h>    
#include<string.h>
int main()
{char arr[] = "abcdef";//[a b c d e f \0]printf("%d\n", strlen(arr));  //6//首元素地址printf("%d\n", strlen(arr+0)); //6//首元素地址printf("%d\n", strlen(*arr)); //错误//strlen需要的参数为指针类型,报错printf("%d\n", strlen(arr[1]));  //错误//strlen需要的参数为指针类型,报错printf("%d\n", strlen(&arr));  //6//首元素地址printf("%d\n", strlen(&arr+1));  //随机值//首元素地址跳过一整个字符串长度的地址printf("%d\n", strlen(&arr[0]+1));  //5//第二个元素的地址return 0;
}

4.字符型指针 

(1)sizeof()对字符型指针的应用 

#include<stdio.h>
int main()
{char* p = "abcdef";printf("%d\n", sizeof(p));//  4/8//p是字符串的首元素地址printf("%d\n", sizeof(p+1));// 4/8//第二个元素的地址printf("%d\n", sizeof(*p));// 1//字符串首元素printf("%d\n", sizeof(p[0]));// 1//字符串首元素printf("%d\n", sizeof(&p));// 4/8//指向首元素地址的二级指针printf("%d\n", sizeof(&p+1));//  4/8//指向第二个元素地址的二级指针printf("%d\n", sizeof(&p[0]+1));//  4/8//             sizeof(&(*(p+0))+1)//第二个元素的地址return 0;
}

(2)strlen()对字符型指针的应用

#include<stdio.h>
#include<string.h>
int main()
{char* p = "abcdef";printf("%d\n", strlen(p)); //6
//第一个元素的地址printf("%d\n", strlen(p+1));//5
//第二个元素的地址printf("%d\n", strlen(*p));//报错
//第一个元素,与strlen所需的参数不同printf("%d\n", strlen(p[0]));//报错
//第一个元素,与strlen所需的参数不同printf("%d\n", strlen(&p));//随机值1
//整个字符串的地址printf("%d\n", strlen(&p+1));//随机值2
//首个元素地址+整个字符串长度的地址printf("%d\n", strlen(&p[0]+1)); //5
//第二个元素的地址return 0;
}

5.二维整形数组

(1) sizeof()对二维整形数组的应用

#include<stdio.h>
int main()
{int a[3][4] = {0};printf("%d\n", sizeof(a));//48
//a在sizeof中表示整个数组元素所占的内存大小printf("%d\n", sizeof(a[0][0]));//4
//第一个元素printf("%d\n", sizeof(a[0]));//16
//第一行元素printf("%d\n", sizeof(a[0]+1));//  4/8
//第一行第二个元素的地址printf("%d\n", sizeof(*(a[0]+1)));//4
//第一行第二个元素printf("%d\n", sizeof(a+1));//  4/8
//第二行元素的地址printf("%d\n", sizeof(*(a+1)));//16
//第一行元素printf("%d\n", sizeof(&a[0]+1));//  4/8
//第二行元素的地址printf("%d\n", sizeof(*(&a[0]+1)));//16
//第二行元素printf("%d\n", sizeof(*a));//16
//第一行元素printf("%d\n", sizeof(a[3]));//16
//第三行元素return 0;
}

 二.笔试题

 1.第一题

题目: 

#include<stdio.h>
int main()
{int a[5] = {1,2,3,4,5};int* ptr = (int*)(&a+1);printf("%d,%d",*(a+1),*(ptr-1));return 0;
}

解析:

答案:2,5

#include<stdio.h>
int main()
{
    int a[5] = {1,2,3,4,5};
    int* ptr = (int*)(&a+1);
    //ptr为首元素地址跳过整个数组
    printf("%d,%d",*(a+1),*(ptr-1));//2,5
    return 0;
}

2.第二题 

题目: 

#include<stdio.h>
//已知结构体Test类型的变量大小为20个字节
struct Test
{int Num;char* pcName;short sDate;char cha[2];short sBa[4];
}*p=(struct Test*)0x100000;
int main()
{printf("%p\n",p+0x1);  //0x100014//struct Test类型加一增加20个字节printf("%p\n", (unsigned long)p + 0x1);//0x100001//unsigned long类型加一增加1个字节printf("%p\n", (unsigned int*)p + 0x1);//0x100004//unsigned int*类型加一增加4个字节return 0;
}

解析:

答案: 0000000000100020 ,0000000000100001  , 0000000000100004

#include<stdio.h>
//已知结构体Test类型的变量大小为20个字节
struct Test
{
    int Num;
    char* pcName;
    short sDate;
    char cha[2];
    short sBa[4];
}*p=(struct Test*)0x100000;
int main()
{
    printf("%p\n",p+0x1);  //0x100014
    //struct Test类型加一增加20个字节
    printf("%p\n", (unsigned long)p + 0x1);//0x100001
    //unsigned long类型加一增加1个字节
    printf("%p\n", (unsigned int*)p + 0x1);//0x100004
    //unsigned int*类型加一增加4个字节
    return 0;
}

3.第三题 

题目: 

#include<stdio.h>
int main()
{int a[4] = {1,2,3,4};int* ptr1 = (int*)(&a + 1);int* ptr2 = (int*)((int)a + 1);printf("%x,%x",ptr1[-1],*ptr2);return 0;
}

解析:

答案:4,20000

 #include<stdio.h>
int main()
{
    int a[4] = {1,2,3,4};
    int* ptr1 = (int*)(&a + 1);
    //ptr1为数组首元素地址跳过一整个数组的地址
    int* ptr2 = (int*)((int)a + 1);
    //(int)a+1增加一个字节,(int*)((int)a + 1)为首元素地址向后一个字节
//00 00 00 01 | 00 00 00 02 | 00 00 00 03 | 00 00 00 04——数组中元素地址
//01 00 00 00 | 02 00 00 00 | 03 00 00 00 | 04 00 00 00——在内存中存储(小端存储)
//  |                                                  |
// ptr2                                               ptr1
    printf("%x,%x",ptr1[-1],*ptr2);
//以十六进制输出时,ptr1[-1]为后退四个字节,然后读取四个字节输出——00 00 00 04
//*ptr2为读取四个字节然后输出——02 00 00 00
    return 0;
}

4.第四题 

题目: 

#include<stdio.h>
int main()
{int a[3][2] = {(0,1),(2,3),(4,5)};int* p;p = a[0];printf("%d",p[0]);return 0;
}

 解析:

答案:1

#include<stdio.h>
int main()
{
    int a[3][2] = {(0,1),(2,3),(4,5)};//逗号表达式,读取的值为后面的数
    int* p;
    p = a[0];
    //p为第一行的元素 
    printf("%d",p[0]);
    //p[0]是第一行的第一个元素
    return 0;
}

 

 5.第五题

题目: 

#include<stdio.h>
int main()
{int a[5][5];int(*p)[4];p = a;printf("%p,%d\n",&p[4][2]-&a[4][2], &p[4][2] - &a[4][2]);return 0;
}

 解析:

答案: -4,FFFFFFFC

#include<stdio.h>
int main()
{
    int a[5][5];
    int(*p)[4];
    p = a;
    printf("%p,%d\n",&p[4][2]-&a[4][2], &p[4][2] - &a[4][2]);
//&p[4][2]-&a[4][2]=(-4)
//10000000 00000000 00000000 00000100——(-4)原码
//11111111 11111111 11111111 11111011——反码
//11111111 11111111 11111111 11111100——补码
//FF FF FF FC——十六进制
//按地址输出时把补码当做地址输出
    return 0;
}

6.第六题 

 题目:

#include<stdio.h>
int main()
{int aa[2][5] = {1,2,3,4,5,6,7,8,9,10};int* ptr1 = (int*)(&aa+1);int* ptr2 = (int*)(*(aa + 1));printf("%d,%d",*(ptr1-1),*(ptr2-1)); return 0;
}

解析:

答案: 10,5

#include<stdio.h>
int main()
{
    int aa[2][5] = {1,2,3,4,5,6,7,8,9,10};
    int* ptr1 = (int*)(&aa+1);
    //ptr1为首元素地址跳过整个数组后的地址
    int* ptr2 = (int*)(*(aa + 1));
    //          (int*)aa[1]
    printf("%d,%d",*(ptr1-1),*(ptr2-1)); //10,5
    //*(ptr1-1)—>*(a[2]-1)—>a[1][4]
    //*(ptr2-1))—>*(aa[1]-1)—>aa[0][4]
    return 0;
}

7.第七题 

题目: 

#include<stdio.h>
int main()
{char* a[] = {"work","at","alibaba"};char** pa = a;pa++;printf("%s\n",*pa);return 0;
}

解析:

答案:at 

#include<stdio.h>
int main()
{
    char* a[] = {"work","at","alibaba"};
    char** pa = a;
    //pa为字符串首元素("work")的地址
    pa++;
    //++后pa指向"at"
    printf("%s\n",*pa);
    return 0;
}

8.第八题 

题目: 

#include<stdio.h>
int main()
{char* c[] = {"ENTER","NEW","POINT","FIRST"};char** cp[] = {c+3,c+2,c+1,c};char*** cpp = cp;printf("%s\n", **++cpp);printf("%s\n", *--*++cpp+3);printf("%s\n", *cpp[-2]+3);printf("%s\n", cpp[-1][-1]+1);return 0;
}

解析:

答案: POINT,ER,ST,EW

#include<stdio.h>
int main()
{
    char* c[] = {"ENTER","NEW","POINT","FIRST"};
    char** cp[] = {c+3,c+2,c+1,c};
    char*** cpp = cp;
    //cpp为c+3的地址


    printf("%s\n", **++cpp);//POINT
    //++cpp—>c+2的地址
    // **++cpp—>"POINT"的首元素地址

    printf("%s\n", *--*++cpp+3);//ER
    //cpp为c+2的地址
    //++cpp—>c+1的地址
    //--*++cpp—>c+1-1—>c
    //*--*++cpp—>"ENTER"的首元素地址
    //*--*++cpp+3—>"ENTER"第四个元素的地址

    printf("%s\n", *cpp[-2]+3);//ST
    //cpp为c+1的地址
    //cpp[-2]—>*(cpp-2)—>元素c+3—>"FIRST"的地址
    //*cpp[-2]+3—>*(cpp[-2]+3)—>"FIRST"的第四个元素的地址

    printf("%s\n", cpp[-1][-1]+1);//EW
    //cpp为c+1的地址
    //cpp[-1]—>*(cpp-1)—>元素c+2—>"POINT"的地址
    //cpp[-1][-1]—>*(cpp[-1]-1)—>"NEW"的地址
    //cpp[-1][-1]+1—>"NEW"第二个元素的地址
    return 0;
}


http://www.ppmy.cn/news/1152723.html

相关文章

LCR 172.统计目标成绩的出现次数

​​题目来源&#xff1a; leetcode题目&#xff0c;网址&#xff1a;LCR 172. 统计目标成绩的出现次数 - 力扣&#xff08;LeetCode&#xff09; 解题思路&#xff1a; 两次二分&#xff0c;一次寻找首次出现的位置&#xff0c;一次寻找最后一次出现的位置。 解题代码&#…

SAP报错CX_SY DYN CALL PARAM MISSING

DYN CALL METH PARAM MISSING CX_SY DYN CALL PARAM MISSING 在 ABAP 中&#xff0c;当你定义一个方法时&#xff0c;可以选择将方法的参数标记为可选&#xff08;可选参数&#xff09;或必需&#xff08;必需参数&#xff09;。如果你不勾选可选参数选项&#xff0c;那么该参…

在网络安全、爬虫和HTTP协议中的重要性和应用

1. Socks5代理&#xff1a;保障多协议安全传输 Socks5代理是一种功能强大的代理协议&#xff0c;支持多种网络协议&#xff0c;包括HTTP、HTTPS和FTP。相比之下&#xff0c;Socks5代理提供了更高的安全性和功能性&#xff0c;包括&#xff1a; 多协议支持&#xff1a; Socks5代…

flutter 网络图片封装

可自定义加载时占位图片和加载失败时展示的图片 class ImageBuildView extends StatelessWidget {String? url;double radius;double? width;double? height;String placeholder;ImageBuildView({super.key,this.url,this.width,this.height,this.radius 50,this.placehol…

Git 速通以及常用指令!!

参考视频 01 - Git - 教程简介_哔哩哔哩_bilibili 在需要使用git的文件夹打开git bash&#xff0c;指令如下↓ 当然图形化界面也很香&#xff01;github desktop也很舒服&#xff01; 查看文件 版本号 git cat-file -p 版本号 仓库操作 在当前文件夹下创建git仓库 git ini…

Linux下将驱动编译进内核

在开发的过程中&#xff0c;一般都是将驱动编译成模块&#xff0c;然后将其发送到开发板加载驱动进行功能验证&#xff0c;驱动的功能验证没有问题后就可以将其编译进内核了。本文将介绍如何把上一篇文章Linux下设备树、pinctrl和gpio子系统、LED灯驱动实验中的LED驱动编译到内…

Namomo Summer Camp 23 Day 1

Namomo Summer Camp 23 Day 1 - Virtual Judge B - Brexiting and Brentering AC代码: #include<bits/stdc.h> #define endl \n //#define int long long using namespace std; string s; void solve() {cin>>s;int x-1;for(int is.size()-1;i>0;i--){if(s[i…

Spring Cloud Gateway 搭建网关

新建一个module添加依赖&#xff1a; <!--Spring Cloud Gateway依赖--> <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId> </dependency><!-- nacos客户端依赖…