《C语言深度刨析》整理--指针和数组

C和指针课后练习题总结 下面是一些对软件大赛比较有用的东东,咱学院08级的聪哥精心整理。。 有些题做起来可能麻烦。。但是挺有帮助! 《c和指针》这本书大家不需要单独购买,浪费钱毕竟~~~不如省下钱来请俺吃饭饭!哈哈~~~~如果只做题的话从网上下载电子版的就可以了。 链接在此。。不需要积分。。。http://ishare.iask.sina.com.cn/f/23415790.html 阅读详情
 

  指针是c/c++ 精华,没有很好的掌握指针,基本是没有掌握c/c++,对c/c++ 也是一知半解,往往指针掌握不好,也不能很好的理解数组和内存管理

一、指针在系统同占用的空间

        在32位系统中,指针所占空间的大小为 4个字节,与指针指向的数据类型无关;

       比如   int  *p; char *p;  double *p; int **p;  已经执行构造类型的结构体的(比如指向  结构体,联合体等的指针)大小均为4个字节

       int *p;  表示内存中分配四个字节的内存空间,并将这块空间命名为p,并且这块内存p 中存入的数据都当做地址来看,大小是4个字节

二、int *p = NULL 和*p = NULL 区别

       (1) int *p = NULL;

          表示定义了一个指向int 类型的指针 p(p指向的内存用来存放int类型的数据),并将p 初始化为NULL,即p 指向内存为NULL地方(内存地址0x00000000);

       (2) int *p;    *p = NULL;

         表示定义了一个指向int类型的指针 p(p指向的内存用来存放int类型的数据),注意此处p 未被初始化,p可能指向内存中一个非法的内存地址,而这时对*p = NULL; 赋值

        可能是对非法的内存地址进行赋值;

        解析:区别:(1)表示对p赋值(定义p指向的内存地址)(2) p 指向未定义,p指向随机的一块内存地址,是对p指向的内存进行赋值

        注意:定义变量的时候,定义的同时一定要对变量进行初始化;

三、将数值存储到指定的内存地址

       现对内存为0x0012ff60 的内存进行赋值0x100(首先保证0x0012ff60这个内存地址是可以访问的)

      (1) int *p = (int *)0x0012ff60;

                   *p = 0x100;

       (2) *((int *)0x0012ff60) = 0x100;

四、数组内存布局

        int a[10] = {0};

        表示在内存中申请了一块内存 大小是 sizeof(int)*10,这块内存存放10个int 类型的数据,整块内存命名为a,这块内存没有名字,要访问内存中的各个元素只能通过数组

名a 加上下标或者偏移量的形式访问;

       (1) a 作为右值的时候表示数组首元素首地址; sizeof(a) = 40 (32位机下)

      (2)  &a 表示数组的首地址, &a + 1 将偏移 sizeof(int) * 10 个大小的空间

       (3)a 不能作为左值:a 的值不可改变(数组的访问要通过a加地址偏移或者下标形式访问)a 不能作为左值

               比如a++ 是错误的, a++ 等价于 a = a + 1;(编译错误)

               int *p = NULL;  p = a + 1;  (编译正确)

       (4)&a[0]和&a 区别

              虽然&a[0]和&a 值是相同的,但表示的意义不同:

            &a[0] 表示a[0]的地址(数组首元素首地址)

            &a 表示的是整个数组的首地址

五、指针和数组的关系

        指针和数组无任何关系

         (1)指针就是指针,指针变量在32 位系统下,永远占4 个byte,其值为某一个内存的地址。指针可以指向任何地方,但是不是任何地方都能通过这个指针变量访问到

         (2)数组就是数组,其大小与元素的类型和个数有关。定义数组时必须指定其元素的类型和个数。数组可以存任何类型的数据,但不能存函数

六、指针、数组访问

        看下面一道例题:

  1. int main()   
  2. {   
  3.     int a[5] = {1,2,3,4,5};   
  4.     int *ptr = (int *)(&a+1);   
  5.     printf("%d, %d", *(a+1), *(ptr-1));   
  6.     return 0;   
  7. }   

 

解析:

       (1) &a + 1  表示自数组的首地址开始,偏移了&a +  5*sizeof(int) 大小的地址, 指向数组a[4]即 元素5 后面的元素;

                 (int *) (&a + 1)  然后强制类型转化为指向int 类型的指针,然后赋值给 ptr,ptr的偏移量n, 就转化为偏移 n*sizeof(int) 大小

                所以,*(ptr - 1) 值为 5

      (2) *(a+1) 表示数组首元素首地址偏移一个 sizeof(int) 的地址, 所以*(a+1) 值为2

七、代码在一个地方定义为指针,在别的地方也只能声明为指针;在一个的地方定义为数组,在别的地方也只能声明为数组

八、指针数组和数组指针

      (1)指针数组:首先它是一个数组,数组的元素都是指针,数组占多少个字节由数组本身决定。它是“储存指针的数组”的简称。 比如: int *p1[10];

      (2)数组指针:首先它是一个指针,它指向一个数组。在32 位系统下永远是占4 个字节,至于它指向的数组占多少字节,不知道。它是“指向数组的指针”的简称

                比如: int (*p2)[10];

九、指针数组经典例题

         在x86 系统下,其值为多少?

  1. int  main()  
  2. {  
  3.     int a[4]={1,2,3,4};  
  4.     int *ptr1=(int *)(&a+1);  
  5.     int *ptr2=(int *)((int)a+1);  
  6.     printf("%x,%x",ptr1[-1],*ptr2);  
  7.     return 0;  
  8.  }  

        解析:

        (1) ptr1 的值为 4 (解析见前面)

         (2) 首先要确定系统是大端还是小端模式

               确定大端小端模式函数:  函数返回值为1:小端模式;函数返回值为0:大端模式

               

  1. int  checkSystem()  
  2.   
  3. {  
  4.   
  5.      union test  
  6.   
  7.      {  
  8.   
  9.          int i;  
  10.   
  11.          char ch;  
  12.   
  13.      }a;  
  14.   
  15.      a.i = 1;  
  16.   
  17.     return  ( a.ch == 1);  
  18.   
  19.  }  

          若checkSystem() 返回值 为1,表示系统为小端模式, *ptr2 值为 2000000

          若checkSystem()返回值 为0,表示系统为大端模式,  *ptr2 值为  100

十、二维数组

     1. 二维数组的地址

       char a[3][4];

      二维数组在内存中是以线性的形式存储的,char a[i][j] ;编译器总是将二维数组看成是一个一维数组,而一维数组的每一个元素又都是一个数组

     a[i][j]的首地址为&a[i]+j*sizof(char)。再把&a[i]的值用a 表示,得到a[i][j]元素的首地址为:a+ i*sizof(char)*4+ j*sizof(char)。同样,可以换算成以指针的形式表示:*(a+i)+j

      2. 二维数组的初始化

    

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

    解析: 结果是 1,而不是0  注意例题中初始化的时候,用到的是括号表达式而不是大括号

   在初始化二维数组的时候一定要注意,别不小心把应该用的花括号写成小括号了。

十一、二级指针

       char **p;
     定义了一个二级指针变量p。p 是一个指针变量,在32 位系统下占4 个byte。它与一级指针不同的是,一级指针保存的是数据的地址,二级指针保存的是一级指针的地址。

     注: 多维数组和多级指针可以根据二维数组和二级指针依次类推

十二、数组参数和指针参数

     1. 不能向函数传递一个数组

          比如:       

  1. #include "stdio.h"  
  2.   
  3. void fun(char a[10])  
  4. {  
  5.     ......  
  6. }  
  7.   
  8. int main()  
  9. {  
  10.     char b[10] = "abcdefg";  
  11.     fun(b[10]);  
  12.     return 0;  
  13. }  

解析:

     (1):b[10] 代表的是数组的一个元素,不能代表数组

     (2):b[10] 数组越界了

     (3):void fun(char a[10]); 实际是要传递的是一个char类型的指针;参数可以改写为

                    void fun(char a[]); 或者 void fun(char *a);

     (4):函数调用的时候可以改写成 fun(b);

    总结:C 语言中,当一维数组作为函数参数的时候,编译器总是把它解析成一个指向其首元素首地址的指针。

  2. 不能把指针本身传递给函数

    例一:  

  1. #include "stdio.h"  
  2.   
  3. void fun(char *p)  
  4. {  
  5.     char c = *(p+3);  
  6.     printf("%c\n", c);  
  7. }  
  8.   
  9. int main()  
  10. {  
  11.     char *p2 = "abcdefg";  
  12.     fun(p2);  
  13.   
  14.     return 0;  
  15. }  

解析:

       (1). p2 是main 函数内的一个局部变量,它只在main 函数内部有效。(注意:main 函数内的变量不是全局变量,而是局部变量,只不过它的生命周期和全局

                   变量 一样长而已。全局变量一定是定义在函数外部的)

      (2). 对实参p2做一份拷贝并传递给被调用的函数。即对p2 做一份拷贝,假设其拷贝名为_p2。那传递到函数内部的就是_p2 而并非p2 本身。

     例二:

  1. #include "stdio.h"  
  2. #include "stdlib.h"  
  3. #include "string.h"  
  4.   
  5. void GetMemory(char * p, int num)  
  6. {  
  7.     p = (char *)malloc(num * sizeof(char));  
  8. }  
  9. int main()  
  10. {  
  11.     char *str = NULL;  
  12.   
  13.     GetMemory(str, 10);  
  14.     strcpy(str, "hello");  
  15.     free(str);//<span style="color:#000099;">free 并没有起作用,内存泄漏</span>  
  16.   
  17.  return 0;  
  18. }  

解析:

          通过编译可以看到,str的值仍未NULL。因为str 传到函数内部的是str的拷贝假设名字是_str, 当函数GetMemory(char *p, int num) 退出时,申请的内容

 同时释放掉并未传递给str(malloc 的内存的地址并没有赋给str,而是赋给了_str。而这个_str 是编译器自动分配和回收的),导致内存访问异常;

 例二:解决方法

        (1) 增加return,将申请的内存返回给str,同时要用str 进行接收

  1. #include "stdio.h"  
  2. #include "stdlib.h"  
  3. #include "string.h"  
  4.   
  5. char * GetMemory(char * p, int num)  
  6. {  
  7.     p = (char *)malloc(num * sizeof(char));  
  8.   
  9.     return p;  
  10. }  
  11. int main()  
  12. {  
  13.     char *str = NULL;  
  14.   
  15.     str = GetMemory(str, 10);  
  16.     strcpy(str, "hello");  
  17.     free(str);  
  18.   
  19.     return 0;  
  20. }  

    (2)使用二级指针

  1. #include "stdio.h"  
  2. #include "stdlib.h"  
  3. #include "string.h"  
  4.   
  5. void GetMemory(char ** p, int num)  
  6. {  
  7.     *p = (char *)malloc(num * sizeof(char));  
  8.   
  9. }  
  10. int main()  
  11. {  
  12.     char *str = NULL;  
  13.   
  14.     GetMemory(&str, 10);  
  15.     strcpy(str, "hello");  
  16.     puts(str);  
  17.     free(str);  
  18.      return 0;  
  19. }  

解析:

        这种方法真正的将str传到函数GetMemory(char **p, int num) 中
        (1)GetMemory(&str, 10); 这里传递的是 str的地址,函数内部申请空间赋值给 *p(也就是str),malloc 分配的内存地址是真正赋值给了str

 3. 二维数组参数和二维指针参数

      void fun(char a[3][4]);

      可以把a[3][4]理解为一个一维数组a[3],其每个元素都是一个含有4 个char 类型数据的数组。上面的规则,“C 语言中,当一维数组作为函数参数的时候,编译器总是把它解

析成一个指向其首元素首地址的指针。所以上面表达式可以改为:   void fun(char a[ ][4]); 或者 void fun(char (*a)[4]);

     C 语言中,当一维数组作为函数参数的时候,编译器总是把它解析成一个指向其首元素首地址的指针。这条规则并不是递归的,也就是说只有一维数组才是如

此,当数组超过一维时,将第一维改写为指向数组首元素首地址的指针之后,后面的维再也不可改写

十三、函数指针

        函数指针的形式之一: char * (*fun1)(char * p1,char * p2); (注意:此处的fun1 是指向函数的指针,而不是函数名,此函数是匿名的)

    1、函数指针的使用

        比如:

  1. #include <stdio.h>  
  2. #include <string.h>  
  3.   
  4. char * fun(char * p1, char * p2)  
  5. {  
  6.     int i = 0;  
  7.     i = strcmp(p1, p2);  
  8.   
  9.     if (0 == i)  
  10.     {  
  11.        return p1;  
  12.     }  
  13.     else  
  14.     {  
  15.        return p2;  
  16.     }  
  17. }  
  18.   
  19. int main()  
  20. {  
  21.     char *str = NULL;  
  22.     char * (*pf)(char * p1, char * p2);  
  23.   
  24.     pf = &fun;  
  25.   
  26.     str = (*pf)("aa", "bb");  
  27.     puts(str);  
  28.   
  29.     return 0;  
  30. }  

解析:

使用指针的时候,需要通过钥匙(*)来取其指向的内存里面的值,函数指针使用也如此。通过用(*pf)取出存在这个地址上的函数,然后调用它。这里需要注意到

是,在Visual C++6.0 里,给函数指针赋值时,可以用&fun 或直接用函数名fun。因为函数名被编译之后其实就是一个地址,所以这里两种用法没有本质的差别。

  2. (*(void(*) ())0)() 的含义

     解析:

      (1)void(*)()    定义了一个函数指针

      (2)(void(*)()0)  将0强制转化为一个函数指针,0是个地址,这个匿名函数保存于起始地址为0的一块内存中

      (3)(*(void(*) ())0),这是取0 地址开始的一段内存里面的内容,其内容就是保存在首地址为0 的一段区域内的函数

      (4)(*(void(*) ())0)(),这是函数调用

  3. 函数指针数组

      char * (*pf[3])(char * p);

      解析:

      pf 是数组名,这个数组是指针数组,数组中的每个元素均为指针(指向函数的指针)

      例题:指针数组的使用

  1. #include <stdio.h>  
  2. #include <string.h>  
  3. char * fun1(char * p)  
  4. {  
  5.     printf("%s\n",p);  
  6.     return p;  
  7. }  
  8.   
  9. char * fun2(char * p)  
  10. {  
  11.     printf("%s\n",p);  
  12.     return p;  
  13. }  
  14.   
  15. int main()  
  16. {  
  17.     char * (*pf[3])(char * p);  
  18.   
  19.     pf[0] = fun1; // 可以直接用函数名  
  20.      pf[1] = &fun2; // 可以用函数名加上取地址符  
  21.   
  22.      pf[0]("fun1");  
  23.     pf[1]("fun2");  
  24.   
  25.     return 0;  
  26. }  

 

C语言深度解剖 PDF 分享 链接:https://pan.baidu.com/s/1U-8L7ZY5_sLpk4p0J302Mg           提取码:d8nu 相关推荐 [Objective-c程序设计] 中文编程·学习进阶_易语言 Windows API开发详解 函数、接口、编程实例 Programming in ... 阅读详情

相关推荐

嵌入式C语言面试:指针、数组与野指针考点全解析

在嵌入式开发中,内存管理是系统稳定性的基石,而C语言指针直接暴露了内存地址的底层操作逻辑。理解指针的类型、步长与内存模型,是编写可靠驱动代码的前提。数组与指针的纠缠关系、野指针的隐患,以及C++引用的语义差异,都是嵌入式工程师在实际项目中的高频难题。无论是寄存器访问、DMA缓冲处理,还是多任务数据共享,这些基础知识都直接影响代码在恶劣硬件环境下的表现。本文从面试官视角出发,系统拆解指针、数组、野指针、引用等核心考点的底层原理与实战技巧,帮助开发者建立清晰的内存模型思维,提升嵌入式场景下的排错能力与代码质量。

weixin_33858485的博客 381

指针-C语言的灵魂

指针详解指针定义指针类型指针的运算.常见几种指针 指针定义 指针定义: 计算机把整个内存条分成了一个小小的存储单元。 每一个存储单元都有一个唯一的地址,指针变量就是存放这些地址的对象。 地址:内存单元中每一个字节的编号。 指针:内存中的一个地址.以后理解成地址和指针等价。 指针变量:保存指针的变量.int* px;px就是指针变量。 指针定义格式: 类型* 指针变量名 = &变量。 指针打...

Limit_Fly的博客 364

《C语言深度解剖》20题手把手教学

目录 1.下面代码输出什么?为什么? 2.下面代码会有什么问题,为什么? 3.下面的代码i和j的值分别是什么?为什么? 4.下面代码里,假设在32位系统下,各sizeof计算的结果分别是多少? 5.下面代码的结果是多少?为什么? 6.下面的代码,哪些内容可以被改写,哪些不可以被改写 7.下面的两段代码有什么区别?什么时候需要使用代码(2)? 8.在32位的X86系统下,输出的值是多少? 9.0x01<<2+3的值为多少?为什么? 10.定义一个函数宏,求x的平方 11.下面

Ll_R_lL的博客 1575

【C语言进阶】指针常见笔试题详解

在我们学习完指针的有关知识之后,我们为了对指针有一个更为深入的理解,我们今天来学习几道指针笔试题,来看看指针是如何考察的。

weixin_61654591的博客 810

告别复杂模型:用UFLD算法5分钟搞定车道线检测(附Python代码)

本文介绍了UFLD(Ultra Fast Lane Detection)算法在车道线检测中的高效应用,仅需5行核心代码即可实现实时检测,特别适合边缘计算设备。通过对比传统方法,UFLD在推理速度、模型大小和硬件需求上具有显著优势,是深度学习领域轻量级解决方案的典范。

weixin_27872611的博客 288

用SOLIDWORKS从零画一个履带机器人,手把手教你搞定底盘和传动

本文详细介绍了如何使用SOLIDWORKS从零开始设计履带式机器人,重点讲解底盘结构优化和传动系统设计的关键步骤。通过七个阶段的实战指南,包括前期规划、底盘建模、驱动系统装配、履带生成、动态模拟等,帮助工程师和爱好者掌握履带机器人的核心设计技巧,提升地形适应能力和动力效率。

weixin_30872499的博客 632

数组与指针关系

数组与指针的关系

qq_41727421的博客 4990

波束形成算法:LCMV实现(MATLAB)

阵列信号处理,波束成形,

weixin_43601588的博客 1万+

指针与数组的关系及运算

一、概念: 1.1、指针:指针变量p的值是地址,“*”为取数据符,*p表示取p所指向的地址中的数据,“&”为取地址符。 1.2、数组:数组是用于储存连续多个相同类型数据在内存中的集合。 1.3、指针与数组的关系:指针变量p是个地址,而数组的数组名a也是个地址,从而可以这样赋值p=a,由此衍生的指针数组、数组指针所产生的表达式及运算千变万化,经常看到一个表达式都不知道,最终所求的值是地址还是数据。网络上看了好多推演的教程,也思考了很久,但看到好多推演断层式的表达式,还是想不明白。最终自己找...

oO斯曼的博客 7078

FOC电机控制中电流采样延迟补偿的原理和方法

摘要: FOC电机控制中,电流采样、计算与PWM更新存在固有延迟(约1.5个PWM周期),导致相位滞后,限制电流环带宽。主流补偿方法包括: 一阶前向预测法:基于历史电流值预测未来电流,抵消延迟,工程应用广泛; 相位超前补偿:通过s/z域校正器设计实现等效预测; 状态观测器法(如龙伯格观测器):通过电机模型闭环估计状态,兼具噪声抑制和参数辨识能力,但复杂度高。实际需注意参数敏感性、离散化精度及延迟时间校准,避免过补偿风险。一阶预测法因平衡效果与复杂度成为工业首选。

jifengzhiling的博客 2232

ESP32-C3入门教程 WiFi篇①——WiFi Scan 扫描附近AP无线热点 | 堵塞等待扫描结果,回调事件通知扫描结果

文章目录一、快速运行二、运行效果三、程序流畅四、关键函数4.1 扫描所有有效的AP4.2 获取上次扫描中找到的AP列表4.3 获取上次扫描中找到的AP数 一、快速运行 示例项目中,选择WiFi—>scan menuconfig配置ESP32C3-Specific—>Rec 0 芯片选择ESP32-C3(Built-in USB JTAG) 快速运行ESP-IDF Build, Flash and Monitor(左下角) 二、运行效果 三、程序流畅 esp_netif_init,初始

5417

十一:数组和指针的关系?

十一:数组和指针的关系:区别和联系;

qq_26538113的博客 3828

DAMMFND: Domain-Aware Multimodal Multi-view Fake News Detection

虚假新闻的泛滥不仅严重阻碍了互联网社交媒体的健康发展,还在政治、经济和社会层面造成了实际危害,凸显了自动化虚假新闻检测的重要性(Zhou 等,2015;Cui 等,2019;Zhu 等,2022a;Li 等,2024c,b,a)。现有的虚假新闻检测方法通常聚焦于特定领域的新闻,例如健康或政治领域。然而,在现实世界中,社交媒体上的新闻往往跨越多个领域,这就要求现有的虚假新闻检测方法必须考虑多域泛化(Nan 等,2021;Qi 等,2019;Zhu 等,2022b)。

qq_52053775的博客 337

【C语言】深度理解指针(下)

💎昨晚整理博客时突然发现指针还少了一篇没写,今天就顺便来补一补。上回书说到,emmm忘记了,没事,我们直接进入本期的内容:本期我们带来了几道指针相关笔试题的解析,还算是相对比较轻松的。话不多说,让我们来看看吧👀【C语言】深度理解指针(上)【C语言】深度理解指针(中)✈做完这8道题目,不得不说,画图真的是一个非常好的解题方法。有些题目,尽管看似十分复杂,当我们把示意图画出来时,问题就迎刃而解,非常直观。因此我们在日常分析题目时要擅于画图。

忆梦初心的博客 2260

Apache Kafka Connect任意文件读取漏洞(CVE-2025-27817)

由于Apache Kafka客户端未对用户输入进行严格验证和限制,未经身份验证的攻击者可通过构造恶意配置读取环境变量或磁盘任意内容,或向非预期位置发送请求,提升REST API的文件系统/环境/URL访问权限。(CVE-2025-27817)

iSee857的博客 2026

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

C语言深度理解数组与指针——你真的会用数组吗?

本篇是对字符指针、数组指针、指针数组这篇博客进行的补充。字符指针、数组指针、指针数组以及指针传参——C语言上一篇博客对字符串常量的介绍较为笼统与模糊,以及对“二维数组”根本没有介绍。本篇将重点整理数组与指针的关系以及一些便于记忆的代码。我们先研究一段代码: 输出结果:这段代码我们介绍过,但是并没有给出很明确的解释。 现在我们来详细分析:我们用 if else 语句来判断 str 和 arr 的地址是否相同,输出结果为 0 ,即不相同。我们的问题在于,都使用看起来相同的字符串,为什么地址会不相同。首先看

weixin_59913110的博客 312

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

《C语言深度刨析》整理--内存管理

一、内存的存储区 1.、栈(堆栈)区、堆区、静态区等 (1)、栈区(堆栈)(stack):由编译器自动分配释放 ,存放函数参数值,局部变量等。栈上的内容只在函数的范围内存在,当函数运行结束,这些内容也会自动被毁.其特点是:效率高,但空间大小有限 (2)、堆区(heap) :一般由程序员分配释放 , 由malloc 系列函数或new 操作符分配的内存。其生命周期由free 或delete 决定

xyk_code的专栏 456

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

【万字长文】一文搞定C语言指针

本文系统讲解了C语言指针的核心知识点,包括指针的本质与内存模型、核心操作与类型系统、与数组的深度关联、在函数中的高级应用、动态内存管理、与结构体的结合、const限定符的使用、常见问题与调试技巧等。文章详细剖析了指针的二重性(地址属性和类型属性)、空指针与野指针的区别、指针与数组的等价性、函数指针与回调机制、malloc/free的正确使用、结构体指针与链表实现等关键内容。同时提供了大量代码示例、内存管理最佳实践和调试方法,并推荐了进一步学习的经典书籍。

HRDMN的博客 1392

《C语言深度解剖》面试题整理

请在40分钟内完成以下20道C语言基础题。在没有任何提示的情况下,如果能得满分,那么你可以扔掉本书了,你的水平已经大大超过了作者;如果能的80分以上,说明你的C语言基础还不错,学习本书可能会比较轻松;如果得分在50分以下,也不要气馁,努力学习就行了;如果不小心得了10分以下,你就得给自己悄悄警钟了;如果不幸得了0分,那实在是不应该,因为毕竟很多题是很简单的。 从《C语言深度解剖》摘录,若想晓得答案,自己运行一遍即可,欢迎交流。

fovwin的专栏 3673

整理《C语言深度剖析》4.3.2 –a和&a的区别

以下内容为本人大学时的笔记,最近偶然翻到,所以发出来也算留一下备份,所以有些描述什么的可能不太准确,欢迎各位大神批评指正。 整理《C语言深度剖析》4.3.2 –a和&a的区别 下面是陈正冲老师的《C语言深度剖析》的内容: 上面这些是书中的内容,我个人感觉最难理解的是&a+1,陈正冲老师对&a+1的解释如下: 对指针进行加 1 操作,得到的是下一个元素的地址,而不是原有地址值直接加 1。所以,一个类型为 T 的指针的移动,以 sizeof(T) 为移动单位。 因此,对上题来说, a

D_Flash的博客 487

为什么说指针是c语言的灵魂?

我攻克这个难关,花了好几年时间,因为它不像单片机的问题,网上都有答案,也有例程参考,这种问题,是开发经验的问题,网上找不到资料,有也只是零零散散的。工作6,7年以后,独立做了一些复杂的项目,有物联网网关,有Ble产品,研究过协议栈和模块厂的SDK,也见过很多同事写的代码,对指针又有了新的理解。刚做开发的前两三年,我总是感觉自己写的程序,不够专业高大上,很多程序都过度使用指针,看起来更复杂显得专业点,现在回看那程序:真傻杯,脱裤子放屁。你可以简单理解成,就像人没有灵魂,废了,c语言没有指针,也废了。

无际单片机编程 1179

最新刨析《C语言》【进阶】付费知识【二(2),干货整理

/因为book_name是字符型的数组名,数组本身是个地址。#pragma pack()//取消设置的默认对齐数,还原为默认。#pragma pack()//取消设置的默认对齐数,还原为默认。//等同于p->price。#pragma pack(8)//设置默认对齐数为8。#pragma pack(1)//设置默认对齐数为1。//使用库函数字符串拷贝函数。printf(“相同”);//输出的结果是什么?

afagagagaa的博客 321

C语言数组分析

定义二维数组的时候,行可以省略,列绝对不能省略。int a[][4];// 合法写法int a[3][];// 编译报错静态数组内存连续,空间固定;malloc 动态内存不一定连续。C99 变长数组不能动态扩容。,所有下标底层都是指针解引用运算。多维数组拆解思路:二维数组 = 存放多个一维数组的数组;三维数组 = 存放多个二维数组的数组。分清两个极易混淆概念:→ 数组指针(指针,接收多维数组)int *p[n]→ 指针数组(数组,存放一堆指针)

W_32600的博客 574

C语言第七天学习笔记:指针、数组与字符串的深度解析

C语言入门的核心在于理解指针与数组的关系,这不仅是语法知识,更是内存操作能力的体现。数组名在表达式中常被转换为首元素指针,而二维数组的行指针概念则决定了函数传参的正确写法。字符串处理如逆序、拷贝与比较,需要区分字符数组和字符指针的差异;循环控制中的while与do-while选择、排序算法的手写练习,都是工程实践中的高频基础。文件读写与浮点数比较等细节,也直接影响程序的稳定性和可移植性。掌握这些底层原理,能帮助学习者在实际项目中更自信地运用C语言,从容面对计算机二级或嵌入式开发中的常见考题。

weixin_32466193的博客 328

C语言-深度理解

经过几天的整理,我将C语言中一些难度比较高的语法和需要的注意点列出来,还有很多没有整理出来,比如最基本的数据类型、选择分支循环的语法,因为那些在C语言中使用得比较多也比较熟,所以就在此省略。 一、指针 (*p) 1、 数据类型的本质是固定内存块大小的别名。        指针也是一种数据类型,占4个字节,用来保存地址,指针指向谁就把谁的地址传给指针。 2、指针变量和他所指向的内存空间变量是

一念之间、 972
上一篇: 《c语言深度剖析》整理--预处理
下一篇: 《C语言深度刨析》整理--内存管理
xyk_code
博客等级 码龄15年 3粉丝 11原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值