目录
八、函数
九、数组
1、数组的定义:一组相同类型元素的集合
2、数组的下标
数组的每个元素都有一个下标,下标是从0开始的。
数组可以通过下标来访问元素。
3、数组的使用
十、操作符
1.常见操作符:
举例:
1)算数操作符:+ - * / %
2) sizeof
3) 前置--,后置--;前置++,后置++;
4)强制类型转换
5)逻辑与 、逻辑或
6)条件表达式(三目操作符)
7) 逗号表达式
8)下标访问操作符[]
9)函数调用操作符()
十一、关键字
1. 关键字(auto 、continue、break、char、short、int、float、double、register)
2.关键字typedef -类型重定义
3.关键字static
1.修饰局部变量
2.修饰全局变量:
3.修饰函数:
十二、#define 定义常量和宏
1)define定义标识符常量
2)define定义宏
十三、指针
指针变量的大小
十四、结构体
八、函数
将一个复杂的功能操作,写成一个模块的东西,反复利用,提高效率
#include <stdio.h>
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 <stdio.h>
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;
}
九、数组
1、数组的定义:一组相同类型元素的集合
int main()
{
//int arr[10]; //创建数组
//char ch[5];
//int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };//完全初始化
//int arr2[10] = { 1, 2, 3, 4, 5 };//不完全初始化
//char ch[] = { 'a', 'b', 'c' };
//char ch1[] = "abc";
return 0;
}
2、数组的下标
数组的每个元素都有一个下标,下标是从0开始的。
数组可以通过下标来访问元素。
int main()
{
int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
//下标0-9
printf("%d\n", arr[0]);
int i = 0;
while (i < 10) //一次输入数值
{
scanf("%d", arr[i]);
i++;
}
//打印数组
i = 0;
while (i < 10)
{
printf("%d", arr[i]);
i++;
}
return 0;
}
3、数组的使用
#include <stdio.h>
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;
}
十、操作符
1.常见操作符:
算数操作符:+ - * / %
移位操作符:<< >> (移动的是二进制)
位操作符: & ^ | (二进制位的运算)
按位与 按位或 按位异或赋值操作符:
= += -= *= /= &= ^= |= >>= <<=单目操作符:! - + & sizeof ~ ++ -- * (类型)-强制类型转换
关系操作符:> < >= <= != ==
逻辑操作符:&& ||
条件操作符(三目操作符): exp1?exp2:exp3
逗号表达式 : exp1,exp2,exp3,...expN
从左向右依次计算,但整个表达式的结果是最后一个表达式的结果下标引用 :在数组里用[]访问下标
举例:
1)算数操作符:+ - * / %
int main()
{
//int a = 21;
//int b = 4;
21/4 = 5...1
//printf("%d\n", a / b);// /除法 - 得到的是商
//printf("%d\n", a % b);// %取模 - 得到的是余数
float a = 10.0f;
float b = 3.0f;
printf("%d\n", a / b);// 3.333333
//printf("%d\n", a % b);// 报错!! %取模 - 操作符两边必须是整数!!!
float s = 10 / 3;// /两端为整数,执行整数除法,得到的是整数
printf("%d\n", s); //3
float d = 10 / 3;// /两端只要有一个为浮点数,执行的就是浮点型的除法,得到的数为小数
printf("%d\n", s); //3.333333
return 0;
}
int main()
{
int flag = 3;
//C语言中,0表示假,非0为真
if (flag)//flag为真,打印hehe
{
printf("hehe\n");
}
if (!flag)//flag为假,打印haha
{
printf("haha\n");
}
return 0;
}
2) sizeof
int main()
{
int a = 10;
printf("%d\n", sizeof(a));//计算变量。4 - 单位是字节
printf("%d\n", sizeof(int));//计算类型。4
int arr[10] = { 0 };
printf("%d\n", sizeof(arr));//计算的是数组的总大小,单位是字节 40
int sz = sizeof(arr) / sizeof(arr[0]);//求数组元素的个数
printf("%d\n", sz);
return 0;
}
3) 前置--,后置--;前置++,后置++;
int main()
{
//int a = 10;
//int b = a--;//后置--,先使用,后--
//printf("a=%d b=%d\n", a, b);//a=9 b=10
//int a = 10;
//int b = --a;//前置--,先--,后使用
//printf("a=%d b=%d\n", a, b);//a=9 b=9
//int a = 10;
//int b = a++;//后置++,先使用,后++
//printf("a=%d b=%d\n", a, b);//a=11 b=10
//int a = 10;
//int b = ++a;//前置++,先++,后使用
//printf("a=%d b=%d\n", a, b);//a=11 b=11
return 0;
}
4)强制类型转换
int main()
{
int a = (int)3.14;
float b = (float)3.14;
printf("%d\n", a);
printf("%f\n", b);
return 0;
}
5)逻辑与 、逻辑或
int main()
{
//逻辑与 - 并且
int age = 21;
if (age >= 18 && age <= 30)
{
printf("青年\n");
}
//逻辑或 - 或者
char ch = 'Q';
if (ch<'a' || ch>'z')//'a'~'z'
{
printf("非小写字母\n");
}
return 0;
}
6)条件表达式(三目操作符)
int main()
{
int a = 0;
int b = 0;
int m = 0;
scanf("%d %d", &a, &b);
if (a > b)
{
m = a;
}
else
{
m = b;
}
//m = (a > b ? a : b); //条件表达式(三目操作符)
printf("%d\n", m);
return 0;
}
7) 逗号表达式
int main()
{
int a = 3;
int b = 5;
int c = 0;
int d = (a += a, b = a - 5, c = a + b);
//a=a+a=6 b=a-5=6-5=1 c=a+b=6+1=7 //逗号表达式的最后的式子为整个表达式的结果
printf("%d\n",d);//7
return 0;
}
8)下标访问操作符[]
int main()
{
int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
printf("%d\n", arr[4]);//[]下标访问操作符,arr和4是[]操作符的操作数
return 0;
}
9)函数调用操作符()
int Add(int x, int y)
{
return x + y;
}
int main()
{
int a = 10;
int b = 20;
int sum = Add(a, b);//( )函数调用操作符,操作数Add,a,b
printf("%d\n", sum);
return 0;
}
十一、关键字
1. 关键字(auto 、continue、break、char、short、int、float、double、register)
auto 局部变量(自动变量),自动创建,自动销毁;通常auto省略掉
continue、break :循环、switch语句
char、short、int、long 、float、double数据类型 :既是数据类型也是关键字
register:寄存器。作用:建议把某个变量放在寄存器中存储。但最终是否放在寄存器中,取决于编译器。
int main()
{
//auto int a = 10;//局部变量(自动变量),自动创建,自动销毁;通常auto省略掉
//continue、break :循环、switch语句
//char、short等 :既是类型也是关键字
//register int num = 100;//建议把100放在寄存器中存储。最终是否放在寄存器中,取决于编译器。
return 0;
}
2.关键字typedef -类型重定义
由于有些类型太长不利于编程或记忆,可以给数据类型定义一个别名,方便记忆和编程
//typedef 类型重命名 - 别名
typedef unsigned int uint;//将unsigned int(无符号整型)这个数据类型,定义为uint这个别名
int main()
{
unsigned int num = 100;//通常创建无符号整型变量的方法
uint num2 = 200;//利用typedef重命名类型之后,直接使用别名创建变量
return 0;
}
3.关键字static
1.修饰局部变量
1)一个普通的局部变量是放在栈区的,而被static的修饰的局部变量,是放在内存的静态区的
2)栈区的变量是进入局部区域创建,出局部区域就销毁了;静态区的变量是程序结束了,才会被销毁。
3)(存储位置发生了变化)使得局部变量出了作用域不会销毁(保留上一次的值),改变了生命周期
//1.修饰局部变量
void test()
{
//int a = 1; 如果此时a是这样,那么最后的结果为 2 2 2 2 2 2 2 2 2 2,因为每一次进入test都会重新创建一次a,a++之后得到2,所以每一次打印的结果都为2
static int a = 1; //静态变量,第一次创建了,之后不会再重复创建,结果会保留。第一次a++得到2,第二次a=2,保留上一次的,a++之后得到3,依次类推。。
a++;
printf("%d\n", a);//静态变量,最后的结果为2 3 4 5 6 7 8 9 10 11
}
int main()
{
int i = 0;
while (i < 10)
{
test();
i++;
}
return 0;
}
2.修饰全局变量:
1)一个全局变量在整个工程都可以使用的!!
2)全局变量是具有外部链接属性的。只要在其他源文件内部,适当的声明(extern),就能使用static修饰全局变量,全局变量的外部链接属性就变成内部链接属性了,只能在自己所在的.c文件中使用
3)影响了变量的作用域
//代码1
//add.c
int g_val = 2018; //在add.c文件里面的内容,定义了一个整型变量g_val ,值为 2018
//test.c
extern int g_val;//引用外部文件的变量。全局变量是具有外部链接属性的。只要在其他源文件内部,适当的声明(extern),就能使用
int main()
{
printf("%d\n", g_val); //可以打印。在另一个文件里(同一项目下),打印add.c文件里的g_val值
return 0;
}
//代码2
//add.c
static int g_val = 2018; //静态变量,static是全局变量失去外部链接的属性,变成内部链接,导致该变量只能在本文件中使用无法引用到外部文件
//test.c
extern int g_val;
int main()
{
printf("%d\n", g_val); //err报错,无法正常运行
return 0;
}
3.修饰函数:
1)函数具有外部链接属性
2)stati修饰函数后,函数的外部链接属性就变成了内部链接属性
只能在自己所在的.c文件中使用,在其他文件中无法使用
3)相当于影响了作用域
//代码1
//add.c
int Add(int x, int y) //在add.c文件中定义函数Add
{
return c+y;
}
//test.c
extern int Add(int x, int y) //引用外部文件中的Add函数
int main()
{
printf("%d\n", Add(2, 3));//正常运行,打印5。函数具有外部链接属性,可以引用
return 0;
}
//代码2
//add.c
static int Add(int x, int y) //stati修饰函数后,函数的外部链接属性就变成了内部链接属性
//只能在自己所在的.c文件中使用,在其他文件中无法使用
{
return c+y;
}
//test.c
extern int Add(int x, int y)
int main()
{
printf("%d\n", Add(2, 3)); //err报错。静态static修饰后,无法引用
return 0;
}
十二、#define 定义常量和宏
1)define定义标识符常量
2)define定义宏
//define定义标识符常量
#define MAX 1000
#define STR "hello world!"
//define定义宏
#define ADD(x, y) ((x)+(y))
#include <stdio.h>
int main()
{
int sum = ADD(2, 3);
printf("sum = %d\n", sum);
sum = 10*ADD(2, 3);
printf("sum = %d\n", sum);
return 0;
}
十三、指针
1)指针变量的大小:
指针变量是用来存放地址的
2)地址是:
32位机器上:32个0/1组成的二进制序列,需要32bit位的空间储存,指针变量就需要4字节
64位机器上:64个0/1组成的二进制序列,需要64bit位的空间储存,指针变量就需要8字节
int main()
{
int a = 10;//向内存申请4个字节空间,存储10
int* pa = &a;//pa叫做指针变量。& - 取地址操作符
//a实际占用4个字节的空间,每个字节都有地址,但是&a拿到的是第一个字节的地址(也就是小的地址)
//pa是一个存放地址的变量,也是存放指针的变量,所以pa叫指针变量
//pa的类型就是 int*
//*说明,pa是指针变量;int说明,pa指向的对象的int类型
printf("%d\n", a);
*pa = 20;//* 解引用操作符 找到pa指向的变量a,将a的值改为20
printf("%d\n",a);
return 0;
}
指针变量的大小
#include <stdio.h>
//指针变量的大小取决于地址的大小
//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;
}
十四、结构体
//14************* 结构体 ********************
/*
人:名字+id+出生日期+性别
书:书名+作者+出版社+定价
*/
struct Student
{
//结构体类型
char name[20];//名字
int age;//年龄
char id[15];//学号
float score;//成绩
};
int main()
{
//s1、s2是结构体对象
struct Student s1 = { "张三", 20, "2022010823", 88.5f };
struct Student s2 = { "翠花", 18, "2022030405", 98.0f };
printf("%s %d %s %f\n", s1.name, s1.age, s1.id, s1.score);//结构体变量.成员
struct Student * ps = &s1;
printf("%s %d %s %f\n", (*ps).name, (*ps).age, (*ps).id, (*ps).score);
printf("%s %d %s %f\n", ps->name, ps->age, ps->id, ps->score);//结构体指针->成员
return 0;
}