目录
什么是计算机语言
C语言
计算机语言发展
关于电脑
写C语言代码
初识数据结构
C语言数据类型
计算机中的单位
变量与常量
变量的分类
scanf输入函数与printf输出函数
变量的作用域以及生命周期
关于常量
常量的分类
关于枚举
字符串加转义字符加注释
字符串
转义字符
注释(解释代码)
注释分类
语句
经典分支语句
经典while循环语句
函数
数组
*** 作符
算数 *** 作符
移位 *** 作符
位 *** 作符
赋值运算符
单目 *** 作符
sizeof使用
关于原码反码和补码
补码思想
关系 *** 作符
逻辑 *** 作符
条件 *** 作符(三目 *** 作符)
常见关键字
#define定义常量和宏
1.define定义标识符常量
2.define定义宏
指针
指针的原理
指针的 *** 作
指针占用内存的大小
结构体
什么是计算机语言
计算机语言:人和计算机交流的语言。
C语言是一门通用的计算机编程语言,广泛用于底层软件开发。
C语言是一门有国际标准的语言
计算机语言发展- 二进制语言:0/1这样的序列语言
- 汇编语言:将具有特定功能的0/1序列进行封装,用助记符代替。
- B语言
- C语言
买回来一个电脑,如果想让他工作,应在电脑上装 *** 作系统( *** 作硬件) *** 作系统如果想让电脑硬件工作应在电脑中装硬件驱动。
( *** 作系统调用驱动来促使硬件进行工作)
写C语言代码写代码的工具——编译器
怎么写呢?
- 创建一个项目
- 创建一个源文件
- 写代码
- 编译代码
写主函数(main函数)——C语言是从主函数第一行开始执行的,所以C语言代码中得有主函数,并且只能有一个,不然报错。
printf("hello")——其是一个库函数,用来在屏幕上打印信息,因为其是库函数,因此使用时需要打招呼(引用头文件-stdio.h)#include
运行项目如果出现一闪而过的命令控制台,那么就右键点击项目 -属性-系统 然后将子系统改为控制台 然后应用-确定。
计算机语言-解决生活中的问题那么他必须有能力描述生活中的问题——数据结构
C语言数据类型- char:字符数据类型——1字节
- short:短整型——2字节
- int:整形——4字节
- long:长整型——4字节
- long long:更长得整形——8字节
- float:单精度浮点数——4字节
- double:双精度浮点数——8字节
C语言标准规定sizeof(long)>=sizeof(int)
printf("%d", 100);——格式控制输出语句。
printf("%d",sizeof(char));
sizeof(char)——关键字——计算类型或者变量所占空间的大小单位字节。
- bit——比特位
- byte——字节=8bit
- kb——1024byte
- mb——1024kb
- gb——1024mb
- tb——1024gb
- pb——1024tb
常量:不能改变的量。
变量:能被改变的量。
%d | 整形 |
%p | 打印地址 |
%f | 单精度浮点型 |
%s | 字符串 |
%lf | 双精度浮点型 |
%c | 字符型 |
- 局部变量:在大括号内部定义的变量
- 全局变量:在大括号外面定义的变量
当局部变量与全局变量名字冲突的情况下——局部优先
scanf输入函数与printf输出函数scanf函数:输入函数
格式:scanf("%d %d", &a, &b);——a,b分别为变量
printf函数:输出函数
格式:printf("%d", sum);——sum为变量
scanf函数不能用解决方法:
在源文件第一行加:#define _CRT_SECURE_NO_WARNINGS 1
scanf_s函数:VS编译器提供的,不是C语言标准提供的,不能实现跨平台。
程序设计概念,通常来说,一段程序代码中所用到的名字并不是总是有效的,而限定这个名字的可用性的代码范围就是这个名字的作用域。
局部变量的作用域:变量所在的局部范围
全局变量的作用域:整个工程
全局变量写在方法的最前面并且全局变量定义的名称只能定义一次(范围:在一个源文件中)
变量的生命周期:变量生命周期指的是变量的创建到变量的销毁之间的一个时间段。
局部变量的生命周期:进入局部范围生命周期开始,出局部范围生命周期结束。
全局变量的生命周期:程序的生命周期
在一个源文件中有2个.c文件,其中一个声明了int类型变量a并为其赋了值那么在另一个.c文件中要想使用,应提前声明一下extern int a;(前提:a是整个工程的全局变量)
关于常量常量:不变的量
常量的分类- 字面常量——(eg:‘a'、36……)
- const修饰的常变量(具有常属性的变量)——(eg:const int a=8;)
- #define定义的标识符常量(可以放在任何位置)——(eg:#define MAX 10000)MAX值不可以更改
- 枚举常量——(可以一一列举的常量)
分别以整形的方式打印会得到0,1,2——枚举常量是常量默认的值是从0开始 当然,可以赋初值,但是不可以在外面进行值的改变。
打印会得到3,4,5
如果仅仅female=7,则打印会得到0,7,8
字符串加转义字符加注释 字符串定义:由双引号引起来的一串字符称为字符串的字面值,或者亦称字符串
注意:字符串的结束标志是一个\0的转义字符,在计算字符串长度的时候\0是结束标志,不算作字符串的内容。
单引号包裹的东西是字符常量,双引号里包裹的东西为字符串其能包裹多个字符;
int main() {
char a[] = "abc";
char b[] = { 'a','b','c' };
printf("%s\n", a);
printf("%s", b);
}
打印结果:
原因:字符串的结束标志为\0,b没遇到\0会继续向后打印直到找到\0
求字符串长度
使用前需导入头文件
#include
int len = strlen("abc");
printf("%d\n", len);
最后得出的长度为3,\0是字符串的结束标志,不算做字符串的长度里面
转义字符转变了字符本来的意思常用方法,在字符前加\
转义字符 | 意义 | ASCII码值(十进制) | |
\a | 响铃(BEL) | 007 | |
\b | 退格(BS) ,将当前位置移到前一列 | 008 | |
\f | 换页(FF),将当前位置移到下页开头 | 012 | |
\n | 换行(LF) ,将当前位置移到下一行开头 | 010 | |
\r | 回车(CR) ,将当前位置移到本行开头 | 013 | |
\t | 水平制表(HT) (跳到下一个TAB位置) | 009 | |
\v | 垂直制表(VT) | 011 | |
\ | 代表一个反斜线字符''\' | 092 | |
\' | 代表一个单引号(撇号)字符 | 039 | |
\" | 代表一个双引号字符 | 034 | |
空字符(NULL) | 000 | \ddd | |
1到3位八进制数所代表的任意字符 | 三位八进制 | \xhh | |
1到2位十六进制所代表的任意字符 | 二位十六进制 |
ASCII
在ASCII码表里每个字符都有一个对应值,这个值叫字符对应的ASCII码值
注释(解释代码)- 代码中有些代码比较难懂,可以加一些注释文字
int main() {
int a = 0;
printf("你是否好好学习?(0/1)\n");
scanf("%d",&a);
if (a == 0) {
printf("走上人生巅峰!");
}
else if(a==1) {
printf("回家卖白薯!");
}
else {
printf("请正确输入您的值!");
}
}
1.单行注释(注释一整行)——(//写的代码)
2.多行注释(注释多行)——(/*写的代码*/)
多行注释不支持嵌套注释:遇到第一个注释开头作为注释开头,遇到第一个注释结尾作为注释结尾。
int line = 1;
while (line < 300) {
printf("写代码%d行\n", line);
line++;
}
printf("get offer");
经典while循环语句
C语言中实现循环的方式
- for语句
- do……while语句
int main() {
int a = 0, b = 0;
scanf("%d%d", &a, &b);
printf("%d", add(a, b));
return 0;
}
int add(c, d) {
return c + d;
}
经典函数代码——实现两个数的相加
//这里面中括号的10代表有10个元素,元素下标由0——9
int main() {
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
char ch[10] = { 'a','b','c'};//不完全初始化,剩下的默认为0
printf("%d", arr[0]);
return 0;
}
数组
数组:一组相同类型元素的集合
需求:存储1——10的数字
int main() {
float a = 9 / 2;
printf("%f", a );
return 0;
}
数组访问方式:下标访问
*** 作符 算数 *** 作符符号:+ - * / %
符号说明:
+ ---> 分别用于整数及浮点数的加法
- ---> 分别用于整数及浮点数的减法
* ---> 分别用于整数及浮点数的乘法
/ ---> 分别用于整数及浮点数的除法
% ---> 用于返回两个整数相除的余数
int a = 10;
printf("%d", sizeof a);
printf("%d", sizeof (int));
//sizeof后面可以接变量与类型,当后面接变量的时侯后面的()可省略,但是当后面接类型的时候,后面应加()
最终得到的结果为4.0000,因为算数两边的数均为整形,最终结果为整形,只不过最终用浮点类型进行了接收。
移位 *** 作符
符号:<< >>
符号说明:
左移运算符:用于将整数左移指定位数
右移运算符:用于将整数右移指定位数
<< ---> 算数左移运算符
>> ---> 算数右移运算符
<<< ---> 逻辑左移运算符
>>> ---> 逻辑右移运算符
移位规则:
(左移运算符):不论算术移位还是逻辑移位,均将左边的数舍弃,右边空缺位补0(左边丢弃,右边补0)
(右移运算符):当进行逻辑移位时,右边位丢弃,左边空缺位补0(右边丢弃,左边补0) ;当进行算术移位时,右边位丢弃,左边位补原数的符号位(右边丢弃,左边补符号位)。
&:按位与(1&1==1)
|:按位或(1|任何数==1)
^:按位异或(1^0=1,0^1=1)
赋值运算符a=a+5——a+=5(依次类推)
单目 *** 作符(只有一个 *** 作数的 *** 作符)
sizeof使用int arr[10] = { 0 };
printf("%d", sizeof arr);
//结果为40,计算数组的总大小,单位字节
printf("%d", sizeof arr[0]);
//计算第一个类型的大小——为4
整数在内存中存储的是补码
原因:计算机只会玩加法,做减法的时候就加负数的补码玩
一个整数的二进制表示有3种
原码
反码
补码
补码的创建是针对负数的计算,正整数的原码,反码,补码都相同
补码=反码+1原理剖析
补码思想现在是9点,如果我想调到6点;
9 - 3 -> 6 往前拨3个小时——(-3为源码)
9 + 9 -> 6 往后拨9个小时——(9为补码)
这里称12为模,写作mod12; 称9是-3以12位模的补数,记作 -3≡+9(mod 12)
由于前面9和-3互为补数且是以12为模,此刻我们先抛开负数不提得到9+3=12(反正最后在给任意一个变量加上符号,这两个数便互为补码)
一个 N 位的二进制数,可表示的最大值是2^N-1;
假设存在 x+y = 2^N-1 --> x+y+1 = 2^N;
如果此时把2^N 当做模 --> -x(如今加上负号) 和 y+1 就互为补数;
而x+y = 2^N-1,2^N-1是一个 N 位的二进制数最大的数了(就是各位是1的数),如果x和y相加真要得到这个数那么就两个从各位逐个相加一位是1那么第二个数的该位必定是0,现在我们已经知道了x和y逐个位相反,然而-x与y+1为补码啊,那么由反码定义可知-x与y必为反码。
C语言中加上一个数就等于加上这个数的补数(本质:运算溢出情况)。
在C语言中0表示假,1表示真,当然,正数都表示真。
前置++与后置++
- 后置++(a++):先参与运算,再+1
- []:下标引用
逻辑 *** 作符>(大于)
>=(大于等于)
<(小于)
<=(小于等于)
!=(不等于)
==(等于)
条件 *** 作符(三目 *** 作符)&&(逻辑与)——同真则真,有假则假
||(逻辑或) ——有真则真,同假则假
exp为(表达式)
exp1 ? exp2 :exp3
表达式1成立,则整个表达式的结果为表达式2,否则为表达式3.
逗号表达式(逗号隔开的一段表达式)
特点:从左向右依次计算,整个逗号表达式的结果是最后一个逗号表达式的结果。
exp1,exp2,exp3,……expn
下标引用,函数调用和结构成员
- ():函数调用
- .:结构体中用来访问成员变量
- C语言提供的,不能自己创建关键字
- ->:指针指向结构体成员变量的调用
关键字
- 变量名不能是关键字
//假设在一个源文件中有一个函数,我在另一个源文件中想使用它,那么我可以在要使用的源文件中进行函数声明
extern ADD(int, int);
也可以写成
extern ADD(int a, int b);
auto:是自动的,每个局部变量都是auto修饰的
原因:局部变量都是有作用域的,每个局部变量在作用域内被创建,出了作用域自动销毁,所以每个局部变量前面默认加一个auto
break:用于循环语句的跳出循环
case:用于switch语句的分支选择
char:字符类型修饰符
const:将变量加上const后,此变量便具有常属性,不可以再被更改
continue:用于循环语句结束当前循环,跳到下一次循环
default:switch语句里的默认选项
do:do……while循环所用
double:双精度浮点型
else:if……else里的选择
enum:枚举类型
extern:用来声明外部符号(声明时不需要指定它的值,指定他的类型即可)
//将unsigned int 用u_int修饰符表示,可以在方法里面(需要使用前定义),方法外面定义
typedef unsigned int u_int;
float:单精度浮点型
for:for循环的使用
goto:goto语句时使用
if:选择语句时使用
int:整形
long:长整型
register:寄存器关键字(用此关键字修饰的属性建议放到寄存器中)
cpu取数据一般都去寄存器里面拿,因为内存速度太慢了
short:短整型
return:返回关键字
signed:有符号的
unsigned:无符号的
sizeof:计算类型的大小
static:静态的
static修饰局部变量,改变了局部变量的生命周期(本质上改变了变量的存储类型)
static修饰全局变量,使得这个全局变量只能在自己所在的源文件内部可以使用,其他源文件中不能使用。
(全局变量在其他源文件内部可以被使用,是因为全局变量具有外部链接属性,但是被static修饰之后,就变成了内部链接属性,其他源文件就不能链接到这个静态的全局变量了。
)
static修饰函数,使得函数只能在自己所在的源文件内部使用,不能在其他源文件内部使用,本质上使函数的外部链接属性变成了内部链接属性
struct:结构体
switch:switch分支语句
typedef:类型重定义
//放在使用定义符号的前面
#define MAX 1000
union:联合体(共用体)
void:空类型
volatile:线程可见性,禁止指令重排序
while:while循环
#define定义常量和宏define与include不是关键字,他们两个叫预处理指令(预编译期间处理的指令)
1.define定义标识符常量//这里定义宏主要实现了替换功能,ADD(x,y)被替换成了x+y
#define ADD(x,y) x+y
int main() {
printf("%d\n",4*ADD(2,3));
return 0;
}
//这样会打印11,如果想得到20,定义如下
#define ADD(x,y) (x+y)
2.define定义宏
int main() {
int a = 56;
printf("%p\n",&a);
int* pa = &a;
*pa = 20;
printf("%d\n", a);
return 0;
}
指针
指针的原理
内存:内存是电脑上特别重要的存储器,计算机中所有程序的运行都在内存中进行。
所以为了有效地使用内存,就把内存分成了一个个细小的内存单元,每个内存单元的大小都是一字节。
为了能够有效的访问到内存的每个单元,就给内存单元进行了编号,这些编号被称为该内存单元的地址。
计算机中的32位与64位
32位——32根地址线——通电——每根线的通电状态(0/1)
64位——64根地址线——通电——每根线的通电状态(0/1)
电信号转化成数字信号就变成了1,0组成的2进制序列
以32位为例
00000000000000000000000000000000
……
11111111111111111111111111111111
总共可以表示的地址数为2^32个,这些序列都可以作为内存的编号,每个序列都可以作为内存的一个地址
如果电脑为32位内存大小为0.5gb,那么电脑管理的每个内存单元大小为1bit
既然内存有地址,那么指针就可以拿出内存单元的地址
在C语言中指针用来存放变量的地址,指针本身也是个地址,只不过是存放地址的地址。
当一个变量所占空间大于一个地址单元时,那么他会往下面继续排列所占用的地址连续,如果取址这个变量,那么拿到的是这个变量第一个地址单元的地址。
(取址a——&a)
指针的 *** 作printf("%d\n", sizeof(char*));
printf("%d\n", sizeof(int*));
printf("%d\n", sizeof(long*));
printf("%d\n", sizeof(long long*));
这里*号代表pa是指针变量
int代表pa执行的对象是int类型
这里存放a的地址是为了找到a,并对其进行控制
*pa就代表了a,这里的*号是解引用 *** 作符目的是找到a
指针占用内存的大小指针类型的大小都是相同的,指针有多大,取决于地址有多大。
结构体是C语言中的重要知识点,结构体使C语言能够描述复杂类型
比如描述学生,学生包含:名字+年龄+性别+学号 这几项信息(结构体成员)——成员变量
这里只能用结构体来描述了——结构体可以让C语言创造出新的类型出来
struct Stu{
char name[20];
int age;
double score;
};
void main(){
struct Stu s = { "lili",25,85.5 };
printf("1:%s %d %lf\n", s.name, s.age, s.score);
struct Stu* pa = &s;
printf("2:%s %d %lf\n", (*pa).name, (*pa).age, (*pa).score);
printf("3:%s %d %lf\n", pa->name, pa->age, pa->score);
}
->用于指针类型指向结构体的成员变量。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)