目录

1. 相关资料

2. 快速入门

2.1 数据类型

void万能类型

小结

2.2 变量本质

2.3 内存“四区”

2.4 指针

一级指针

一级指针与字符串

一级指针与数组

二级指针(**)

数组、数组指针,指针数组

多维数组做函数参数 退化的本质

函数指针

小点:const 强化

小点:define宏定义

小点:typedef

​​​​​​​小点:static强化

​​​​​​​小点:extern关键字


1. 相关资料

  • Video

    • C语言基础入门视频学习:链接: https://pan.baidu.com/s/1_-5CdTPXkxtYpbVj3cv_fQ   密码:osfu (备注:视频讲的很清晰,但是时间比较长)
  • 教程:
    • 菜鸟教程:http://www.runoob.com/cprogramming/c-exercise-example1.html  (备注:适合入门)

      • C语言知识点总结:https://wenku.baidu.com/view/75569ee8f8c75fbfc77db254.html
      • C语言与数据结构精讲: http://c.biancheng.net/cpp/u/shuju/
  • 难点Blogs
    • C语言内存管理:https://blog.csdn.net/lovemysea/article/details/79338678 (备注:注意内存的四个区域及功能)
    • 指针:https://blog.csdn.net/constantin_/article/details/79575638 (备注:需要注意指针的含义,数组与指针的关系)

2. 快速入门

2.1 数据类型

void万能类型

小结

2.2 变量本质

  1. 程序通过变量来申请和命名内存空间 int a = 5;
  2. 通过变量名访问内存空间
    1. (一段连续)内存空间的别名(是一个门牌号)
  3. 修改变量有几种方法?
    1. 直接
    2. 间接。内存有地址编号,拿到地址编号也可以修改内存--->指针(编程案例2)
  4. 数据类型和变量的关系 ?答案:通过数据类型定义变量
  5. 总结及思考题
    1. 对内存,可读可写
    2. 通过变量往内存读写数据
    3. 不是向变量读写数据,而是向变量所代表的内存空间中写数据。

2.3 内存“四区”

2.4 指针

  • 指针是一种数据类型
  • 指针也是一种变量,占有内存空间,用来保存内存地址
  • *p操作内存
  • 间接赋值(*p)是指针存在的最大意义
  • 引申: 函数调用时,n指针(形参)改变n-1指针(实参)的值。

一级指针

典型用法:做函数参数

  • 一级指针做输入
int showbuf(char *p)
int showArray(int *array, int iNum)
  • 一级指针做输出
int geLen(char *pFileName, int *pfileLen);

理解:主调函数还是被调用函数分配内存;被调用函数是在heap/stack上分配内存

一级指针与字符串

  • 在C语言中用字符数组模拟字符串
//若没有指定长度,默认不分配零
char buf1[] = {'a', 'b', 'c', 'd', 'e'};//若指定长度,不够报错;buf长度多于初始化个数,会自动补充零
char buf2[6] = {'a', 'b', 'c', 'd', 'e‘};
char buf3[6] = {'a', 'b', 'c', 'd', 'e‘};
//char buf4[5] = {'a', 'b', 'c', 'd', 'e’};
  • C语言中的字符串是以’\0’结束的字符数组
  • C语言中的字符串可以分配于栈空间,堆空间或者只读存储区

一级指针与数组

  • 元素类型角度:数组是相同类型的变量的有序集合 测试指针变量占有内存空间大小
  • 内存角度:连续的一大片内存空间
  • 数组名是数组首元素的起始地址,但并不是数组的起始地址
  • 通过将取地址符&作用于数组名可以得到整个数组的起始地址
  • 数组名 在做函数参数时 退化成指针

二级指针(**)

典型用法(指针做函数参数)

  • 二级指针做输入
int main(int arc ,char *arg[]); 字符串数组
int shouMatrix(int [3][4], int iLine);
  • 二级指针做输出
int Demo64_GetTeacher(Teacher **ppTeacher);int Demo65_GetTeacher_Free(Teacher **ppTeacher);int getData(char **data, int *dataLen);Int getData_Free(void *data);Int getData_Free2(void **data); //避免野指针

理解: 主调函数还是被调用函数分配内存;被调用函数是在heap/stack上分配内存

数组、数组指针,指针数组

  • 数组
  • 数组指针:指向 数组的 指针  int (*a) [10]
  • 指针数组:指针的数组    int *a[10]

定义数组指针的方式

  • 利用数组类型的别名
typedef int (MyArrayType) [5];
MyArrayType *pointer; // a[5]
  • 声明一个数组指针类型
typedef int (*MyPointer) [5];
MyPointer myPoint;
  • 直接定义:
int (*pointer)[n];

多维数组做函数参数 退化的本质

  • 二维数组可以看做是一维数组
  • 二维数组中的每个元素是一维数组
  • 二维数组参数中第一维的参数可以省略
  • void f(int a[5])   --->  void f(int a[]);   --->   void f(int* a)
  • void g(int a[3][3]) ---> void g(int a[][3]);  ---> void g(int (*a)[3])

函数指针

  • 一个数据变量的内存地址可以存储在相应的指针变量中,函数的首地址也以存储在某个函数指针变量中。这样,我就可以通过这个函数指针变量来调用所指向的函数了。
  • 函数指针变量的声明:
void (*funP)(int) ;   //声明一个指向同样参数、返回值的函数指针变量。

小点:const 强化

  • 修饰普通变量 à常量
  • 指针常量和常量指针
  • 修饰函数参数
    • 防止修改指针指向的内容: void StringCopy(char *strDestination, const char *strSource);
    • 防止修改指针指向的地址: void swap ( int * const p1 , int * const p2 )
  • 修饰函数的返回值:
    • 如果给以“指针传递”方式的函数返回值加 const 修饰,那么函数返回值(即指针)的内容不能被修改,该返回值只能被赋给加const 修饰的同类型指针。
const char * GetString(void);
const char *str = GetString();  //right
// char * = GetString(void); wrong

小点:define宏定义

参考:https://blog.csdn.net/xingjiarong/article/details/47282255

  • 关键字const用来定义常量,如果一个变量被const修饰,那么它的值就不能再被改变,我想一定有人有这样的疑问,C语言中不是有#define吗,干嘛还要用const呢,我想事物的存在一定有它自己的道理,所以说const的存在一定有它的合理性,与预编译指令相比,const修饰符有以下的优点:

    • 预编译指令只是对值进行简单的替换,不能进行类型检查
    • 可以保护被修饰的东西,防止意外修改,增强程序的健壮性
    • 编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高。
  • 预编译指令只是对值进行简单的替换,不能进行类型检查
#define MAXTIME 1000
#define max(x,y) (x)>(y)?(x):(y);

小点:typedef

  • 定义一种类型的别名,而不只是简单的宏替换。可以用作同时声明指针型的多个对象。比如:
typedef char* PCHAR;
PCHAR pa, pb;  
  • 用在旧的C代码中,帮助struct。以前的代码中,声明struct新对象时,必须要带上struct,即形式为: struct 结构名对象名,如:
typedef struct tagPOINT{ int x; int y; } POINT;
POINT p1; 
  • 为复杂的声明定义一个新的简单的别名。方法是:在原来的声明里逐步用别名替换一部分复杂声明,如此循环,把带变量名的部分留到最后替换,得到的就是原声明的最简化

    • 原声明:void (*b[10]) (void (*)());
    • 简化:
      • 变量名为b,先替换右边部分括号里的,pFunParam为别名一:
      • typedef void (*pFunParam)();
      • 再替换左边的变量b,pFunx为别名二:
      • typedef void (*pFunx)(pFunParam);
      • 原声明的最简化版:
      • pFunx b[10];

​​​​​​​​​​​​​​小点:static强化

  • 参考:

    • https://www.cnblogs.com/wly603/archive/2012/04/11/2442065.html
    • https://www.cnblogs.com/wly603/archive/2012/04/11/2442065.html
  • static变量定义
    • 局部

      • 静态局部变量在函数内定义,生存期为整个源程序,但作用域与自动变量相同,只能在定义该变量的函数内使用。退出该函数后, 尽管该变量还继续存在,但不能使用它。
      • 对基本类型的静态局部变量若在说明时未赋以初值,则系统自动赋予0值。而对自动变量不赋初值,则其值是不定的。
    • 全局
      • 全局变量本身就是静态存储方式 静态全局变量当然也是静态存储方式但是他们的作用域,非静态全局 变量的作用域是整个源程序(多个源文件可以共同使用); 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。
  • ​​​​​​​​​​​​​​static函数(也叫内部函数)
    • ​​​​​​​只能被本文件中的函数调用,而不能被同一程序其它文件中的函数调用。区别于一般的非静态函数(外部函数)

​​​​​​​小点:extern关键字

  • extern char *ctime(const time_t *);
  • 具有文件外部链接,但是声明extern变量时,编译器并不会给这个变量分配内存,在另外的文件中定义这个文件时才会为其分配内存,一旦声明了extern关键字,对编译器来意味着:
  • 这个变量声明(即数据类型和变量名,但是编译器并没有分配内存
  • 这个变量的定义在其他文件中(在定义变量的文件中编译器才会为其分配内存)

C语言快速入门和相关资料相关推荐

  1. Swift教程Swift语言快速入门(内部资料)

    Swift语言快速入门(内部资料) 试读下载地址:http://pan.baidu.com/s/1eQCGRHw 前言Swift教程Swift语言快速入门(内部资料)Swift教程Swift语言快速入 ...

  2. Swift语言快速入门

    Swift语言快速入门(首部同步新版官方API文档和语法的Swift图书,确保代码可编译,作者专家在线答疑,图书勘误实时跟进) 极客学院 编著   ISBN 978-7-121-24328-8 201 ...

  3. JAVA程序设计-头歌实训-------# 第一阶段 Java语言快速入门

    第一阶段 Java语言快速入门 第1关:Java程序的基本框架:Hello Java World! 任务描述 本关的任务是编写你人生中第一个Java程序,从此开启你的Java实训之旅,显示效果如下: ...

  4. Python语言快速入门(下)

    前言 本图文是本期图文的下篇,可能篇幅较长大概有10000多字,很高兴您能阅读,也感谢您的关注支持!这期下篇主要还是接着上次的内容继续,在上篇中我介绍了关于Python环境的安装.基本数据处理.输入输 ...

  5. 视频教程-做游戏学Python-Python语言快速入门-Python

    做游戏学Python-Python语言快速入门 20年软件项目开发管理经验 工信部人才交流中心特聘专家讲师 日本U-CAN在线教育特聘主任讲师 国家十二·五规划软件工程教材作者(书:清华大学出版社出版 ...

  6. Swift 1.1语言快速入门7.2使用无参函数

    Swift 1.1语言快速入门7.2使用无参函数 无参数函数是指没有参数列表的函数.以下对它的声明定义.调用以及最简单的函数--空函数进行详细的讲解 7.2.1  无参函数的声明定义 函数在使用之前必 ...

  7. Common Lisp语言快速入门

    zhezhelin Common Lisp语言快速入门 Lisp是软件领域的分裂力量.一方面,Lisp爱好者誓言Lisp比软件领域内的其它语言都更加快捷.整洁和强大:而反对者则辩称,不可靠的执行和库支 ...

  8. sql语言和php,SQL语言快速入门(三)_php

    我们日常使用SQL语言的工作过程中,使用最多的还是从已经建立好的数据库中查询信息.下面,我们就来详细介绍一下如何使用SQL语言实现各种数据库查询操作. SELECT-FROM 为方便讲解,我们在数据库 ...

  9. Swift 语言快速入门

    Swift 语言快速入门 简单值 控制流 函数闭包 对象和类 枚举和结构体 协议和拓展 错误处理 泛型 由于项目原因,需要做一款 iOS 应用...然后这个任务就落到了我身上-emm 经过我的全方面了 ...

最新文章

  1. 读书笔记-恰到好处的幸福
  2. Android桌面悬浮窗进阶,QQ手机管家小火箭效果实现
  3. 抖音数据统计_“彭十六elf”单条视频获赞200W+,荣登抖音TOP20丨红人榜
  4. Jquery Easy UI--datagrid的使用(转)
  5. 第二天 PYTHON 基本数据类型 - 数字 - 字符串
  6. php汽车找车位,遭遇到车多车位少 教你如何快速找到停车位
  7. java异常错误的是,java 异常 错误处理
  8. mysql 连边聚合_MySQL分组,聚合函数,连表查询,子查询
  9. Linux定时器函数setitimer
  10. java求sobel算子代码_sobel算子原理与实现
  11. 阶段3 1.Mybatis_01.Mybatis课程介绍及环境搭建_04.mybatis概述
  12. Fragstats计算景观生态指数
  13. 卸载JLink驱动弹出“could not open INSTALL.LOG file”的解决方法
  14. 《电子商务概论》刘宏,PPT总结成Word
  15. 电赛校赛经验-程控风力摆
  16. python快速搭建服务器方法
  17. 全国计算机ncrc广东,2020年普通高等学校招生全国统一考试广东卷Ⅰ
  18. 计算机视觉城市排名,计算机视觉技术量化城市变迁
  19. linux gpu 地址空间,显卡内存和进程的虚拟地址空间
  20. 设备接入ONENET(2)STM32 + ESP8266(MQTT协议)接入云 :使用 OneNET 官方麒麟座开发板例程

热门文章

  1. 70个经典面试问题,有备无患~
  2. 创业是一种心态、信念和坚持,是一种生活方式
  3. 输出Ceres自动求导的雅克比
  4. SL651-2014水文检测数据通信规约pdf下载
  5. SwiftUI 精品项目之完整Go围棋游戏App支持在线对战OGS Alamofire SocketIO(教程含源码)
  6. 苹果手机能低价买?46人被骗1.5亿元
  7. 如何设计数据库(1)?
  8. 带你开发类似Pokemon Go的AR游戏(1)
  9. ATF(Adobe Texture Format)简介
  10. 【TARS】理解RegistryServer