C语言编程总结(三)

一、多维数组和指针

        从二维数组的角度看,x代表的是二维数组首元素的地址,现在的首元素不是一个简单的整型元素,而是由四个整型元素所组成的一维数x代表的是首行(即第0行)的首地址。x+1代表第1行的首地址。

x[0]、x[1]、x[2]、x[3]、x[4]、x[5]既然是一维数组名,而C语言由规定了数组名代表数组首元素地址,因此x[0]代表一维数组x[0]中第0列元素的地址,即&x[0][0]。x[1]的值是&x[1][0],以此类推。

       请考虑0行1列的元素的地址怎么表示?x[0]为一维数组名,该移位数组中序号为1的元素的地址显然应该用x[0]+1来表示。此时 x[0]+1 中的1代表1个列元素的字节数,即4个字节。今x[0]的值是2000,x[0]+1的值是2004(而不是2016),这是因为现在是在一维数组范围内讨论问题的,正如有一个一维数组a。a[0]+1是其第一个元素x[1]一样。x[0]+0、x[0]+1、x[0]+2、x[0]+3、x[0]+4、x[0]+5分别是x[0][0]、x[0][1]、x[0]2]、x[0][3]、x[0][4]、x[0][5]的地址。

       x[0]和*(x+0)等价,x[1]和*(x+1)等价,x[i]和*(x+i)等价。因此,x[0]+1和*(x+0)+1都是&x[0][1]。x[1]+2和 *(x+1)+2的值都是&x[1][2]。

      进一步分析,欲得到x[0][1]的值,用地址法怎么表示呢?既然x[0]+1和*(x+0)+1是x[0][1]的地址,那么,*(x[0]+1)就是x[0][1]的地址。同理,*(*(x+0)+1)或*(*x+1)也是x[0][1]的值。

二、字节对齐

https://blog.csdn.net/cclethe/article/details/79659590

三、静态库和动态库

四、内存泄漏和内存泄漏

https://blog.csdn.net/xwh012510/article/details/86518577?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-4&spm=1001.2101.3001.4242

内存溢出,申请不到足够的内存;

内存泄露,无法释放已申请的内存;

两者关系:内存泄露 → 剩余内存不足 → 后续申请不到足够内存 →内存溢出。

五、const

  • 1、什么是const?

    const就是constant的缩写,意思是“恒定不变的”,它是定义只读变量的关键字,或者说const是定义常变量的关键字,常类型的变量或对象的值是不能被更新的

  • 2、为什么引入const?

    const推出的初始目的,就是为了取代预编译指令,消除它的缺点,同时继承它的优点

1. define只是用来进行单纯的文本替换,define常量的声明周期止于编译期,不分配内存空间,它存在于程序的代码段,在实际程序中它只是一个常数,一个命令中的参数并没有实际的存在;而const常量存在于长须的数据段,并在堆栈中分配了空间,const常量在程序中确实存在,且可以被调用、传递

2. const常量有数据类型,而define常量没有数据类型,编译器可以对const常量进行类型安全检查,但是define不行

3.很多IDE支持调试const定义的常量,而不支持define定义的常量

综上

由于const修饰的变量可以排除程序之间的不安全性因素,保护程序中的常量不被修改,而且对数据类型也会进行相应的检查,极大地提高了程序的健壮性,所以一般更加倾向于用const定义常量类型

  • 3、const有什么主要的作用?

    (1)可以定义const常量,具有不可变性。例如:const int MAX = 100; int array[MAX];

    (2)便于进行类型检查,使编译器对处理内容有更多了解,以消除一些隐患

        例如:void f(const int i) {......}编译器就会知道 i 是一个常量,不允许修改。

    (3)可以保护被修饰的东西,防止意外的修改,增强程序的健壮性。还是上面例子,如果在函数体内修改了 i ,编译器就会报错

        例如:void f(const int i){ i = 1001;} error!

    (4)为函数重载提供了一个参考

class A
{
  void f(int i) { ...... }  //一个函数
  void f(int i) const { ...... }  //上一个函数的重载.....
};

    (5)提高了效率。 编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高。

  • 4、const的使用

  const在实际中用得并不多,先列出如下const短小总结,const关键字修饰指针,const在*号的左边还是右边(左定值,右定向)

复制代码

1.const int a;      //a是一个常整形数
2.int const a;      //a是一个常整形数
3.const int *a;      //a是一个指向常整数型的指针(整形数是不可修改的,但指针可以)
4.int const *a;      //a是一个指向常整数型的指针(同上)
5.int *const a;      //a是一个指向整形数的常指针(指针保存内容不可修改)
6.int const * const a;  //a是一个指向常整形数的常指针(指针指向的整形数是不可修改的,同时指针也是不可修改的)

(1)int const * ;

    int const *a 和 const int *a意义一样。

    从右往左看,进行解析,这个a是一个指针,而且是一个常量,类型是整形,称为指针常量

    特点:*a指向一个整形的常量,但是不能通过修改p所指向内存单元的值,只能通过修改其所指向的对象,可称为指向常整形的指针

int data = 88;
const int number = 99;
const int *p1 = &number;

p1 = &data;     //允许通过编译,允许修改所指向的对象
*p1 = 10086;   //不允许通过编译,无法通过指针修改内容

(2)int * const  a;

从右往左看,一个常量a被定义为整形指针。可称为指向整形的常指针

特点:常量a是一个整型类型的指针,它能通过指针来进行修改其中的内容,但当它已经指向一个地址之后,便不能再指向其他地址,和int const*有区别

int data = 88;
int k = 99;
int * const p2 = &data;

*p2 = 10010;  //允许通过编译,允许通过指针修改内容;
p2 = &k;     //不允许通过编译,无法修改所指向的对象;
(3)const int * const p;

从右往左看,结合上面两个,可以看做常量指针常量,即常量p是一个整形的指针,而且这个指针还是个常量

int data = 88;
int k = 99;
int const * const p3 = &data;

p3 = &k;    //不允许通过编译
*p3 = 4399;  //不允许通过编译

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

孙八瓶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值