一、常见关键字
1.关键字typedef
typedef的作用就是给一个类型定义一个别名(起个外号)例如当有的类型比较长的时候。比如无符号…(unsigned)。unsigned可以和谁搭配呢?char 、short 、int、 long 、long long。而float和double一定是有符号的,有IEEE756标准来规定。
下面举个例子吧。
int main()
{
unsigned int num1 = 0;
typedef unsigned int unit;
unit num2 = 1;
return 0;
unsigned int 不能表示负数。
2.关键字static
static的字面含义是“静态”,然而它的作用却和静态没有什么关系。
在C语言中:static是用来修饰变量和函数的。
1.修饰局部变量
2.修饰全局变量
3.修饰函数
1)修饰局部变量
下面展示两串代码帮助大家理解一下
void print() {
int num = 1;
printf("num=%d\n", num);
num++;
}
int main() {
print();
print();
print();
return 0;
system("pause");
}
运行结果为:
num++的结果随着大括号结束就会销毁,重新进入函数依旧是num=1,所以三次打印结果全是1。
下面看第二个程序:
void print() {
static int num = 1;
printf("num=%d\n", num);
num++;//没有脱离大括号之后就随之销毁
}
int main() {
print();
print();
print();
return 0;
system("pause");
}
运行结果为:
可以看到,加了static运行结果有很大区别,改变了变量的生命周期,程序结束,生命周期才结束。那么作用域是否改变了呢
void print() {
static int num = 1;
printf("num=%d\n", num);
num++;//没有脱离大括号之后就随之销毁
}
int main() {
print();
print();
print();
printf("num=%d\n", num);//错误,没有改变作用域
return 0;
system("pause");
}
程序会报错,说明没有改变作用域。
结论:static修饰局部变量改变了变量的生命周期,让静态局部变量出了作用域依然存在,到程序结束,生命周期才结束。
2.修饰全局变量test.c:
int main() {
printf("global=%d\n", global);
return 0;
system("pause");
}
test2.c:
int global = 10;
编译会发现出错,global未定义的标识符。这是因为C中函数或变量使用之前要先有声明或者定义,用extern表示声明。其中extern可以省略。声明语句不能进行初始化,生命相当于一个“空头支票”。下面加上声明,会发现程序运行正确。
extern int global;
int main() {
printf("global=%d\n", global);
return 0;
system("pause");
}
那假如我们把test2.c注释掉,会出现如下错误:
表示链接错误,原因是只看到变量或函数声明,没有在其他文件中找到对应定义。
假如把注释改为static,会发现也出现同样的错误。
结论:一个全局变量被static修饰,改变了这个变量的作用域,使得这个全局变量只能在本源文件内使用,不能再其他源文件内使用。
3.修饰函数
与全局变量一样。
示例:
test.c:
int main()
{
extern int Add(int x, int y);
printf("%d\n", Add(2, 3));
return 0;
system("pause");
}
test2.c:
int Add(int x, int y)
{
return x + y;
}
此时编译运行出来结果是正确的,但是如果在test2.c第一行最前面加上static,就会出现和之前一样的错误。这里一定要记得加声明,如果不加的话,没有错误,但会出现警告。运行程序时要尽可能的减少警告,这是一种内在的隐患。警告的内容是:
“Add”未定义;假设外部返回 int。这里假设正确了,确实是返回int但一旦我们把程序改的复杂,改为返回double,这是它在猜int的话,自然程序就有错误了。
结论:一个函数被static修饰,使得这个函数只能在本源文件内使用,不能在其他源文件内使用。
二、指针
内存:
可以把内存想象成超市门口的一排存储柜,这上面有很多小柜子,每个小柜子都能存储一个字节的数据,每个小柜子都有一个标号(从0开始,依次递增),把这个标号称为地址。
可以创建一个变量(重新申请一个内存空间),就用这个内存空间来存储某个地址,这个存储了地址的变量,就是“指针变量”。
啥是指针呢?
指针是一个变量,变量里存了一个整数,有特定的含义,就是内存中的一个地址。通过指针变量,就可以查看到指针变量里存储的那个内存地址是啥,进一步,就可以根据这个内存地址找到对应的内存空间(往里面存储或者读取数据)。就比如,每个小柜子都会给一个小条,通过它,我们就可以找到这个柜子,扫描,就可以打开,可以往里面放东西,也能取出里面的东西。
int main()
{
int num = 10;
#//取出num的地址
printf("%p\n", &num);//打印地址,%p——以地址的形式打印
return 0;
system("pause");
}
int* p=#
int* 表示变量P的类型就是int* 类型。所谓的指针变量其实是一类统称:int*、char*、double*。
C语言中,*至少有三种用法:
1.乘
2.前面带类型,表示指针类型(整体)
3. *后带了一个指针变量,*表示“解引用操作”或者“间接访问操作”。
三、结构体
本质上是一个自定义类型
struct Stu
{
char name[20];
int age;
char sex[5];
char id[15];
};
struct Stu s = { "张三",20,"男","20210101" };//打印结构体信息
printf("name=%s age=%d sex=%s id=%s\n", s.name, s.age, s.sex, s.id);//.为结构成员访问操作符
}
name、age这些是结构体的成员变量/属性/字段。
结构体的关键用法:成员访问