c语言笔记照片_c语言笔记
如何看懂一个程序,分三步
1. 流程
2. 每个语句的功能
3. 试数
对于一些小程序的算法
尝试自己去编程解决它,大部分人都无法自己解决
如果解决不了,尝试看答案
关键要把答案看懂,这个要花很大的精力,也是我们学习的重点
看懂之后尝试自己去更改程序,并且知道修改之后程序的不同输出结果的含义
重要的运算符
举例:
1/2=0 1.0/2=0.5 1/2.0=0.5
1%2=1 2%2=0 n-1% n=n-1
指针
1. 指针就是地址 地址就是指针
2. 地址就是内存单元的编号
3. 指针变量是存放地址的变量
4. 指针和指针变量是两个不同的概念
5. 但是要注意,通常我们叙述时会把指针变量简称为指针,实际上它们含义并不一样
指针的本质就是操作受限的非负整数.
#include
int main(void)
{
int *p; //p是变量的名字, int *表示p变量存的是int类型变量的地址
int i=3;
p=&I; 1.p保存了i的地址,因此p指向i;
2. p不是i,i也不是p,更准确地说修改p的值不影响i的值,修改i的值也不影响p的值.
3.如果有一个指针变量指向了普通变量,则 *指针变量 就完全等同于 普通变量. *p 完全等同于i,或者说:在所有出现*p的地方都可以替换成i,在所有出现i的地方都可以替换成*p
*p就是以p的内容为地址的变量
return 0;
}
指针的重要性:
1. 表示一些复杂的数据结构
2. 快速的传递数据
3.使函数返回一个以上的值
4.能直接访问硬件
5.能够方便处理字符串
6.是理解面向对象语言中应用的基础
总结:c语言的灵魂
指针的定义:
地址:
内存单元的编号
从零开始的非负整数
指针的分类:
1. 基本类型指针
2. 指针和数组
3. 指针和函数
4. 指针和结构诶
5. 多级指针
*的三种含义:
1. 乘法
2.定义指针
Int *p ; // 定义了一个名字叫p的变量,int*表示p只能存放int 变量的地址
3.指针运算符
该运算符放在已经定义好的指针变量的前面
如果p是一个已经定义好的指针变量 则*p表示 以p的内容为地址的变量]
如何通过被调函数修改主调函数普通变量的值
1. 实参必须为该普通变量的地址
2. 形参必须为指针变量
3. 在被调函数中通过
*形参名 =…… 的方式就可以修改主调函数相关变量的值
指针和数组
指针和一维数组
一维数组名是个指针常量,它存放的是一维数组第一个元素的地址
如int a[5] a就是a[0]的地址
下标和指针的关系
如果p是一个指针变量,则p[i]永远等价于 *(p+i)
确定一个一维数组需要几个参数(如果一个函数要处理一个一维数组,则需要接受该数组的哪些信息)
1. 数组第一个元素的地址 即数组名
2. 数组长度
Int a[5]; // a是数组名 5是数组元素的个数 元素就是变量 a[0]~a[5]
Int a[3] [4] // 3行4列 a[0][0]是第一个元素 a[i][j] 第i+1行第j+1列
指针变量的运算
指针变量不能相加 不能相除 也不能相乘
如果这两个指针变量指向的是同一块连续空间的不同存储单元,则这两个指针才可以相减
一个指针变量到底占几个字节
预备知识:
Sizeof (数据类型)
功能:返回值就是该数据类型所占的字节数
Sizeof(变量名)
功能:返回值就是该变量所占字节数例子: sizeof(int) =4 sizeof(char) =1
假设p指向char类型变量(1个字节)
假设q指向int类型变量(4个字节)
假设r指向double类型变量(8个字节)
p q r 本身所占的字节是否一样
一个指针变量,无论它指向的变量占几个字节,该指针变量本身只占四个字节
一个变量的地址使用该变量首字节的地址来表示
动态内存分配
传统数组的缺点:
1. 数组的长度必须事先制定,且只能是常整数,不能是变量(c99之后可以?)
2. 传统形式定义的数组,该数组的内存无法手动释放
在一个函数运行期间,系统为该函数中数组所分配的空间会一直存在,直到该函数运行完毕时,数组的空间才会被系统释放
3. 数组的长度一旦定义,其长度不能再更改,数组的长度不能在函数运行的过程中动态的扩充或缩小
4. A函数定义的数组,在A函数运行期间可以被其它函数使用,但A函数运行完毕之后,A函数中的数组将无法在其它函数中使用
传统方式定义的数组不能跨函数使用.
malloc memory(内存) allocate(分配)的缩写
#include
int * p = (int *) malloc (4);
1. 要使用malloc函数,必须添加malloc.h这个头文件
2. malloc函数只有一个形参,并且形参是整型
3. 4表示请求系统为本程序分配4个字节
4. malloc函数只能返回第一个字节的地址
5. 分配了8个字节,p变量占4个字节,p所指向的内存地址也占4个字节
6. P本身所占的内存是静态分配的,p所指向的内存是动态分配的
free(p)表示把p所指向的内存给释放掉,p本身的内存是静态的,不能由程序员手动释放,p本身的内存只能在p变量所在函数运行终止时由系统释放
为什么需要动态分配内存
动态数组很好的解决了传统数组的4个缺陷
动态数组的构造
#include
int main(void)
{
int a[5] //如果int占4个字节的话,则本数组总共包含20个字节,每4个字节被当作 一个int变量来使用
int len;
int *pArr;
printf(“请输入你要存放的元素的个数:”)
scanf(“%d”,&len);
pArr =(int *)malloc(4* len) //本行动态的构造了一个一维数组,该一维数组的长度是len
return 0;
}
动态内存和静态内存的比较
静态内存是由系统自动分配,由系统自动释放
静态内存是在栈分配的
动态内存是由程序员手动分配的,手动释放
动态内存是在堆分配的
多级指针
#include
Int main(void)
{
Int i=10;
Int *p=&i; //p是int *类型 ,&p是int ** 类型
Int **q=&p;
Int ***r =&q;
因为r是int ***类型,r只能存放 int ** 类型变量的地址
跨函数使用内存
# include
void f(int **q) q是个指针变量,无论q是什么类型的指针变量,都只占4个字节
{
Int i=5;
}
Int main(void)
{
Int *p;
f(&p);
return 0;
}
结构体是根据用户实际需要自己定义的复合数据类型
如何使用结构体
两种方式:
Struct Student st ={1000,”zhangsan”,20};
Struct Student *pst = &st;
1.
St.sid
2.
Pst->sid
Pst所指向的结构体变量中的sid这个成员
注意事项:
结构体变量不能加减乘除,但是可以相互赋值
普通结构体变量和结构体指针变量作为函数传参的问题
#include
#include
struct Student{
int age;
char sex;
char name[100];
};
void InputStudent(struct Student * pstu);
void OutputStudent(struct Student ss);
int main(void)
{
struct Student st;
InputStudent(&st); //对结构体变量的输入
printf("%d %c %s\n",st.age ,st.sex, st.name);
OutputStudent(st); //对结构体变量的输出,可以发送st的地址也可以发送st的内容
return 0;
}
void OutputStudent(struct Student ss)
{
printf("%d %c %s\n",ss.age, ss.sex , ss.name);
}
void InputStudent(struct Student * pstu) //pstu只占4个字节
{
(*pstu).age =10;
strcpy(pstu->name,"张三");
pstu->sex='f';
}
/*
//本函数无法修改主函数st的值,所以本函数是错误的
void InputStudent(struct Student stu)
{
stu.age=10;
strcpy(stu.name,"张三"); //不能写成 stu.name="张三";
stu.sex='f';
}
*/
动态构造存放学生信息的结构体数组
//动态构造一个数组,存放学生信息,然后按分数排序输出
#include
#include
struct Student
{
int age;
char sex;
float score;
char name[100];
};
int main(void)
{
int len;
struct Student * pArr;
int i,j;
struct Student t;
printf(" 请输入学生的个数:\n");
printf("len =");
scanf("%d",&len);
//动态地构造一维数组
pArr =(struct Student *)malloc(len *sizeof(struct Student));
for (i=0;i
{
printf("请输入第%d个学生的信息:\n",i+1);
printf("age=");
scanf("%d",&pArr[i].age);
printf("name=");
scanf("%s",pArr[i].name); //不用加&,因为name是数组名,本身就已经是数组首元素的地址
printf("score=");
scanf("%f",&pArr[i].score);
}
//按学生成绩升序,冒泡算法
for(i=0;i
{
for(j=0;j
{
if(pArr[j].score>pArr[j+1].score)
{
t=pArr[j];
pArr[j]=pArr[j+1];
pArr[j+1]=t; //换位置而不是换成绩
}
}
}
printf("\n\n学生的信息是:\n");
//输出
for (i=0;i
{
printf("第%d个学生的信息是:\n",i+1);
printf("age=%d\n",pArr[i].age);
printf("name=%s\n",pArr[i].name);
printf("score=%f\n",pArr[i].score);
printf("\n");
}
return 0;
}
枚举
什么是枚举?
把一个事物所有可能的取值一一列举出来
怎样使用枚举
#include
//只定义了一个数据类型,并没有定义变量,该数据类型的名字是 enumm 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);
return 0;
}
枚举的优缺点
代码更安全
书写麻烦
进制转换
预备知识:
小数除以大数 商为零 余数是小数本身
十进制转换为r进制
方法
除r取余,直至商零,余数倒序排列
二进制到十六进制
方法: 从左往右,四位一段,分别转化,不够四位的补零
二进制与八进制相互转换
原码:
也叫符号-绝对值码
最高位0表示正 1表示负,其余二进制位是该数字的绝对值的二进制位
原码简单易懂
加减运算复杂
存在加减乘除四种运算,增加了cpu的复杂度
零的表示不唯一
反码
反码运算不便,也没有在计算机中运用
移码
移码表示数值平移n位,n为偏移量
移码主要用于浮点数的阶码的存储
补码
已知十进制求二进制
求正整数的二进制
除2取零,直至商0,余数倒叙排序
求负整数的二进制
先求与该负数相对应的正整数的二进制代码,然后将所有位取反,末位加1,不够位数时,左边补1
求零的二进制
全是零
已知二进制求十进制
如果首位是0,则表明是正整数,按普通方法求
如果首位是1,则表明是负数,将所有位取反,末尾加1,所得数字就是该负数的绝对值
如果全是0,则对应的十进制数字就是0
比方说:十进制中的1用二进制表示就是01,当你二进制转十进制的时候,你需要输入01,系统是自动在01前头补30个0来凑够32位.这是正整数的时候,可是当你是十进制中的-1时,二进制表示时,先取十进制-1的绝对值1的二进制.否则系统会自动给你补30个0,导致二进制的11被认为是正整数3而不是-1
算法:
通俗定义:
解题的方法和步骤
狭义定义:
对存储数据的操作
对不同的存储结构,要完成某一功能所执行的操作是不一样的
比如:
要输出数组中所有元素的操作和要输出链表中所有元素的操作肯定是不一样的,这说明算法是依附于存储结构的,不同的存储结构,所执行的算法是不一样的
广义定义:
广义的算法也叫泛型
无论数据是如何存储的,对该数据的操作是一样的
我们至少可以通过两种结构来存储数据
数组:
优点:
存取速度快
缺点:
需要一个连续的很大的内存
插入和删除元素的效率很低
链表
优点:
插入删除元素效率高
不需要一个连续的很大的内存
缺点:
查找某个位置的元素效率很低
专业术语:
头结点
头结点的数据类型和首节点的类型一模一样
头结点是首节点前面的那个节点
头结点并不存放有效数据
设置头结点是为了方便对链表的操作
头指针
存放头结点地址的指针变量
首节点
存放第一个有效数据的节点
尾节点
存放最后一个有效数据的节点
确定一个链表需要一个参数(头结点的地址)
郝斌老师的09年课程
c语言笔记照片_c语言笔记相关推荐
- c语言笔记照片_C语言学习笔记
一般情况下,在C语言中,函数指针定义时就会说明其指向的函数的参数情况以及返回值类型,比如以下定义: void (*func_p)(int a); 以上代码就声明了一个函数指针func_p,其指向的函数 ...
- c语言笔记照片_C语言入门这一篇就够了-学习笔记
按照之前的计划,这篇文章本该写C语言简介,包括一些历史背景,发展状况, 语言特点什么的,这些东西着实比较啰嗦. 吃饭用的筷子,到现在我都不知道它的由来,不知道它是在什么历史背景下诞生的 有些东西还是有 ...
- c语言笔记照片_C语言基础知识笔记
一.C语言的结构 1.Hello world 简单来说,一个C程序就是由若干头文件和函数组成. #include //包含头文件 /* *主函数 */ int main(){ printf(" ...
- java和c语言的区别_C语言为何不会过时?你需要掌握多少种语言?
关注.星标公众号,不错过精彩内容 整理/排版:付斌 转自:嵌入式ARM 01 为什么C语言不会过时 评价任何一门编程语言,都是招人骂的.永远是这样.就像是春寒料峭的季节, 街上穿棉袄和穿单衣的擦肩而过 ...
- c语言求素数_C语言 | 求100~200的素数
"要成为绝世高手,并非一朝一夕,除非是天生武学奇才,但是这种人-万中无一" --包租婆这道理放在C语言学习上也一并受用.在编程方面有着天赋异禀的人毕竟是少数,我们大多数人想要从C语 ...
- c语言实现通讯录_C语言实现双人猜数字游戏
点击上方"学士科技",选择"设为星标" 资讯.技术干货第一时间送达! C语言合集(基础.进阶.高级)通通有,点我点我 C语言实例 01.C语言编写简单 ...
- window直接运行不需要环境的软件是什么语言开发的_C语言为何不会过时?你需要掌握多少种语言?_C 语言...
01为什么C语言不会过时 评价任何一门编程语言,都是招人骂的.永远是这样.就像是春寒料峭的季节, 街上穿棉袄和穿单衣的擦肩而过,双方一定是同时在心里出现了两个字:"s b!"这个在 ...
- c语言c99标准_C语言的三套标准:C89、C99和C11
我们今天使用的 Windows.Linux.Mac OS 等操作系统都是由一种叫做 Unix 的系统演化而来.Unix 作为80年代主流的操作系统,是整个软件工业的基础,是现代操作系统的开山鼻祖,C语 ...
- java c语言与人工智能_C语言与LISP语言的区别
C语言:C是过程式编程语言.它被设计成使用编译器编译.该语言有少量固定数量的关键字,如if/else,for,while,..等等.我们可以使用一个以上的作业,可以用这种语言在一个语句中使用.函数也在 ...
最新文章
- 使用OpenCV和Python高效计算视频的总帧数
- 万字超强图文讲解 AQS 以及 ReentrantLock 应用
- H3C 交换机S6520X软件版本升级
- sklearn数据集操作API
- ABAP代码自动完成实现原理
- windows10上安装mysql
- 5G iPhone SE即将试产 搭载A15仿生芯片采用4.7英寸屏幕
- MyBatis框架generatorSqlmapCustom自动生成及下载方法
- keras可视化模型训练过程
- c#进销存(1):需求分析
- 峰值性噪比matlab,PSNR峰值信噪比matlab实现
- 小说网站源码_ptcms精美小说阅读网站源码(带采集规则)
- aamp;m大学计算机科学,斑马博士捷报|德克萨斯AM大学 (TAMU) MSc Computer Science录取!...
- 做了7年新媒体人,现在才懂的精细化运营增粉变现秘诀!黎想
- Android 集成高德地图SDK
- (面向对象)员工信息管理系统 1.当有新员工的时候将员工加入到管理系统 2.可以根据工号实现对该员工信息查询 3.可以现实查看所有员工信息 4.可以修改员工的薪水
- mysql8多值索引(Multi-Valued Indexes)使用方法和性能测试
- 【Excel 教程系列第 6 篇】制作斜线表头
- nginx - nginx的安装部署
- php安全新闻早八点-高级持续渗透-第二季关于后门补充一
热门文章
- 地铁译:Spark for python developers --- 搭建Spark虚拟环境 4
- Cannot find module -----Node.js编程的第一个问题
- 在IIS express 下用ajax调用webmethod
- POJ 3498 March of the Penguins
- Microsoft Visual Studio 2008 快捷键
- 解决log4net独占日志文件的问题以及 log4net的各种输出配置(Appender)
- 在Windows 64位下为PHP5.6.14安装redis扩展
- 如何屏蔽PHP浏览器头信息X-Powered-By
- 大道至简第五章阅读笔记
- ActiveMQ 部署及发送接收消息