由于这些天有其他事情耽搁了,关于初识C语言(3)的部分一直没能更新(也是最后一部分),今天抽出时间来更新一下初识C语言的最后一部分。
初识C语言(3)- 1.常见关键字
- 1.1 关键字typedef:
- 1.2 关键字static -- 静态的
- 2.#define定义常量和宏
- 3.指针
- 3.1内存的理解
- 3.2指针变量的大小
- 4.结构体
- 4.1 (.)操作符
- 4.2 (->) 操作符
1.常见关键字
⚠️:
1)常见关键字是不能自己创建的。
2)关键字不能是变量名。
接下来介绍几个关键字的用法,进一步加深理解关键字。
1.1 关键字typedef:typedef是类型定义,这里应该理解为类型重命名。
比如:
//将unsigned int 重命名为uint_32
typedef unsigned int unit_32;
int main()
{
//这时,num1和num2这两个变量的类型是一样的,这就是typedef的用法。
unsigned int num1 = 0;
uint_32 num2 = 0;
return 0;
}
1.2 关键字static – 静态的
在C语言中,static是用来修饰变量和函数的。
1)修饰局部变量 – 称为静态局部变量
2)修饰全局变量 – 称为静态全局变量
3) 修饰函数 – 称为静态函数
在了解这些变量之前,我们先了解一下静态变量在内存中是处于哪一块吧。 --> 内存是一块比较大的存储空间,在使用内存时会划分出不同的功能区域。在目前的学习阶段,只需要了解有:栈区、堆区、静态区就好了。
1)static修饰局部变量:
通过下面代码的输出我们来比较一下不加static和加入static来修饰局部变量的区别。
//code 1 不加static #include//在这里不需要函数返回任何值,所以使用void void test() { int a = 1; a++; printf("%d ", a); } int main() { int i = 0; while(i < 10) { test(); i++; } return 0; } //code 2 用static修饰局部变量 #include //在这里不需要函数返回任何值,所以使用void void test() { static int a = 1; a++; printf("%d ", a); } int main() { int i = 0; while(i < 10) { test(); i++; } return 0; }
根据两个代码的结果推断出,如果使用static修饰局部变量时,每调用一次test函数,使用的(a)都是上一次函数调用留下的(a),出了局部变量的作用域范围并没有被销毁。
根据结果可以得出:
- static修饰局部变量时,其实改变的是变量的存储类型,从栈区存储变为了静态区存储。
- 静态的局部变量出了自己的作用域也不会被销毁,相当于改变了局部变量的生命周期。
2)static修饰全局变量:
在一个源文件下建立两个.c文件,如果想要在当前代码1中使用代码2或其他文件(外部文件)的全局变量,需要先声明一下。
//code 1 test.c #include//extern是一个关键字,专门用来声明外部符号。 extern int g_val; int main() { printf("%dn", g_val); return 0; } //code 2 Add.c //g_val 是一个全局变量 int g_val = 2021;
通过代码的运行,我们可以看到在代码1中声明之后,是可以使用代码2中的全局变量的。
//code 1 test.c #include//extern是一个关键字,专门用来声明外部符号。 extern int g_val; int main() { printf("%dn", g_val); return 0; } //code 2 Add.c //g_val 是一个全局变量 static int g_val = 2021;
相同的代码,当我们使用static修饰全局变量后,我们发现代码1不能再次使用代码2中的全局变量。
通过代码的运行我们能得到:
全局变量能够在整个工程的其他文件内部被使用,是因为全局变量具有外部链接属性。但是当一个全局变量被static修饰的时候,这个全局变量的外部链接属性就变成了内部链接属性(本身源文件外,其他人看不到了)。使得这个全局变量只能在自己所在的源文件内部使用,其他源文件内部不能使用了。给我们的感觉是作用域变小了。
3)static修饰函数:
使用static修饰函数和修饰全局变量是非常相似的。
函数本来也具有外部链接属性。但是被static修饰的时候,就变成了内部链接属性。这个函数也是只能在自己所在的源文件内部使用,不能在其他文件内部使用,作用域变小。
//#define定义常量 #include//#define定义常量时是:#define + 名 + 参数 #define X 100 #define SKY "sky" int main() { printf("%dn", X); printf("%sn", SKY); return 0; }
//#define定义宏 #include//#define定义宏时是:#define + 宏名(参数) +宏体 #define ADD(X, Y) ((X) + (Y)) int main() { int a = 10; int b = 20; int ret = ADD(a, b); printf("%dn", ret); return 0; }
在初识中,现在只需要知道#define的两种用法,具体的后面在来学习。
内存是电脑上特别重要的存储器,计算机中程序的运行都是在内存中进行的 。
所以为了有效的使用内存,就把内存划分成一个个小的内存单元,每个内存单元的大小是1个字节。
为了能够有效的访问到内存的每个单元,就给内存单元进行了编号,这些编号被称为该内存单元的地 址。
因为变量是创建在内存中的,每个内存单元都有地址,所以变量也有地址。
下面的就让我们用代码标识如何取出变量的地址:
#includeint main() { int num = 10; # //取出num地址,& -->是取地址符。 printf("%pn", &num); //打印地址,%p是以地址的形式打印 return 0; }
因为num是整形变量,整形是4个字节,一小块内存为1个字节,每个字节都有地址,所以占用了4小块内存。
取出的第一块字节的地址,就是num 的打印地址。
即然有地址,那么肯定就有存储的办法,地址的存储需要方式使用指针变量来实现的。
#includeint main() { int num = 10; int *p = # //int *p就是指针变量,专门用来存储地址 *p = 20; //*是解引用操作符,*p的意思是通过p中的值,找到p所指向的对象,*p也就是num,赋值20就是把num的值给改为20. printf("%dn", num); return 0; }
通过结果我们可以看到,*p找到了num的地址,然后把20赋值给了num,把原来num = 10的值进行了改变。
指针变量的大小取决于平台。
在32位平台下地址就是32个bit位(即4个字节)。
在64位平台下地址就是64个bit位(即8个字节)。
#includeint main() { printf("%dn", sizeof(char *)); printf("%dn", sizeof(short *)); printf("%dn", sizeof(int *)); printf("%dn", sizeof(double *)); printf("%dn", sizeof(float *)); return 0; }
因为我使用的是64位平台,所以输出的指针大小都为8字节。
指针方面我们在初识中就了解到这里,后面进行指针进阶学习的过程中,再来针对指针这个大方面进行复习总结。
4.结构体结构体是C语言中特别重要的知识点,结构体使得C语言有能力描述复杂类型。
接下来我们来简单的了解一下结构体。
比如描述学生,学生包含: 名字+年龄+性别+学号 这几项信息, 这里只能使用结构体来描述了。
例如:
//描述一个学生的结构体
struct stu
{
char name[20]; //名字
int age; //年龄
char sex[5]; //性别
char id[15]; //学号
}; //这里有一个分号,不能省略!!!
结构体成员访问的操作符有:(.)和(->)。
4.1 (.)操作符//. 操作符是结构体成员访问的操作符 //表达形式为:结构体变量.结构体成员 #include4.2 (->) 操作符//结构体 struct stu { //结构体成员 char name[20]; int age; char sex[10]; char id[15]; }; int main() { //创建结构体变量,并初始化 struct stu zhangsan = {"张三", 22, "man", "202110216"}; //结构体打印的数据 printf("nanme = %s age = %d sex = %s id = %sn", zhangsan.name, zhangsan.age, zhangsan.sex, zhangsan.id); return 0; }
//-> 也是结构体成员访问操作符 //表达形式为:结构体指针->结构体成员 #include//结构体 struct stu { //结构体成员 char name[20]; int age; char sex[10]; char id[15]; }; int main() { //创建结构体变量,并初始化 struct stu zhangsan = {"张三", 22, "man", "202110216"}; //->操作符 struct stu *p = &zhangsan; //结构体打印的数据 //p->name,就是pl指向的对象是结构体变量zhangsan的成员name printf("nanme = %s age = %d sex = %s id = %sn", p->name, p->age, p->sex, p->id); return 0; }
通过结果我们可以发现,使用->结构体成员访问操作符也能打印出来结构体的数据,而且要比 . 操作符更为简单。
学习到这里,初识C语言的过程就已经算结束了,通过1,2,3的学习,可以大概了解下C语言的各个方面,接下来的学习就是进阶学习各个方面的内容。如果感觉有帮助的小伙伴可以关注一下,我会不定时更新C语言从0到1的学习过程。



