目录
1.数据结构
类型的使用
2. 变量、常量
2.1 定义变量的方法
2.2 变量的命名
2.3 变量的分类
2.4变量的使用
scanf
printf
2.5 变量的作用域和生命周期
作用域
生命周期
2.6 常量
3. 字符串+转义字符+注释
3.1 字符串
3.2 转义字符
4. 注释
5. 选择语句
6. 循环语句
7. 函数
8. 数组
8.1 数组定义
8.2 数组的下标
8.3 数组的使用
9.操作符
算术操作符
移位操作符
位操作符
赋值操作符
单目操作符
关系操作符
逻辑操作符
逗号表达式
下标引用、函数调用和结构成员
10. 常见关键字
10.1 关键字 typedef
10.2 关键字static
10.2.1 修饰局部变量
10.2.2 修饰全局变量
10.2.3 修饰函数
11. #define 定义常量和宏
12. 指针
12.1 内存
12.2 指针变量的大小
13. 结构体
为了表示生活中各种各样丰富的值,C语言的开发者为我们这些使用者设定了许多数据类型。
char // 字符数据类型short // 短整型int // 整形long // 长整型long long // 更长的整形float // 单精度浮点数double // 双精度浮点数
#include int main (){printf ( "%d\n" , sizeof ( char )); -------------> 1printf ( "%d\n" , sizeof ( short )); -------------> 2printf ( "%d\n" , sizeof ( int )); -------------> 4printf ( "%d\n" , sizeof ( long )); -------------> 4printf ( "%d\n" , sizeof ( long long )); -------------> 8printf ( "%d\n" , sizeof ( float )); -------------> 4printf ( "%d\n" , sizeof ( double )); ;-------------> 8printf ( "%d\n" , sizeof ( long double )); -------------> 8return 0 ;而此刻,他们的单位是Byte,即字节。}
1Byte=8bit---------->1B=8b
KB = 1,024 Byte
1MB = 1,024 KB1GB= 1,024MB = 1,048,576 (1024)KB
1TB= 1,024GB = 1,073,741,824 (1024)KB
即 b B KB MB GB TB PB
char ch = 'w' ;这里存储了一个字符,实际上计算机存储的是字符对应的ASCII码值.int weight = 120 ;int salary = 20000 ;
int age = 150 ;float weight = 45.5f ;注意编译器在识别时,55.5直接写出来是默认是double类型。55.5f这个时候就是float类型。char ch = 'w' ;
#include int global = 2019 ; // 全局变量(包涵在大括号外的变量)int main (){int local = 2018 ; // 局部变量(包含在大括号内的变量)//下面定义的global会不会有问题?int global = 2020 ; // 局部变量printf ( "global = %d\n" , global );return 0 ;}
上面的局部变量global总结:al变量的定义其实没有什么问题的!当局部变量和全局变量同名的时候,局部变量优先使用。
#include int main (){int num1 = 0 ;int num2 = 0 ;int sum = 0 ;printf ( " 输入两个操作数 :>" );scanf ( "%d %d" , & num1 , & num2 );sum = num1 + num2 ;printf ( "sum = %d\n" , sum );return 0 ;}// 这里介绍一下输入,输出语句//scanf//printf
scanf的返回值是 读取到的数据个数,如果读取失败那么返回EOF。
C语言中有 #define EOF -1
那么此时就可以用该函数的返回值进行重复输入
while(scanf("%d",&d)!=EOF)
{
scanf("%d",&d);
}
一般编译器按住Ctrl+Z就可以停止输入,而VS需要按三次。
printf的返回值是打印的数据个数。
%c 字符
%d 整型 %02d前面空两格,用2填充。
%s 字符串
%f 浮点型 %.2f保留两位小数。
%p 地址 以16进制的方式表示地址
字面常量
const 修饰的常变量(就是具有常属性,但是其本质还是变量)
#define 定义的标识符常量(相当于给一个常量取一个名字)
枚举常量( // 注:枚举常量的默认是从 0 开始,依次向下递增 1 的 )
#include // 举例enum Sex{MALE ,FEMALE ,SECRET};// 括号中的 MALE,FEMALE,SECRET 是枚举常量int main (){// 字面常量演示3.14 ; // 字面常量1000 ; // 字面常量//const 修饰的常变量const float pai = 3.14f ; // 这里的 pai 是 const 修饰的常变量pai = 5.14 ; // 是不能直接修改的!//#define 的标识符常量 演示#define MAX 100printf ( "max = %d\n" , MAX );// 枚举常量演示printf ( "%d\n" , MALE );printf ( "%d\n" , FEMALE );printf ( "%d\n" , SECRET );// 注:枚举常量的默认是从 0 开始,依次向下递增 1 的//注:枚举常量可以初始化,但是不能在主函数中赋值return 0 ;}
"hello word\n"
#include // 下面代码,打印结果是什么?为什么?(突出 '\0' 的重要性)int main (){char arr1 [] = "bit" ;char arr2 [] = { 'b' , 'i' , 't' };char arr3 [] = { 'b' , 'i' , 't' , '\0' };printf ( "%s\n" , arr1 );printf ( "%s\n" , arr2 );printf ( "%s\n" , arr3 );return 0 ;}#include int main (){printf ( "c:\code\test.c\n" );return 0 ;}
转义字符 |
释义
|
\?
|
在书写连续多个问号时使用,防止他们被解析成三字母词
|
\'
|
用于表示字符常量 '
|
\“
|
用于表示一个字符串内部的双引号
|
\\
|
用于表示一个反斜杠,防止它被解释为一个转义序列符
|
\a
|
警告字符,蜂鸣
|
\b
|
退格符 //往回退一格,相当于 BackSpace
|
\f
|
进纸符
|
\n
|
换行
|
\r
|
回车
|
\t
|
水平制表符 // TAB 相当于两个或四个空格,在strlen中相当于一个字符。
|
\v
|
垂直制表符
|
\ddd
|
d d d 表示 1~3 个八进制的数字。 如: \130 表示字符 X
|
\xdd
|
d d 表示 2个十六进制数字。如: \x30 表示字符 0
|
#include int main (){// 问题 1 :在屏幕上打印一个单引号 ' ,怎么做?// 问题 2 :在屏幕上打印一个字符串,字符串的内容是一个双引号 “ ,怎么做?printf ( "%c\n" , '\'' );printf ( "%s\n" , "\"" );return 0 ;}
// 程序输出什么?#include int main (){printf ( "%d\n" , strlen ( "abcdef" ));// \62 被解析成一个转义字符printf ( "%d\n" , strlen ( "c:\test\628\test.c" ));return 0 ;}
#include int Add ( int x , int y ){return x + y ;}/*C 语言风格注释int Sub(int x, int y){return x-y;}*/int main (){//C++ 注释风格//int a = 10;// 调用 Add 函数,完成加法printf ( "%d\n" , Add ( 1 , 2 ));return 0 ;}
#include int main (){int coding = 0 ;printf ( " 你会去敲代码吗?(选择 1 or 0 ) :>" );scanf ( "%d" , & coding );if ( coding == 1 ){prinf ( " 坚持,你会有好 offer\n" );}else{printf ( " 放弃,回家卖红薯 \n" );}return 0 ;}
//while 循环的实例#include int main (){int line = 0 ;while ( line <= 20000 ){line ++ ;printf ( " 我要继续努力敲代码 \n" );}if ( line > 20000 )printf ( " 好 offer\n" );return 0 ;}
#include int main (){int num1 = 0 ;int num2 = 0 ;int sum = 0 ;printf ( " 输入两个操作数 :>" );scanf ( "%d %d" , & num1 , & num2 );sum = num1 + num2 ;printf ( "sum = %d\n" , sum );return 0 ;}上述代码,写成函数如下:#include int Add ( int x , int y ){int z = x + y ;return z ;}int main (){int num1 = 0 ;int num2 = 0 ;int sum = 0 ;printf ( " 输入两个操作数 :>" );scanf ( "%d %d" , & num1 , & num2 );sum = Add ( num1 , num2 );printf ( "sum = %d\n" , sum );return 0 ;}int arr [ 10 ] = { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 }; // 定义一个整形数组,最多放 10 个元素
int arr [ 10 ] = { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 }; // 定义一个整形数组,最多放 10 个元素
C语言规定:数组的每个元素都有一个下标,下标是从0开始的。数组可以通过下标来访问的。
比如:int arr[10] = {0};//如果数组10个元素,下标的范围是0-9
#include int main (){int i = 0 ;int arr [ 10 ] = { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 };for ( i = 0 ; i < 10 ; i ++ ){printf ( "%d " , arr [ i ]);}printf ( "\n" );return 0 ;}
注:C99前 数组的定义不能用变量
C99后,引入数组增长,可以用变量定义数组,但是此时无法进行数组初始化。
在初识C语言中,只是简单的介绍。
+ - * / %
注:% 取余,但是无法对浮点型取余/ 除法 1、计算结果是整除后面的商2、除法 分为 整数除法浮点数除法:除数和被除数之间至少有一个浮点数
>> <<
位移操作符移动的是二进制,操作的也是二进制
& ^ |
= += -= *= /= &= ^ = |= >>= <<=
! 逻辑反操作 //if(a),a为真进入if ; if(!a),a为假进入if;- 负值+ 正值& 取地址sizeof 操作数的类型长度(以字节为单位) //他不是函数~ 对一个数的二进制按位取反-- 前置、后置 --++ 前置、后置 ++ //前置++,先++再使用;后置++,先使用后++* 间接访问操作符 ( 解引用操作符 )( 类型 ) 强制类型转换
>>=<<=!= 用于测试 “ 不相等 ”== 用于测试 “ 相等 ”
&& 逻辑与 并且,两个操作数都为真,才为真;只要有一个为假,则为假;|| 逻辑或 或者,只要有一个操作数为真,就为真;
exp1, exp2, exp3, …expN
真,执行, 不执行假,不执行,执行
[] () . ->[] 下标引用操作符
()函数调用操作符,定义时不是,只有调用时是。
auto break case char const continue default do double else enumextern float for goto if int long register return short signedsizeof static struct switch typedef union unsigned void volatile while
比如:
//将unsigned int 重命名为uint_32, 所以uint_32也是一个类型名
typedef unsigned int uint_32 ;int main (){// 观察 num1 和 num2, 这两个变量的类型是一样的unsigned int num1 = 0 ;uint_32 num2 = 0 ;return 0 ;}
注:相当于给类型标识符重新起了一个名字。
栈区 |
局部变量 形式变量 临时作用的变量都在栈区 |
特点:进入作用域创建,出了作用域销毁。 |
堆区 | 动态内存分配 malloc calloc realloc free |
|
静态区 | 全局变量 静态变量 |
特点:创建好后,直到程序结束才销毁 |
//代码1#include void test (){int i = 0 ; //每一次都是一个全新的ii ++ ;printf ( "%d " , i );}int main (){int i = 0 ;for ( i = 0 ; i < 10 ; i ++ ){test ();}return 0 ;}//代码2#include void test (){//static修饰局部变量static int i = 0 ; //每一次都是同一个ii ++ ;printf ( "%d " , i );}int main (){int i = 0 ;for ( i = 0 ; i < 10 ; i ++ ){test ();}return 0 ;}
// 代码 1//add.cint g_val = 2018 ;//test.cint main (){printf ( "%d\n" , g_val ); //全局变量具有外部连接属性,在其他源文件中依旧可以使用。return 0 ;}// 代码 2//add.cstatic int g_val = 2018 ;//test.cint main (){printf ( "%d\n" , g_val );return 0 ;}
// 代码 1//add.cint Add ( int x , int y ){return x + y ;}//test.cint main (){printf ( "%d\n" , Add ( 2 , 3 ));return 0 ;}// 代码 2//add.cstatic int Add ( int x , int y ){return x + y ;}//test.cint main (){printf ( "%d\n" , Add ( 2 , 3 ));return 0 ;}
结论:
//define 定义标识符常量,相当于给常量取了一个名字。#define MAX 1000//define 定义宏#define ADD (x, y) ((x)+(y))名字 参数 宏实现体#include int main (){int sum = ADD ( 2 , 3 );printf ( "sum = %d\n" , sum );sum = 10 * ADD ( 2 , 3 );printf ( "sum = %d\n" , sum );return 0 ;}
内存 | |
一个字节 | OXFFFFFFFF |
一个字节 | OXFFFFFFFE |
一个字节 | OXFFFFFFFD |
................................. | ....................... |
一个字节 | OX00000001 |
#include int main (){int num = 10 ;& num ; // 取出 num 的地址// 注:这里 num 的 4 个字节,每个字节都有地址,取出的是第一个字节的地址(较小的地址)printf ( "%p\n" , & num ); // 打印地址, %p 是以地址的形式打印return 0 ;}
那地址如何存储,需要定义指针变量。
int num = 10 ;int * p ; //p 为一个整形指针变量p = & num ;
#include int main (){int num = 10 ;int * p = & num ;* p = 20 ;return 0 ;}
#include
int main()
{
char ch = 'w';
char* pc = &ch;
*pc = 'q';
printf("%c\n", ch);
return 0;
}
#include // 指针变量的大小取决于地址的大小//32 位平台下地址是 32 个 bit 位(即 4 个字节)//64 位平台下地址是 64 个 bit 位(即 8 个字节)int main (){printf ( "%d\n" , sizeof ( char * ));printf ( "%d\n" , sizeof ( short * ));printf ( "%d\n" , sizeof ( int * ));printf ( "%d\n" , sizeof ( double * ));return 0 ;}
总结:
实质上指针是什么呢?
首先,他是一个变量。
什么类型的变量?
用于存放内存地址的变量
有什么特别的用处?
这里不多说,就可引用 *号来表示出内存中所存放的内容。
struct Stu{char name [ 20 ]; // 名字int age ; // 年龄char sex [ 5 ]; // 性别char id [ 15 ] ; // 学号};
// 打印结构体信息struct Stu s = { " 张三 " , 20 , " 男 " , "20180101" };//. 为结构成员访问操作符 (结构体变量)printf ( "name = %s age = %d sex = %s id = %s\n" , s . name , s . age , s . sex , s . id );//-> 操作符 (结构体指针)struct Stu * ps = & s ;printf ( "name = %s age = %d sex = %s id = %s\n" , ps -> name , ps -> age , ps -> sex , ps -> id );