c语言基础超详细知识点(CC编程笔记)
c语言基础超详细知识点(CC编程笔记)
2024-09-29 01:39:37  作者:兲鍀寵餌  网址:https://m.xinb2b.cn/sport/hlq354422.html


一、C语言程序的构成

与C 、Java相比,C语言其实很简单,但却非常重要。因为它是C 、Java的基础。不把C语言基础打扎实,很难成为程序员高手。

1、C语言的结构

先通过一个简单的例子,把C语言的基础打牢。


C语言的结构要掌握以下几点:

(1)C语言的注释是,而不是//···,//是C 的单行注释,有的C语言版本也认可。

(2)C语言区分大小写,每句以分号结尾。

(3)C语言程序是从main函数开始的。函数的返回值如果缺省则为int,而不是void。

(4)函数必须用return来返回。即使void类型也不建议省略。

(5)使用函数时须包含相应的头文件。自定义的头文件用双引号,C语言自身的头文件用<···>

2、main()函数的写法与含义

main()的参数和返回值全部省略,这和上例含义相同。省略写法是一种很不好的习惯。


main()的参数是一种不限个数的写法,argc代表参数的个数,真正的参数是放在argv[]数组里面的。注意:当数组当参数用时,数组被降格为指针。初学者先照着样子写,以后小雅会详细说明指针和数组的区别。


3、头文件的意义

每个C程序通常分为两个文件。一个文件用于保存程序的声明(declaration),称为头文件。另一个文件用于保存程序的实现(implementation),称为定义(definition)文件。

C程序的头文件以“.h”为后缀,C 程序的定义文件以“.c”为后缀。

头文件的内容也可以直接写C程序中,但这是很不好的习惯。许多初学者用了头文件,却不明其理。在此略作说明。

(1)通过头文件来调用库功能。在很多场合,源代码不便(或不准)向用户公布,只要向用户提供头文件和二进制的库即可。用户只需要按照头文件中的接口声明来调用库功 能,而不必关心接口怎么实现的。编译器会从库中提取相应的代码。

(2)头文件能加强类型安全检查。如果某个接口被实现或被使用时,其方式与头文件中 的声明不一致,编译器就会指出错误,这一简单的规则能大大减轻程序员调试、改错的 负担。

关于头文件的内容,初学者还必须注意。

(1)头文件中可以和C程序一样引用其它头文件,可以写预处理块,但不能写语句命令。

(2)可以申明函数,但不可以定义函数。

(3)可以申明常量,但不可以定义变量。

(4)可以“定义”一个宏函数。注意:宏函数很像函数,但却不是函数。其实还是一个申明。

(5)结构的定义、自定义数据类型一般也放在头文件中。

(6)#include <filename.h>,编译系统会到C语言固定目录去引用。#include "filename.h",系统一般首先在当前目录查找,然后再去环境指定目录查找。

4、好的风格是成功的关键

版本声明、函数功能说明、注释等是C语言程序的一部分。不养成很好的习惯则不能成为C语言高手(专业人员)。


二、比较、逻辑、位运算符

只有类型相同(或C语言能自动转换)的表达式才能比较,如果类型不同就必须用函数转换。例如:判断一字符串的长度是否等于10,就要用strlen()将字符串的长度求出来变成了整型,才能和10比较。

比较运算符只有6个,即:等于(==)、不等于(!=)、大于(>)、小于(<)、大于等于(>=)、小于等于(<=)。比较运算符也叫关系运算符。

逻辑运算符只有3个,即:与AND(&&)、或OR(||)、非NOT(!)。

位运算符只有6个,即:与AND(&)、或OR(|)、非NOT(~)、异或XOR(^)、左移ShiftLeft(<<)、右移ShiftRight(>>)。

三、数组

(1)数组名也是一变量名,定义时须指定类型和长度。

(2)长度可以方括号中直接指定,也可以通过赋值来间接指定。

(3)数组可以在定义时直接赋值,也可以定义时不赋值,之后再赋值。

(4)当使用超出范围的值时,编译不出错,但运行会出错。(上例运行时出错后,选“忽略”后得到的结果)

数组的地址

弄清数组地址对使用数组有很大好处,另外,有的函数的参数是指针(如scanf函数),如果要用数组的某一元素作参数,就必须知道其地址。


1.数组iArr是int类型,所以它的地址是按4字节递增。

2.数组cArr是char类型,所以它的地址是按1字节递增。

3.数组元素的地址是通过数组元素前面加“&”来取得。(如:&iArr[3])

4.数组名单独使用时,代表该数组的首地址。(iArr等同于&iArr[0])(注意:以后使用指针会经常用到这一点)

四、字符数组和字符串的重定义

字符数组就是字符串吗?有人说是,因为书上这么写,教师也这么教的。小雅不敢说书上或教师们错了,但至少可以说许多初学者都混淆了这两个概念。因此,在这此将这2个概念再明确一下。

1.字符数组,完整地说叫字符类型的数组。字符数组不一定是字符串。

2.字符串是最后一个字符为NULL字符的字符数组。字符串一定是字符数组。

3.字符数组的长度是固定的,其中的任何一个字符都可以为NULL字符。

4.字符串只能以NULL结尾,其后的字符便不属于该字符串。

5.strlen()等字符串函数对字符串完全适用,对不是字符串的字符数组不适用。


从上面例子看来,还要注意以下几点:

(1)char sArr[] = "quanxue";这种方式,编译时会自动在末尾增加一个NULL字符。

(2)NULL字符也就是'\0',在ASCII表中排在第一个,用16进制表示为0x00。

(3)sizeof()运算符求的是字符数组的长度,而不是字符串长度。

(4)strlen()函数求的是字符串长度,而不是字符数组。它不适用于字符串以外的类型。

(5)char sArr[] = "quanxue";也可以写成char sArr[8] = "quanxue";(注意:是8而不是7)

字符数组和字符串数组的转化

字符数组中插入一个NULL字符,NULL字符前面(包括NULL字符)就成了字符串,一般NULL字符插在有效字符的最后。


数组的输入输出『gets(),puts()』

getchar()和putchar()函数是单个字符的输入输出,gets()和puts()是字符串的输入输出,也是标准函数,在stdio.h中被定义。

五、指针

指针符号『*』和地址符号『&』

『&』符号是取变量的地址,『*』符号是取地址的内容(即:值)。两个操作正好相反。例如:“&i”就是取变量i的地址,“*(&i)”就是取“&i”这个地址的值,其实就是变量i。既然如此,为什么还要定义指针呢?原来,用『&』所取到的地址,自身只能用而不能修改。因此,直接把『&』取到的地址放到指针变量中去,既然指针变量也是变量,这个变量就可以任意存放其它地址。


指针变量的赋值和指针的赋值

上例中p是指针变量,*p是p的指针,p存放的是某个变量的地址,*p存放的是某个变量的值。当*p的内容改变时,p所指的变量的内容也发生改变,因为是同一个地址的存贮单元的值发生改变。同理,当p所指的变量的值发生改变时,*p的内容也随之改变。


被初始化的是指针变量还是指针

上面2例,指针变量都是用的p,初学者不要认为只能用p,既然是变量,只要不违反命名规则都可以。当指针变量被定义时立即赋值,这时被赋值的是指针变量还是指针呢?下面这段程序请大家千万注意!


(1)charstr[] ="http://www.quanxue.cn/";中str是数组变量,当地址赋给point之后,point[11]就是str[11],所以其内容可以改变。

(2)char*ptr ="http://www.51minge.com/";中赋值的性质和上面的str不同。这并不是将"http://www.51minge.com/"赋给*ptr指针,而是先定义一个常量"http://www.51minge.com/",这个常量是定义在“栈”里面,然后将这个常量的地址赋给ptr,而不是*ptr。常量是不能被修改的,因此ptr[13]也就出错了。这是初学者经常犯的错误。


不赋值的指针和NULL

未赋值的指针变量是不能被使用的,其地址指向未不能使用的空间。建议定义时如果暂不使用,先赋NULL。为一个指针申请空间时,一定义要判断其是否为空,因为分配内存失败时返回NULL。不仅如此,甚至在使用指针时都应该判断一下是否为空。


六、指针、数组和字符串

一、数组和指针的关系

下面仍然是初学者容易搞错的地方。指针变量加n或减n,并不是地址加n或减n,而是当前所指的地址向后或向前跳n次所指的地址。


char型的指针数组相当于二维字符数组,并不等于说指针数组可以直接转化为二维字符数组,相反字符数组可以直接转化为指针数组。因为二维字符数组的地址是连续的,而指针数组所指的元素不一定连续(如下的m1、m2、m3的地址可以不连续,长度也可以不一样)。


三、指向指针的指针

在第一章讲main()函数的参数时,已经见过指针的指针,这和指针数组有相同的作用,但还是有细小的区别。指针数组可以在定义时直接初始化,而指向指针的指针不行。正如二维数组一样,不指定第二维长度不能直接初始化一样。即不能char str[][]={"...", "...", ...}


四、指针的长度

让许多初学者遗憾的是,C语言没有提供数组长度的函数,但可以用sizeof()运算符先求数组的总长度,再求出数组类型的长度,二者相除便得到数组的长度。C语言更大的一个遗憾便是,sizeof()对指针变量求值时,结果总是4,这是因为指针变量的内容是地址,地址总是4个字节来表示。

因此有经验的编程人员,在用指针作参数时,一般总是同时多定义一个参数,来存放其长度。也就是指针和其长度同时传递过去。另外,数组长度如果事先知道,一般定义为常量。


七、为指针动态分配内存

C语言程序员要严防内存泄漏,这个“内存泄漏”就是由动态内存分配引起的。指针是C语言和其它语言的最大区别,也是很多人不能跨入C语言的一道门槛。既然指针是这么一个“危险”的坏东西,干吗不取消它呢?

其实指针本身并没有好坏,它只是一种操作地址的方法,学会了便可以发挥其它语言难以匹敌的功能,没学会的话,只能做其它语言的程序员,也同样发挥你的光和热。小雅本人也在C语言门外徘徊多年,至今仍属于初学者。


一、变量和数组可以通过指针来转换

“int*x”中的x究竟是不是数组?光看这一句小雅无法告诉你,因为它既可表示单个变量内容,也可表示数组。下面是小雅专门为你准备的例子,理解之后,对动态分配时长度计算有好处。


二、动态分配内存

前面讲到的指针,基本上将已经定义好的变量的地址赋给指针变量,现在要学的是向操作系统申请一块新的内存。申请到的内存,必须在某个地方手动释放,因此下面2个函数必须配对使用。malloc()和free(),都是标准函数,在stdlib.h中定义。

根据不同的电脑使用状况,申请内存有可能失败,失败时返回NULL,因此,动态申请内存时,一定要判断结果是否为空。malloc()的返回值类型是“void *”,因此,不要忘记类型转换。(许多人都省略了。)


三、隐蔽的内存泄漏

内存泄漏主要有以下几种情况:

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

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

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

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

(5)释放了内存却继续使用它。

下面的程序造成内存泄漏,想想错在何处?如何修改?


四、对动态内存的错误观念

有人对某一只在函数内使用的指针动态分配了内存,用完后不释放。其理由是:函数运行结束后,函数内的所有变量全部消亡。这是错误的。动态分配的内存是在“堆”里定义,并不随函数结束而消亡。

有人对某动态分配了内存的指针,用完后直接设置为NULL。其理由是:已经为NULL了,这就释放了。这也是错误的。指针可以任意赋值,而内存并没有释放;相反,内存释放后,指针也并不为NULL。

八、return和exit、assert的区别

return语句是结束当前函数。而exit是结束main()函数,即整个程序,一般都是在遇到非常错误时才调用exit()。assert()是一个宏定义,在assert.h中申明,用来在DEBUG方式诊断程序,当参数中的条件不成立时,中断main()函数。建议多多使用assert()。


九、变量和函数

在函数之外定义的变量是全局变量,在函数内定义的变量是这个函数的局部变量。局部就是只能在当前函数内使用,而全局变量可以在任何一个函数中使用。

注意:一般而言,全局变量总是在所有函数之前定义,但如果某全局变量定义在两个函数之间,则定义出后面的函数可以使用,而且前面函数不能使用。

有人说静态变量相当于全局变量,这句话其实不对。全局变量变成静态,就失去了静态的意义,因此,静态一般是加在局部变量上的。那么,究竟什么是静态的局部变量呢?静态变量随函数的定义而定义,如果已经存在就延用,但并不随函数的结束而消亡。在某一函数中定义的静态局部变量,不能在其它函数使用。

当很多人编写同一程序时,一般程序会被分割成几个文件。当几个人都定义了某一全局变量时,编译时不出错,Link时将出错。解决这个问题的办法:将其中一个定义原封不动,其余的定义前加上extend(即外部的定义)。

刚才所说是许多书上说的,小雅做了n次试验,证明上述编译时也不错,Link时也不错,也就是说extend完全是多余的。大概上面所说是几十年前的版本吧。事实上与extend同列在一起的还有auto、regist等变量修饰符。auto是区别B语言的,早就没用了,regist是将变量放到寄存器来运算,小雅认为基本没有这种需要。

拆成多个文件,多次定义全局变量时要注意:

(1)变量的数据类型要一致。

(2)有长度的数组和没定义长度的数组可以视为同一数据类型。

(3)数组和指针不能视为同一数据类型。

文章就分享到这里了,希望对大家有帮助!

原文链接:https://www.cnblogs.com/lisuyun/p/3974066.html

自学C/C 编程难度很大,不妨和一些志同道合的小伙伴一起学习成长!

C语言C 编程学习交流圈子,关注 私信【C/C 编程】C语言编程学习基地

有一些源码和资料分享,欢迎转行也学习编程的伙伴,和大家一起交流成长会比自己琢磨更快哦!


  • soul图片瞬间怎么删除(视频和文字也是这样删除吗)
  • 2024-09-29视频和文字也是这样删除吗打开手机,进入soul客户端并登陆账户,切换页面至【自己】在自己的界面,找到需要删除的视频瞬间点击进入点击视频瞬间右上角的三点,并点击【删除】,出现提示框后点击【确认】即可删除打开自己的界面,点击想要。
  • 高压锅盖子打不开(高压锅盖子打不开的原因)
  • 2024-09-29高压锅盖子打不开的原因把水杯倒过来,用手在被子底部猛拍几次,然后再用劲拧;把杯子放在冷水里面,泡两三分钟,很容易就拧开了;找一个比较薄的东西,沿着水杯盖和水杯之间的缝隙,稍微撬一下,让冷空气进入,就能打开水杯盖了;找一块棉。
  • 周杰伦最喜欢他的哪首歌(周杰伦都给谁写过歌)
  • 2024-09-29周杰伦都给谁写过歌天王周杰伦在成名前也曾为了生计,给许多前辈写歌的经历,当然就算后来成了名他也依旧会给很多同行写歌,今天来看看都有谁有幸让周董给他写过歌1.李玟《刀马旦》周杰伦作曲,方文山作词,周杰伦和方文山很早的时候。
  • 雅人四好指什么(古代雅人四好指什么)
  • 2024-09-29古代雅人四好指什么古代所说的“雅人四好”都指:弹琴(多指弹奏古琴)、弈棋(大多指围棋和中国象棋)、书法、绘画是文人骚客(包括一些名门闺秀)修身所必须掌握的技能,故合称琴棋书画,即“文人四友”琴:笛子、二胡、古筝、萧、鼓。
  • 保卫萝卜3集市第22关过关攻略(保卫萝卜3集市第21关怎么过)
  • 2024-09-29保卫萝卜3集市第21关怎么过保卫萝卜3集市第21关一共14波,怪物的移动速度超级快,所以小伙伴们要格外小心哦接下来一起看看集市第21关怎么过首先两边放鱼刺,升到二级,然后各放一个冰冻星减速根据小怪的位置移动炮塔记住一定要在空余的。
  • 小学三年级作文巨无霸蚂蚁(小学生同步优秀作文)
  • 2024-09-29小学生同步优秀作文蚂蚁曹范中心小学五年级3班谢俊琦蚂蚁是一种勤劳团结的小动物我们这地方的蚂蚁主要是黑蚂蚁,长约1厘米,身体分为头、胸、腹三部分,有六条腿它们是群居昆虫,一个蚁群中分为不同的成员,有蚁后、雄蚁、工蚁、兵蚁。
  • 王一博演的吴奕辰(官宣时代2定档24日)
  • 2024-09-29官宣时代2定档24日自从忙完了上一部电影《维和防暴队》之后,王一博肖战大部分时间都在北京为接下来的行程做准备本来大家都以为他在为已经官宣的综艺节目《这就是街舞四》忙碌着,谁知道这个时候他却低调干大事,为大家献出了新的惊喜。
  • 含有娜字的网名昵称(含有娜字的网名网名介绍)
  • 2024-09-29含有娜字的网名网名介绍娜娜的印记、婀娜印象、娜样年华不堪留、娜年的花开过了、蒙娜丽莎、娜些时光、雅典娜女神、蒙娜丽莎的微笑、依云柳娜、语嫣思娜、向薇幻娜、思萱若娜娜夜、黑暗酷娜、娜娜の谎言、沙扬娜拉、娑娜酱的蜜汁操作、简单。
  • 抖音老板是梁汝波(梁汝波卸任抖音公司法定代表人及经理)
  • 2024-09-29梁汝波卸任抖音公司法定代表人及经理出品|搜狐科技编辑|黄小芳2月25日消息,企查查APP显示,抖音短视频创始人梁汝波不再担任北京微播视界有限公司的法定代表人,并卸任执行董事、经理职务,由任利锋接任去年11月,梁汝波接替张一鸣担任字节C。
  • 非编系统排名(非编系统的发展和相关国内非编品牌)
  • 2024-09-29非编系统的发展和相关国内非编品牌非编系统又称为非线性编辑系统只要你从事影视传媒行业,就离不开非编系统只要你是剪辑师特效师你每天就会用到非编系统在以前,我们按照接口把非编系统分为专业非线性编辑系统和广播级非线性编辑系统非编系统能到达到。
  • 酒店怎样做能赢得更多顾客(怎么让酒店获得更多的顾客呢)
  • 2024-09-29怎么让酒店获得更多的顾客呢酒店的诚信,诚信是基本的从业品德,要做到童叟无欺,有什么缺点和问题尽量如实地告诉顾客,毕竟任何东西都不可能是十全十美的,诚信是一个和气生财的基础,酒店的促销,在销售淡季,或者店里人气不足时,可采取的方。
  • 面部紧致提升抗衰手法(北大教授科普面部抗衰更有效的手段)
  • 2024-09-29北大教授科普面部抗衰更有效的手段面部衰老是人们不可回避的问题,40岁左右年龄的基础代谢率已从鼎盛时期明显开始下滑,即使是进行各种运动,包括节食,也会在相应的部位出现松弛及脂肪坠积例如面部三沟的出现,腰腹脂肪的堆积等如何能很好的改善衰。