C语言笔记

一、C语言的特点
优点:代码量小,功能强大,速度快
缺点:危险性高(C语言会将一些不是特别错误的也会允许通过),开发周期长(开发 的周期,架构会很长),移植能力差(一个系统到移植到另一个系统,可能会报错,或 者系统不支持)
二、C语言编程预备知识
1.Hello world是如何运行起来的?
当写完程序后其实就像文本里输入了一行数字一样,计算机识别不了,可是通过编译软件比如说(dev++)执行编译后,会把执行该程序的指令发送给操作系统(因为操作系统控制硬件),操作系统会把该消息转移给硬件,硬件CPU接收消息后把该数据处理成计算机可以看懂的数据,二进制,返给操作系统,操作系统转移给显卡,然后进行运算,输出编译后字符
2.什么是数据类型?
整数:没有小数的数
短整型(short int) 大小为2字节
整形(int) 大小为4字节
长整型(long int) 大小为8字节
浮点数【实数】
单精度浮点数(float) 大小为4字节
双精度浮点数(double) 大小为8字节
字符
char 大小为1字节
复合类型数据:把基本类型拼凑在一起就组成了复合类型数据
结构体:java已经没有了
枚举:
共同体:淘汰了
3.什么是变量?
变量的本质就是内存上的存储空间,将一个数赋值给变量后,变量会寻找内存一个空闲的内存位置来充当存储空间,将该数值存储到里面。使用变量时其实使用的是变量中存储的值,也就是之前赋给变量的数值。(比如说我用dev++定义一个i变量,dev++软件会向操作系统请求一个存储空间,操作系统向内存找一个没有使用的内存空间给变量i来存储数据)
4.变量为什么必须的要初始化?
初始化就是赋值,变量如果不进行赋值的话,编译软件会给该变量赋给一个软件指作者编译的程序,因为操作系统分配给的内存空间中还残留着上次使用者的垃圾数据,所以必须要初始化(内存中不存在完全空的空间,只有0或者1)
5.如何定义变量
数据类型 变量名 = 数值 ;
等价于 数据类型 变量名 ;
变量名 = 数值 ;

举例: int i = 10 ;
等价于 int i ;
i = 10 ;
三、进制转换
二进制(B) 八进制(O) 十进制(D) 十六进制(H)
printf的用法:%d十进制 %x十六进制 %o八进制
四、常量在C语言中的表示
整数
十进制: 传统的写法
十六进制: 前面加0x或者0X
八进制: 前面加0 零

浮点数
传统的写法
float x = 3.2 ;
科学计数法
float x = 1.1e3 ; //输出等于1100
字符
单个字符用单引号
‘a’单引号括起
‘ab’错误
“ab“正确
字符串要用双引号
“a“也是正确的
五、常量是以什么样的二进制代码存储到计算机里?
整数是以二进制转换存储到计算机里
实数是通过IEEE754标准转换成二进制存储到计算机中
字符是通过对应ASCII码转换成整数,然后把整数转换为二进制存储到计算机中
六、代码规范化
主要分为三部分,定义变量,操作程序,返回值,每个部分之间要有回车
主要凸显出自己在做什么,注意空格,缩进在程序内容中应该有缩进
七、什么是ASCII码
ASCII码不是数值,而是一种规定,规定了每个字母或者字符所代表的十进制数值,比如规定了
‘A’ – 65 ‘B’ – 66 ……
八、字符的存储
基本的输入和输出函数的用法:
printf() //定义变量后在存储进去,然后进行输出
1.printf(“字符串”)
2.printf(“输出控制符”,输出参数) //输出控制是因为变量里是存储的二进制,输出控制符要定义代码的输出格式
3.printf(“输出控制符1 输出控制符2”,输出参数1,输出参数2)
%d ——int 十进制
%ld ——long int 十进制
%c ——char 字符
%f ——float 单精度浮点数,存储4字节
%lf ——long float 双精度浮点数,存储8字节
%x(或者%X后者%#X) ——int,long int,short int十六进制整数,带#是显示(0x数值),大写X是输出数值为整数
%o ——同上 八进制整数

scanf() //有交互功能,在输出后使用键盘输入内容再进行输出
用法:
1.格式:scanf(“输出控制符”,输出参数);
功能:与键盘产生交互式的作用,可以将键盘输入的内容存储到变量中并直接输出
2.格式:scanf(“非输出控制符 输出控制符”,输出参数);
功能:与键盘产生交互式的作用,可以将键盘输入的内容存储到变量中并直接输出
但是输入时必须要把非输出控制符也要输入进去,否则错误。
3.格式:scanf(“输出控制符 输出控制符”,输出参数,输出参数);
功能:可以一起同时与键盘交互多个变量值,将键盘输入的内容赋值到变量中,但是注意,输入参数时需要按照输出控制符之间的字符来决定输入内容,例如:输出控制符与输出控制符之间有空格就要输入空格,有逗号就要输入逗号。
九、运算符
算术运算符
+ - * /(除号) %(取余数)

关系运算符
> => < =< !=(不等于) ==(等于)

逻辑运算符
C语言对真假的处理,非零是真,零是假,真是用1表示,假是用0表示、
!(非) &&(并且) ||(或)
!(非)真 是假
!(非)假 是真

真&&真		是真
真&&假		是假
假&&真		是假
假&&假		是假

&&(并且)在运行时,左边表达式为假时,右边表达式就不再执行

真||真		真
真||假		真
假||真		真
假||假		假

||(或)在运行时,左边的表达式为真时,右边的表达式就不再执行

赋值运算符
= -= /= *= +=

优先级别
算数 > 关系 > 逻辑 > 赋值
自增[或者自减]
分类:
前自增 —— ++i
后自增 —— i++
前自增与后自增的异同:
结果都是加1
不同:前自增总体的值是i+1之后的值
而后自增的总体的值是i+1之前的值
三目运算符:
格式:
A ? B : C
等价于:
if(A)
B;
else
C;
逗号表达式
格式:
int(A, B, C, D)
功能:
先执行A后执行B顺序执行,最后执行D
十、流程控制
1.什么是流程控制?
流程控制就是代码执行的顺序
2.流程控制的种类
顺序执行

选择执行
定义:某些代码可能执行,也有可能不执行,选择执行某些代码
类型:

  1. 最简单的用法
    格式:
    if (表达式)
    语句
    功能:
    如果表达式为真,则执行语句
    如果表达式为假,则不执行语句
    C语言中,值大于0则是真,小于或者等于0则是假

  2. if的范围用法
    a)if默认只能控制一个语句的输出结果

b)if默认只能控制一个语句的输出结果,可是如果想控制多条语句,必须用大括号括起来{}

  1. if…else…的用法

  2. if…else if…else…的用法
    格式:
    if(1)
    printf(A);
    else if(2)
    printf(B);
    else if(3)
    printf(C);
    else
    printf(D)
    解释:如果1成立输出A,如果1不成立2成立则输出B,如果2不成立3成立则输出C,如果都不成立则输出D

  3. C语言对真假的处理
    真用1表示 假用0表示
    非零是真 0或小于0是假

  4. if举例——求分数的等级

  5. if的常见问题解析
    a) 空语句的问题
    if (1>2);
    等价于
    if (1>2)
    ; //这是一个空语句
    循环执行
    for 命令
    定义
    某些代码会被重复执行
    分类
    for(使用最多)(for的默认范围也只是包括一个)
    格式:
    for ( 1; 2; 3)
    A;
    运行顺序:先运行1后运行2再运行A再运行3,注意:1只运行一次, 2一般代表的是范围,3代表的是加值,A代表的是输入值。
    例子:

    强制类型转换:
    格式:
    (数据类型)(表达式)
    功能:
    把数据类型后的数值强制转化为标记数据类型的数值
    例子:
    (int)(1.1+3.2)//得出结果为4
    (float)(5)//得出的结果为5.00000

试数步骤举例

for循环中不可以使用浮点型数作为自增数字,浮点数会因为算法导致末尾小数的不准确
for循环的多层嵌套

  1. for(1; 2; 3)
    for(4; 5; 6)
    A;
    先执行1再执行2,2判断成立后执行4,再执行5,5成立后执行A,再执行6,再执行5,不成立执行3,再执行2,判断成功后执行4,重复循环
  2. for(1; 2; 3)
    for(4; 5; 6)
    A;
    B;
    这属于两个语句,因为for默认只包含一个语句,所以包含A但是不包括B
  3. for(7; 8; 9)
    for(1; 2; 3)
    {
    A;
    B;
    for(4; 5; 6)
    }
    这也是只有一个语句。

while
执行顺序
while(表达式)
语句;
表达式成立执行语句,再执行表达式,成立继续执行,不成立则终止

与for的相互比较
可以相互转换
for (1; 2; 3)
A;
等价于
1;
while (2)
{
A;
3;
}
举例
菲波拉契序列,回文数转换

do…while
格式:
do
{
……
}while(表达式)
do…while并不等价于for当然也不等价于while
功能:主要用于人机交互
Switch
switch
{
case (表达式):
语句;
break;(结束句)
default :(语句);
break;(结束句)
}
具体案例在(switch用法中看到)
Break和continue
break
主要用来循环中,终止循环
break如果用于switch则是用来switch
break不能直接用于if,除非是if中的一个子句
for (i=1; i<=4; ++i)
{
if (2 > 1)
{
printf(“你最棒!!!”);
break; \虽然是if内部的语句,但是也是终止的是外围的for循环
}
break只能终止离他最近的循环,在多层循环中
for (i=1; i<=4; ++i)
{
for (j=1; j<=4; ++j)
break;
printf(“哈哈哈,我是天下第一帅\n”);
}
coutinue
格式:
for (1; 2; 3)
{
A;
B;
coutinue;//按顺序执行到这里后,会跳过C,D,直接执行3
C;
D;
}
功能:跳过本身存在以后的语句
十一、数组
为什么需要数组
为了解决同类型数据的多数存储
为了模拟现实世界
数组的分类
一维数组
怎样定义一个一维数组?
为n个变量连续分配存储空间
所有的变量数据类型必须一致
所有变量所占的字节大小必须相同
例子:
一维数组名不代表数组中所有的元素
一维数组名代表数组第一个元素的地址
初始化:
完全初始化
Int a[5] = {1,2,3,4,5};
不完全初始化,不被初始化的值都是零
Int a[5] = {1,2,3};
不初始化,所有的元素都是垃圾值
Int a[5];
清零
Int a[5] = {0};
A数组的值与B数组的值互换
Int a[5] = {1, 2, 3, 4, 5};
Int b[5];
Int I;
for [i=0, i<5, ++i]
b[i]=a[i];
二维数组

多维数组

十二、函数
为什么需要函数?
函数可以解决大量同类型的问题,避免了重复性操作,有利于程序的模块化
什么叫函数?
逻辑上:能够完成独立功能的代码块
函数相当于一个工具,是为了解决大量类似问题而设计的函数,函数可以当作一个黑匣子,只通过数据,不研究数据的来源或者过程。
怎么定义函数?
函数的返回值 函数的名称(函数的形参列表)
{
函数的执行体
}

  1. 函数定义的本制是详细描述函数之所以能够实现某个特定功能的具体方法
  2. return表达式的含义:
    a) 终止被调函数,像主函数返回表达式的值
    b) 如果表达式为空,则只种植函数,不向主调函数返回任何值
    c) break是用来终止循环和switch的,renturn则是用来终止函数的
    例子:
    例一:
    int i()
    {
    return 10; //输出结果返回的值为10
    }
    例二:
    int i()
    {
    int i;
    for (i=0; i<5; ++i)
    {
    printf (“大家好”);
    return 0; //用来终止函数,所以后面的我很开心就不会输出
    }
    printf (“我很开心!!!”);
    }
  3. 函数的返回值类型,如果函数名前的返回值类型,与函数的执行体内的return的返回值类型不一样的话,按函数名前的返回值类型进行执行。
    例:
    int i()
    {
    return 10.5 ; //函数的返回值类型为int
    //所以返回值为10不是10.5
    }
    函数的类型
    有参函数 和 无参函数
    表达式有void则是无参函数,反之亦然
    有返回值函数 和 无返回值函数
    在函数的执行体有返回值则是有返回值,反之亦然
    库函数 和 用户自定函数
    库函数:系统自带的
    用户自定函数是自己定义的函数
    值传递函数 和 地址传递函数
    普通函数 和 主函数(main)
    一段程序内必须有且只能有一个主函数
    主函数可以调用其他普通函数,可是普通函数不能调用主函数
    普通函数可以相互调用
    主函数是程序的入口也是程序的出口
    注意的问题
    函数调用和函数定义的 顺序?
    如果函数调用写在了函数定义的前面,必须要加函数前置声明,
    函数前置声明的作用:
  4. 告诉编译器即将可能出现的若干个字母代表的是一个函数
  5. 告诉编译器即将可能出现的若干个字母代表的函数的返回值和形参、名字以及具体情况
  6. 函数前置声明是一个语句,必须要加分号
  7. 库函数的声明必须要用include<库函数所在文件的名字.h>来实现的
    形参和实参?
    个数相同:定义几个形参,对应的就要输入几个实参。
    位置一一对应:位置应该与其一一对应,怎么定义形参就怎么定义实参。
    数据类型必须相互兼容:数据类型比如说int必须输入的也是整数,而float输入的也必须是实数。
    如何在软件开发中合理的设计函数来解决实际问题?
    一个函数的功能尽量独立,单一
    多模仿牛逼大佬的代码来敲。
    函数是C语言的基本单位,类是C++和java和C#的基本单位
    常用的系统函数
    书籍:
    机械工业
    Turboc 2.0实用大全
    十三、递归

十四、变量的作用域和存储方式
按照作用域分:
使用范围:程序从开始到结束都可以使用
全局变量
在所有的函数外部定义的变量称为全局变量
int k = 1000;
int main(void)
{
printf (“%d”,k);
}
// k就是全局变量,在任何函数中都可以使用
适用范围:只可以在一个函数中的声明中使用
局部变量
在一个函数内部定义的变量或者形参,都统称为局部变量
void max(int i)
{
int j = 10;
}
// i和j都属于局部变量
全局变量和局部变量冲突时,全局变量会把局部变量屏蔽掉。
按变量的存储方式:
静态变量
自动变量
寄存器变量
十五、指针
CPU与内存之间的通信
CPU与内存之间有三根线,分别是数据线,控制线和地址线
控制线:控制数据传输的方向
数据线:进行数据的传输
地址线:确定CPU是对内存上的哪个单元进行控制

指针与指针变量的不同?
指针就是地址,地址就是指针
地址就是内存单元的编号
指针变量是存放地址的变量
指针和指针变量是两个不同的概念
但是要注意,我们简述时会把指针变量简称为指针,可是两个的概念不同
指针的重要性:
表示一些复杂的数据结构
快速的传递数据,减少了内存的耗用
使函数返回一个以上的值(之前是默认返回一个值)
可以直接访问硬件信息,比如获取内存条的储存程序代码地址
能够方便的处理字符串
是理解面向对象语言中引用的基础
总结:C语言中的灵魂是指针
指针的定义
地址
内存单元的编号
从0开始的非负整数
范围:0 – 4g - 1
指针
指针就是地址,地址就是指针
指针变量就是存放内存单元编号的变量,或者说指针变量就是存放地址的变量
指针和指针变量是两个不同的概念
但是要注意:通常我们叙述时会把指针变量简称为指针,实际他们含义并不一样
指针的本制就是一个操作受限的非负整数
(地址可以相减,但是不可以乘除加)
指针的分类
1.基本类型指针
int main (void)
{
int * p; //p是变量的名字,int 是表示p变量存放的是int类型变量地址
//int * p不是定义了一个
p的变量名
//int * p应该是这样理解:p是变量名,int *是p变量的数据类型
// 所谓int *数据类型,就是存放int变量地址的类型

int i = 3;
int j;

p = &i;
/*
1. p保存了i的地址, 因此p指向i
2. p不是i,i也不是p,更准确的说: 修改p的值不影响i的值,修改i的值也不会影响p的值
3. 如果一个指针变量指向了某个普通变量, 则
		*指针变量  就完全等同于  普通变量
   例子:	
		如果p是个指针变量,并且p存放了普通变量i的地址
		则p指向了普通变量i
		*p 	就完全等同于 i
		或者说:  在所有出现*p的地方都可以替换成i
				 在所有出现i的地方都可以替换成*p				

        *p 就是以p的内容为地址的变量
*/
j = *p;

printf ("%d %d", i, j);

return 0;

}
的含义:
1.乘法:1
2
2.定义指针:int * 为指针变量
Int * p
//定义了名字为p的变量,int *表示只能存放int类型变量的地址。
3. 指针运算符 j = * p
//该运算符放在已经定义好的指针变量的前面,如果p是一个已经定义好的指针变量,则 * p表示以p的内容为地址的变量
如何通过被调函数,来修改主调函数普通变量的值
void g(int *p, int *q)
{
*q = 10;
*p = 20;
}

int main (void)
{
int a = 3, b = 5;
g(&a, &b);
printf ("%d,%d",a,b);
return 0;
}
1. 实参必须为普通变量的地址
2. 形参必须为指针变量
3. 在被调函数中通过
*形参名 = ……
的方式就可以修改主调函数相关变量的值
2.指针和数组
指针和一维数组
一维数组名
一维数组名是个指针常量
它存放的是一维数组第一个元素的地址
int a[5]; //a是数组名,5是数组元素的个数 元素就是变量 a[0] - a[4]
printf ("%#X\n",&a[0]); //输出结果: 0X62FE00
printf ("%#X\n",&a); //输出结果:0X62FE00
下标和指针的关系
如果p是个指针变量

			确定一个一维数组需要几个参数[如果一个函数要处理一个一维数组]
					需要两个参数:
							数组第一个元素的地址
							数组的长度
		指针变量的运算
						指针变量不能相加,相乘,相除,只能相减。
						如果两个指针变量指向的是同一块连续空间中不同的存储单元
						则两个指针变量才可以相减
		一个指针变量到底占几个字节
								sizeof(数据类型)
								功能:返回值就是该数据类型所占字节数
					32位系统:			
						假设p指向char类型变量(1个字节)
						假设q指向int类型变量(4个字节)
						假设r指向double类型变量(8个字节)
						P q r本身所占字节数是否一样?
							答案:p q r本身所占字节数是一样的
							总结:一个指针变量,无论它所指向的变量类型字节大小
									 该指针变量本身只占四个字节
										
									 一个变量的地址是用该变量的首字节来表示的
					64位系统

64位的指针为八字节,因为32位的地址总线位32根,而64位系统的地址总线位64位,所以该64位在内存中地址编码的大小为8字节。
动态内存分配【重点】
传统数组的缺点

  1. 数组长度必须先定义,且必须是常整数
    int a[5]; //可以
    int len = 5; int a[5]; //不可以

  2. 传统形式定义的数组,该数组的内存程序员无法手动释放,在一个函数运行期间,系统为该函数中数组分配的空间会一直存在,知道该函数执行完毕时,数组所占的空间才会被系统释放。

  3. 数组的长度一旦被定义就不可以变化
    数组的长度不能在函数运行过程中动态的扩充或者缩小

  4. A函数定义的数组,A在运行时其他函数可以被其他函数使用
    但A执行完毕之后,A函数中的数组将无法被其他函数使用
    综上:传统方式定义的数组不能跨函数使用
    为什么需要动态内存分配
    动态数组很好的解决了传统数组的这四个缺陷
    传统数组也叫静态数组
    动态内存和静态内存的区别
    静态内存由系统自动分配,由系统释放的
    静态内存是在栈中分配的

    						动态内存是由管理员手动配置,手动释放的
    						动态内存是堆排序的
    		动态内存分配距离_动态数组的构造
    
    
    		静态内存和动态内存的比较
    
    
    		跨函数使用内存的问题
    

指针和二维数组
3.指针和函数
4.指针和结构体
5.多级指针

结构体
为什么需要结构体
为了表示一些复杂的事物,而普通的基本类型无法满足实际要求
什么叫结构体
把一些基本类型数据组合在一起成为一个新的复合结构类型,这个叫做结构体
如何定义一个结构体
赋值和初始化
定义的同时可以整体赋初值
如果定义完之后,则只能单个赋值
怎样使用结构体变量
赋值和处置话如何取出结构体变量中的每一个成员

  1. 结构体变量名.成员名

  2. 指针变量 -> 成员名
    struct xinxi
    {
    char xingming;
    int nianling;
    float chengji;
    };
    //定义结构体
    int main (void)
    {
    struct xinxi st = {‘C’, 19, 100}; //初始化定义的同时赋值
    struct xinxi * st2 = &st; // &st不能改成* st2 因为类型不同

    st2 -> xingming = ‘H’; //第一种方式
    st.xingming = ‘L’; //第二种方式

    printf ("%c",st.xingming);

    return 0;
    }

  3. st2 -> xingming 在计算机内部会被转换成 (*st2).xingming(硬性规定)

  4. 所以st2 -> xingming 等价于 (*st2).xingming 也等价于 st.xingming

  5. 我们之所以知道st2 -> xingming 等价于 st.xingming,是因为st2 -> xingming,是被转化成了(*st2).age来执行

  6. st2->xingming的含义:
    st2所指向的那个结构体变量中的xingming这个成员
    结构体变量的运算
    结构体变量和结构体变量指针作为函数参数传递的问题
    推荐使用结构体指针变量作为函数参数来传递
    结构体变量的运算
    结构体变量不能相加,不能相减,也不能互相乘除
    但结构体变量可以相互赋值
    举例:
    动态构造存放学生信息的结构体数组
    动态构造一个数组,存放学生的信息
    然后按分数排序输出
    枚举
    什么是枚举
    就是把一个事物所有可能的取值一一列举出来
    样使用枚举
    //只定义了一个数据类型,并没有定义变量, 该数据类型的名字是 enum WeekDay
    enum WeekDay
    {
    MonDay, TuesDay, WednesDay, ThursDay, FriDay, SaturDay, SunDay
    };

int main(void)
{
//int day; //day定义成int类型不合适
enum WeekDay day = SunDay;
printf("%d\n", day);
//输出结果为6
return 0;
}
枚举的优缺点
代码更安全,使代码看起来更直观
补码
源码
也叫 符号-绝对值码
最高位0表示正,1表示负,期与二进制位是该数字的绝对值的二进制

		源码简单易懂
		加减运算复杂
		存在加减乘除四种运算,增加了cpu的复杂度
		零的表示不唯一
		
	反码
		反码运算不变,也没有在计算机中应用
	移码
		移码表示数值平移n位,n成为移码量
		移码主要用于浮点数的阶码的存储
	补码
		已知十进制求二进制
				求证整数的二进制
						除2取余,直至商为零,余数倒叙排列
				求负整数的二进制
						先求与该负数相对应的正整数的二进制代码,然后将
						所有位取反,末尾加1,不够位数时,左边补1,比如
						int类型要32个二进制bit位表示,可是有些数表示

二进制最多占四位二进制,会自动在左边补上1
求零的二进制
全都是零
已知二进制求十进制
如果首位为0,则表明是正整数,按普通方法来求

				如果首位为1,则表明是负整数
						将所有位取反,末尾加1,所得数字就是该负数的绝对值
				求零的二进制
						全为零

位运算符
& – 按位于
&& 逻辑与 也叫并且
&&于& 的含义完全不同
1&1 = 1
0&1 = 0
1&0 = 0
0&0 = 0

						5&7 = 5		21&7 = 5
						5&1 = 1		5&10 = 0
				| -- 或运算符
						||逻辑或
						|按位或
						
						1|0 = 1
						0|1 = 1
						1|1 = 1
						0|0 = 0
				~ -- 按位取反
						~i九十八i变量所有的二进制取反
				^ -- 按位异或
						相同为0
						不同为1
						1^0 = 1
						0^1 = 1
						1^1 = 0
						0^0 = 0
				<< -- 按位左移
						i<<3 表示把i的所有二进制位左移三位
						左移n位相当于乘以2的n次方
						面试题:

A> i = i*8
B> i = i<<3
请问上述两个语句,那个语句执行的速度快
答案:B快
>> – 按位右移
i>>3 表示把i的所有二进制位右移三位,左边一般是0
右移n位相当于除以2的n次方
面试题:
A> i = i/8
B> i = i>>3
请问上述两个语句,那个语句执行的速度快
答案:B快
位运算符的现实意义
通过位运算符我们可以对数据的操作精确到每一位
学习目标
在Vc++6.0中一个int类型的变量所能存储的数字范围是多少
Int类型变量所能存储的最大正数十六进制最大的整数是: 7FFFFFFF
Int类型变量所能存储的绝对值最大的负整数:80000000

绝对值最小负数的二进制代码是多少
最大正数的二进制代码是多少
已知一个整数的二进制代码求出原始的数字
数字超过最大正数会怎样
超过最大正数会溢出,只会保留后面的。
不同类型数据的相互转换
二进制全为0的含义 –000000000000000000 的含义

  1. 代表数值为0
  2. 字符串结束标记符’\0’
  3. 空指针NULL
    NULL表示的是零,而这个零不代表数字零,而代表的是内存单元的编号为零,代表的是地址零

我们计算机规定了,以零为编号的存储单元的内容不可读,不可写
链表
算法:
通俗定义:
解题的方法和步骤
狭义定义:
对存储数据的操作
对不同的存储结构,要完成某一个功能所执行的操作是不一样的
比如:
要输出数组中所有的元素的操作和
要输出链表中所有元素的操作肯定是不一样的
这说明:
算法是依附于存储结构的
不同的存储结构,所执行的算法是不一样的
广义定义:
广义的算法也叫泛型
无论数据是如何存储的,对该数据的操作都是一样的
我们至少可以通过两种结构存储数据
数组
优点:
存取数据快
缺点:
需要一个连续的很大的内存
插入和删除的元素的效率极低
链表
专业术语:
首节点
存放第一个有效数据的节点
尾节点
存放最后一个有效数据的节点
头结点
头结点的数据类型和首节点的数据类型是一摸一样的
头结点是首节点后面的那个节点
头结点并不存放有效数据
设置头结点的目的是为了方便对链表的操作
头指针
存放头结点地址的指针变量
优点:
插入删除元素效率高
不需要一个很大的连续空间
缺点:
查找某个位置的元素效率低

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值