豆瓣9.1,百万程序员的宝藏书,C语言进阶必看!(文末送书) 您所在的位置:网站首页 c语言指针例题程序 豆瓣9.1,百万程序员的宝藏书,C语言进阶必看!(文末送书)

豆瓣9.1,百万程序员的宝藏书,C语言进阶必看!(文末送书)

2023-04-09 00:38| 来源: 网络整理| 查看: 265

一:操作符和表达式

C提供了我们希望编程语言应该拥有的所有操作符,它甚至提供了一些令人意想不到的操作符。事实上,C被许多人所诟病的一个缺点就是它有品种繁多的操作符——C的这个特点使它很难被精通。

但是,C的许多操作符具有其他语言的操作符无可抗衡的价值,这正是C适用于开发范围极广的应用程序的原因之一。C语言进阶,搞清楚操作符优先级和算术转换是重要的一课。

二:数据、结构和联合以及动态内存分配

程序对数据进行操作,数据又经常以成组的形式存在。例如,雇主必须明了每位雇员的姓名、年龄和工资。如果这些值能够存储在一起,访问起来会简单一些。但是,如果这些值的类型不同,则无法存储于同一个数组中。在C中,使用结构可以把不同类型的值存储在一起。

数组的元素存储于内存中连续的位置上。当一个数组被声明时,它所需要的内存在编译时就被分配。但是,也可以使用动态内存分配在运行时为它分配内存。那么什么时候应该使用动态内存分配?怎样进行动态内存分配?想成为一名合格的C语言程序员,这些你都了解了吗?

三:字符串、字符和字节

字符串是一种重要的数据类型,但是C语言并没有显式的字符串数据类型,因为字符串以字符串常量的形式出现或者存储于字符数组中。

字符串常量很适用于那些程序不会对它们进行修改的字符串。处理字符串和字符的库函数,以及一组既可以处理字符串也可以处理非字符串数据的相关函数是进阶C语言的一道不小的门槛。

四:预处理器

编译一个C程序涉及很多步骤。其中第一个步骤被称为预处理 (preprocessing)阶段。C预处理器 (preprocessor)在源代码编译之前对其进行一些文本性质的操作。

它的主要任务包括删除注释、插入被#include指令包含的文件的内容、定义和替换由#define指令定义的符号,以及确定代码的部分内容是否应该根据一些条件编译指令进行编译。

五:指针

C语言只有值的传递,无法直接传递引用,要想传递引用必须通过指针间接实现。

要搞明白指针,就要搞明白:内存和地址、值和类型、指针变量的内容、NULL指针、指针常量、指针的表达式、指针运算等等......这就是为什么指针被称为C语言进阶最大boss的原因了。

新手面对指针的常见问题

C语言的指针很重要,但新手进阶C语言时,指针相关的问题往往是最多的,这里给大家挑选了两个常见问题,看看你对这几点了解吗?

一、未初始化和非法的指针

下面这个代码段说明了一个极为常见的错误:

这个声明创建了一个名叫a的指针变量,后面那条赋值语句把12存储在a所指向的内存位置。但是究竟a指向哪里呢?

我们声明了这个变量,但从未对它进行初始化,所以没有办法预测12这个值将存储于什么地方。从这一点看,指针变量和其他变量并无区别。如果变量是静态的,它会被初始化为0;如果变量是自动的,它根本不会被初始化。无论是哪种情况,声明一个指向整型的指针都不会“创建”用于存储整型值的内存空间。

所以,如果程序执行这个赋值操作,会发生什么情况呢?

如果运气好,a的初始值会是个非法地址,这样赋值语句将会出错,从而终止程序。在UNIX系统上,这个错误被称为“段违例”(segmentation violation)或“内存错误”(memory fault)。它提示程序试图访问一个并未分配给程序的内存位置。在一台运行Windows的PC上,对未初始化或非法指针进行间接的访问操作是一般保护性异常(general protection exception)的根源之一。

对于那些要求整数必须存储于特定边界的机器而言,如果这种类型的数据在内存中的存储地址处于错误的边界上,那么对这个地址进行访问时将会产生一个错误。这种错误在UNIX系统中被称为“总线错误”(bus error)。

一种更为严重的情况是,这个指针偶尔可能包含了一个合法的地址。接下来的事很简单:位于那个位置的值被修改,虽然你并无意去修改它。像这种类型的错误非常难以捕捉,因为引发错误的代码可能与原先用于操作那个值的代码完全不相干。所以,在对指针进行间接访问之前,必须非常小心,确保它们已被初始化!

二、高级声明

在使用更高级的指针类型之前,我们必须观察它们是如何声明的。

我们可以来看几个简单的例子:

int f;

它把f声明为一个函数,它的返回值是一个整数。旧式风格的声明对函数的参数并未提供任何信息。它只声明f的返回值类型。现在将使用这种旧式风格,这样例子看上去简单一些,后面再回到完整的原型形式:

int (*f);

确定括号的含义是分析这个声明的一个重要步骤。这个声明有两对括号,每对的含义各不相同。第2对括号是函数调用操作符,但第1对括号只起到聚组的作用。它迫使间接访问在函数调用之前进行,使f成为一个函数指针,它所指向的函数返回一个整型值。

函数指针?是的,程序中的每个函数都位于内存中的某个位置,所以存在指向那个位置的指针是完全可能的。

int *(*f);

它和前一个声明基本相同,f也是一个函数指针,只是所指向的函数的返回值是一个整型指针,必须对其进行间接访问操作才能得到一个整型值。

通过以上不难看出,指针虽然很强大,与之相伴的风险却也不小。就像指甲锉和链锯,链锯可以更快地切割木材,但链锯更容易让人受伤,而且伤害常常来得极快,后果也非常严重。

指针就像链锯一样,如果使用得当,它们可以简化算法的实现,并使其更有效率;如果使用不当,它们就会引起错误,导致细微而令人困惑的症状,并且极难发现原因。所以对指针只是略知一二便放手使用是件非常危险的事。

想要学好指针,最好的办法就是有一位导师在身后注视你的工作,时不时给你一些提示和警告。导师是谁?当然是它

《C和指针》

豆瓣评分9.1,这本经典之作真正地让人搞懂了烦人的指针。

虽然书名叫《C和指针》,但是书中的内容却讲到了C的方方面面。全书逻辑清晰,通俗易懂,在讨论C语言理论与实践的紧密融合之外,还提供了非常宝贵的提示和警告,让新手才初踏入C语言世界就免受各种陷阱的困扰。

当然,本书最大的特点就是对指针的清晰剖析,对其基础用法和高级特性都有详细介绍,告诉读者该如何有效地把指针融入自己的实际开发当中。

免费送书《C和指针》

免费送5本给计算机视觉life的粉丝。方法:文末 留言评论「你学习C/C++的经验或困惑」, 点再看并发送到朋友圈。留言需要和该主题相关,否则不会被精选,截止至1月13日12:00,点赞最高的第1到5名,可获赠书一本。请勿刷赞,如发现将取消资格返回搜狐,查看更多



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有