以下内容可能不全,有大佬知道可以继续补充。
1. c语言的特性
A: c语言是一种底层语言
B: c 语言是一种小型语言
C: c 语言一种包容性语言,c语言假设用户知道自己做什么,
所以她提供了更为广阔的自由度。
优点:
高效
可移植性,c语言编译器规模小,容易编写。
功能强大
灵活
标准库
与UNIX 系统结合紧密
缺点:
出错率高
难理解
难以修改
2. gcc
gcc( GNU Compiler Collection)
基本用法: gcc [options] [filenames]
-c 只编译,生产.o 为后缀的目标文件,通常用于编译
不包含主程序的子程序文件。
-o output_filename 确定输出文件的名称为
-g 产生符号调试工具gdb 所必要的符号资讯
-O 大写哦对程序进行优化编译
-O2 比-o 更好的优化编译
-std 例如: -std= c89 或者-std=c99
c程序(小全)宏观认识(代码角度,和内存角度)
一个较为完整的程序中,可以包含哪些部分?【描述记忆】
//系统头文件 #include... //宏定义 #define.... //全局变量 int data = 1; //自定义函数的声明 int main() //主函数 { //局部变量 local int data=2; for() //if switch while { //块变量 int data = 3; } } //自定义函数 。。。。。
C程序在内存中的分布?
程序段:代码段存放程序代码的一段区域,程序段是只读的。
数据 :存放已经初始化的全局变量。
bss段:通常用来存放程序中未初始化的全局变量和静态变量的一块内存区域堆
堆:保存进程中被动态分配的内存
申请:malloc remalloc(new) OC(alloc new init)
释放:free delete OC(release)
栈
栈:存储了程序中临时创建的局部变量
变量,生命周期,作用域
1.1 局部变量:【准确记忆】
我们把在函数体中定义的变量叫做这个函数的局部变量。
Int main()
{
Int a,b,c,d........//局部变量
}
Int test()
{
Int a; //局部变量
}
局部变量的特点;
1 生命周期:从定义这个局部变量的地方开始,到函数的结束。
作用域(访问范围):在定义这个局部变量的函数内(定义这个变量的以下语句);
1.2 静态局部变量
Static 修饰的局部变量:
特点【描述记忆】
1 生命周期:整个程序
2 作用域:和普通变量一样。
1.值:数值就是上一次函数调用结束之后的数值。
#include <stdio.h> int test(){ static int i=0; i++; printf("i = %d\n",i); return 0; } int main() { int i=0; //这里的i和test里面的i不一样 for(;i<6;i++) { test(); } return 0; }
结果如下:
编辑切换为居中
1.3 全局变量
:定义在整个程序中的变量称为全局变量
生命周期:整个程序的生命周期之内
作用域(访问范围):整个程序的范围内都可以访问
值:没有初始化的全局变量的数值是0.
1.4 块变量
:定义在语句块里面的变量叫做块变量。
程序块(语句块):使用{}括起来的一组语句。
块变量的特性:
生命周期:定义变量的地方开始,程序块结束的地方消失
作用域(访问范围):程序块内
for(......)
{
Int i = 0; //块变量
}
If(......)
{
Int temp = i ; // 块变量
}
变量优先级:局部优先原则
#include <stdio.h> int data = 1;int main(){ printf("data = %d\n",data); int data = 2; //局部变量 printf("data = %d\n",data); if(1) { int data = 3; //块变量 printf("data = %d\n",data); } return 0;}
结果如下:
编辑切换为居中
关键字修饰变量
Auto static register
Static 修饰全局变量
访问范围:只能在本文件访问。
即使在其他文件中使用extern声明也不能使用
Static 修饰函数
访问范围:
这个函数只能在本文件中使用
什么是自动变量?
普通局部变量(static除外)都是auto ,auto 一般省略。
Auto int i;
Register: 寄存器变量
:告诉编译器这个变量会被频繁的使用,请保存到寄存器中。
使用限制【描述记忆】
1.必须能被cpu的寄存器接受(32位= 4个字节)
2.能对寄存器变量取地址 &
概念:
类型:每个变量都必须声明她的类型。C可分为基本数据类型和复合数据类型
声明:任何变量在使用之前必须进行声明。如:数据类型变量名称
初始化:
1.动变量未初始化的时候访问,其数值是一个随机数值。
#include <stdio.h>int main(){ int day; printf(“day = %d\n”,day); return 0;}
标识符:在编写程序的时候,需要对变量,函数,宏,以及其他实体进行命名,这些名称成为:标示符。
标示符有五条命名规则:
以字母,下划线开头;
可以包含字母,下划线,数字
大小写敏感
不能和关键字冲突
关键字:
特性:
有特殊含义的一串字符
全部小写
标准库中函数名全部小写
字符串
字符串的三种表示方式的区别?
字面值。存在于全局区,不可改变。在内存中只有一个。
Char 数组存在于内存中函数栈,数值可以改变
Char str[] = “abcde”;
//赋值的时候
Str = “abcde”;
3. Char * 既可以指向字面值,也可以指向char 数组里面的元素。
格式化输入/输出:
printf( 格式字符串,表达式1,表达式2,。。。。) //可变长参数
格式字符串可分为两个部分:普通字符和转换说明
转换说明包含以下几部分:
完整格式: % - 0 m.n l或者h 格式字符
1. % 占位符 不能省略
2. - 左对齐,省略右对齐
3. 0 代表空位填0 省略代表空位不填
4. m 域宽 n 精度
5. l 整数long, 浮点数double ; h为 short;
6. i /d 输出十进制整数
O 无符号的八进制整数
X 十六进制
u 无符号的十进制
c 输出一个字符
s 输出一个字符串
f 输出一个浮点数
e 以指数的形式输出浮点数
g 在f和e格式之间选择一个较短格式输出
P 输出一个地址
%m 输出全局error中错误
2 %i%d
在printf里面没有区别
在scanf 有区别
%d 只匹配十进制
%i 八进制 十进制,十六进制
3 如何输出%
%%
4. 4 scanf() 从键盘输入
绝大数情况下,scanf 只包含转换说明。
scanf(格式字符串,地址列表);
例如:scanf(“%f%f%f”, &s1, &s2, &s3);
整数在内存中的存储? 【准确记忆】
整型在内存中的存储是按照补码形式存储的。整数的补码与源码相同,
负数的补码就是其绝对值的二进制形式按位取反,然后整个数值加 1.
进制转换 【理解描述】
sizeof 是c语言的一个关键字,不是函数。
sizeof(变量的名字) 或者sizeof (类型)
sizeof 返回一个对象或者类型所占的内存字节数
sizeof 三种语法方式 b*****b 【准确记忆】
1. sizeof(类型)
2. sizeof(变量名)
3. sizeof(表达式)
int i=5;
sizeof(i=10);
运算符:
算数运算符:+ - * / %
/ 0不能做除数,两个整数相除,取结果的整数部分。
% 要求操作数都为整数,如果其中一个不是整数,编译将无法通过。
赋值运算符
Int i,j;
复合赋值 += -= *= /= %=
自增、自减
比较运算符: ==
推荐写法:if(15 == data)
逻辑运算符的
短路特性 b*****b【准确描述】
&& || ?:
例子:
#include <stdio.h>int main(){ int i=0, j=0; if(++i || ++j); if(--i && ++j); printf("i = %d,j = %d\n",i,j); return 0;}
位运算符
按位取反~3
按位与 &
用途: b***b 【记忆描述】
经常用来屏蔽某些二进制位(置0)。也可以知道某个二进制位是1还是0。
按位或 |
用途: b***b【记忆描述】
经常用来将某些二进制位(置1)。也可以知道某个二进制位是1还是0。
按位异或 ^
运算规则:b*****b 【准确记忆】
对应的二进制位上的数字相同则为0,否则为1。
例子:判断某个整数二进制格式倒数第三位是0还是1?
If(data &4) ==4) 倒数第三位1
左移
规则: b*****b 【准确记忆】
左移的时候右边的空位补零
右移
规则:b*****b 【准确记忆】
右移的时候左边补上符号位。
取地址运算
条件运算符
表达式1?表达式2:表达式3
语句
if else 语句
switch 语句
结构
Switch(控制表达式)
{
Case 常量表达式1 :语句1;
Case 常量表达式2 : 语句2;break;
....
Default: .....
}
注意:
控制表达式:计算结果是整型
常量表达式:不能包含变量或者函数调用,最终结果必须是整数。
例如:n+10 不是常量表达式(除非n是表示常量的宏),
每个分支中可以包含多条语句,可以不使用{}
循环语句:
for(表达式1;表达式2;表达式3)
{
语句;
}
执行流程 表达式1 ==》 表达式2==〉循环语句==》表达式3==〉表达式2==》。。。
注意:可以这样写for(;;){....}
for(i=0;i<10;i++){...}
C99 第一个表达式可以为声明例如:
for(int i=0; i<10; i++){....}
for(i=0,j=0;i<10; printf(),i++,j++){....}
for循环可以嵌套
C语言中两种常用的无限循环(死循环)方式?
while(1)
for(;;)
do-while 循环
从键盘读入: scanf
键盘--》 键盘缓冲区--〉 输入缓冲区--》程序。
#include<stdio.h>int main(){ int data_1 = 0, data_2 = 0; printf("请输入两个整数:"); scanf("%d",&data_1); scanf("%d",&data_2); printf("您输入的两个整数是:%d %d\n",data_1,data_2); return 0;}
编辑切换为居中
分析:scanf失败的原因:类型不匹配
改成如下: #include<stdio.h>int main(){ int data_1 = 0, data_2 = 0; printf("请输入两个整数:"); if(scanf("%d",&data_1) == 0) { scanf("%*[^\n]"); scanf("%*c"); } if(scanf("%d",&data_2) == 0) { scanf("%*[^\n]"); //读走\n之前的所有字符 scanf("%*c");//读走字符包括之前匹配到的(*) c代表字符 } printf("您输入的两个整数是:%d %d\n",data_1,data_2); return 0;}
输出缓冲区
程序--》输出缓冲区--〉屏幕
程序的输出可以到达屏幕的条件: b*****b 【描述记忆】
1,\n
程序结束
输出缓冲区满(4kb)
人工刷新(fflush)
例子:
#include <stdio.h>
int main()
{
printf("welcome!");
while(1);
}
结果:没有输出
#include <stdio.h>
int main()
{
printf("welcome!");
fflush(stdout); //新增加的人工刷新
while(1);
}
字符串
读取一个字符串放到字符数组中,然后打印
scanf(“%s”,&name);
scanf 遇到空白字符结束
gets(name)
从输入设备读取一行字符回来,放到name中
危险:gets 不会考虑name的大小,可能导致name的溢出。
fgets(name,20,stdin);
fgets会在整个字符串的后面添加\n
操作字符串的库函数
Strcpy
Strcat
Strncpy
Strncat
Strlen:
strcmp:
数组和结构 (聚合类型)
数组:
一维数组初始化
Int a[5] = {1,2,3} ; //【可描述】如果初始化里面常量表达式个数小于数组元素的个数,剩余的元素初始化为零。
指定初始化
Int a[30] = { [19] = 54, [9]=> 14, [29] = 45 };
#include <stdio.h>int main(){ int a[10]; printf("sizeof(a[0]) = %d\n",sizeof(a[0])); printf("sizeof(a) = %d\n",sizeof(a)); char c[10]; printf("sizeof(c[0]) = %d\n",sizeof(c[0])); printf("sizeof(c) = %d\n",sizeof(c)); return 0;}
结果如图:
编辑切换为居中
获取数组的个数?
宏带参数的宏: #define sz(a) sizeof(a)/sizeof(a[0])
c99中的变长数组
Int n;
Scanf(“%d”, &n);
Int a[n]; //c99变长数组