C语言学习的三大难题!

时间:2022-07-22
本文章向大家介绍C语言学习的三大难题!,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

提到C语言很多初学者都觉得,学到中间就进行不下去了,尤其是学到指针内存管理的部分,没写过几个野指针、没有debug过内存越界那都不叫完整的“人生”啊!

内存布局

提到c语言的内存操作方式,就绕不开指针。

指是针公认最难理解的概念,也是让很多C语言初学者选择放弃的直接原因。

软件开发/设计行业有这么一句话:没有什么是不能通过增加一个抽象层解决的。

这句话很对……但抽象层并不是免费的。这点就很少有人想过了:一旦你和什么东西之间被加上了一个抽象层,那你就一定得在每次访问它时受到某种限制、或者付出某些代价

而对C来说,数组就是一个指向一片内存区域的指针……它并不去封装这个概念;恰恰相反,它鼓励你去了解藏在表象背后的东西。

于是乎,举例来说,在大量文本中搜索匹配某个模式的字符串(即strstr函数),如果C用3秒能搜完,其它语言再快可能也得9秒。因为每和一个字符比较,其它语言都要多两次索引越界与否的检查动作。

当然,这个好处并不是白捡到的。C语言用户因此而付出的代价,就是防不胜防的缓冲区溢出问题……

常见的指针使用错误包括但不限于:

内存分配未成功,却使用了它。

内存分配虽然成功,但是尚未初始化就引用它。

内存分配成功并且已经初始化,但操作越过了内存的边界。

忘记了释放内存,造成内存泄露。

释放了内存却继续使用它(所谓的野指针)。一般情况下,释放掉指针后将指针置为空。

(以上错误你中了几条?)

指针函数、函数指针听起来是不是有点像绕口令?

函数指针

C语言中指针不仅可以指向内存地址,同样也可以指向函数。指向函数的指针称为函数指针

函数指针指向被调用函数的首地址,可以通过它来调用函数。

其定义方式为 类型说明符 (*变量名)(形参列表);其中形参列表中可以省略形参名称。

指针函数

定义函数时需要说明函数的返回值类型,其可以是整型,字符型或者是指针等,当函数的返回值为指针时,该函数就称为指针函数。

指针函数返回的是指针,其定义方式为:类型说明符 * 函数名(形参列表){函数体}

一句话总结!!!

指向函数的指针叫函数指针

返回值为指针的函数称为指针函数

一个是指针,一个是函数,你说差别大不大。

函数指针的一个应用实例:

#include <stdio.h>
// 函数指针的应用
// 计算两个整数的和
int sum(int a,int b)
{
    return a + b;
}
// 计算两个整数的差
int sub(int a,int b)
{
    return a - b;
}
// 计算两个整数的乘积
int mul(int a,int b)
{
    return a*b;
}
// 计算两个整数相除的余
int mod(int a,int b)
{
    return a%b;
}
 
int main(int argc, char* argv[])
{
    int a = 10,b = 2;
    int (*p)(int ,int );  //定义一个函数指针   根据不同的情况指向不同的函数 
    int op = 2;
    switch(op)
    {
        case 1:
            p = sum;
            break;
        case 2:
            p = sub;
            break;
        case 3:
            p = mul;
            break;
        case 4:
            p = mod;
            break;
        default:
            break;
    }
    int result = p(a,b);
    printf("result = %dn",result);
    return 0;
}

指针函数的一个应用实例:

  //定义一个指针函数
int * getMax(int a ,int b)
{
    return a > b? &a:&b;
}
int main(int argc, const char * argv[]) {
    int num1 = 100,num2 =200;
    int *p = getMax(num1,num2);
    printf("较大的数值是:%dn",*p);
    return 0;
}

结构体

很多大学开c语言课的都把结构体放在最后讲,弄得很多学生觉得结构体不重要,如果只是应付学校的考试,或者就是为了混个毕业证,的确学的意义不大。

但是如果你从事编程这个行业,结构体的概念可以说是相当重要。

没有一个业务体是完全使用原生数据类型来完成的,很多大牛在写代码解决问题的时候,首先要做的就是设计结构体。然后设计函数功能,最后才是编程实现。

如果从节省空间考虑结构体里面的数据放的顺序不一样在内存中占用的空间也不一样,结构体与结构体之间赋值,结构体存在指针那么赋值要特别注意,需要进行深度的赋值。

攻克了c语言学习的这三座大山,再去学习别的内容就相对比较简单了。