十二:#define定义常量和宏
12.1:#define定义的标识符常量
#define 定义的一个标识符常量,这里的M是一个符号不是变量,但是是全局的。
(注意**:箭头指向的语句后边千万不能加分号**。我在这里就老出错)
12.2:#define定义的宏
#define Max(x,y) (x>y?x:y) int main() { int a = 10; int b = 20; int c = Max(a, b); printf("%d\n", c); return 0; }
代码第一行就是定义了一个宏,其中Max叫做宏的名字,(x,y)叫做宏的参数,(x>y?x:y)叫做宏体。它的用法和函数一样。
宏是如何工作的呢?
当编译器检查到main里面的Max的时候,发现Max是一个宏,此**时Max(a,b)会被宏体替换。**如下:
int c = Max(a, b); int c = (a > b ? a : b);//上面的语句被替换成这个
宏和函数的区别:
函数的参数有类型,宏的参数没有类型,宏用来处理逻辑简单的结构,而函数用来处理逻辑复杂的结构。
十三:指针
13.1:内存
内存是计算机上的一种存储空间,像我们平时使用的电脑,有8G的和16G的,程序运行的时候会载入内存,程序中如果有数据需要存储也会申请内存空间。
内存是如何使用的呢?
为了有效的使用内存,就把内存划分成一个个小的内存单元,每个内存单元的大小是1个字节。为了能够有效的访问到内存的每个单元,就给内存单元进行了编号,这些编号被称为该内存单元的地址。
进制:(只是数值的表现形式)
16进制中最大的数字15可以由2进制的1111来表示,所以2进制转16进制时,就是4个2进制位转化成1个16进制位。
13.2:指针
如何取地址:
&就是取地址符,%p是专门打印地址的。
在定义a的时候,就向系统申请了连续的4个字节用来存储a,但取a的地址打印的时候只取了a所占4个字节中的第一个字节的地址。
左边框起来的是内存的地址,因为地址是由16进制数字表示出来的,所以是0x开头的(0开头的数字是8进制)。右边框起来的是内存的数据,红色圆圈圈起来的是一个字节,1个字节等于8位bit,也就是一个字节由8个2进制位,4个2进制位表示一个16进制位,所以一个字节由两个16进制位组成。
地址的用处:
可以先把地址存起来,有朝一日通过这个地址找到你,地址只不过是一个16进制的数字
int main() { int a = 1; int* pa = &a; printf("%p\n", &a); printf("%p\n", pa); return 0; }
其中pa是一个变量,这个变量用来存放地址,而地址又叫指针,所以C语言中把pa叫指针变量(指针变量是存放指针的变量),pa变量的类型是int*型,取出a变量申请的4个字节中的第一个字节的地址,把他给pa。&a和pa的值一样。
解引用操作:
*pa//通过pa中的地址找到a,*pa就是a
int main() { int a = 1; int* pa = &a; *pa = 20;//*pa就是a,就相当于---a = 20; printf("%d\n", a);//此时打印出来的a的值是20 printf("%p\n", &a); printf("%p\n", pa); return 0; }
指针就是地址
口语中指针一般指的是指针变量
13.3:指针变量的大小
x86是32位机,此时两个指针变量的大小都是4个字节
为什么32位机上指针变量的大小都是4个字节?
原因:指针变量是用来存放地址的,32位机器上地址是由32个bit位组成,64位机器上地址是由64个bit位组成的。所以32位机器上指针变量存放的是32bit的地址,64位机器上指针变量存放的是64bit的地址,而32个bit位就是4个字节(1个字节8个bit位)。所以32位机器上,指针变量的大小是4个字节。同理,64位机器上,指针变量的大小是8个字节。
x64为64位机器,此时两个指针变量的大小都是8个字节。(其中%zd打印的是无符号整型,这里也可以用%zu。sizeof返回的是一个无符号数字,%u打印32位机下的无符号整型)
十四:结构体
- char
- short
- int
- long
- long long
- float
- double
- 以上这些都是C语言的内置类型
当我们想描述一本书的时候,书有书名、作者、出版社、定价等信息,描述一个人的时候有姓名、性别、身高、体重、年龄等信息。可以发现书和人都是一个复杂对象,我们很难只用一个上面提到的C语言内置类型来描述清楚,因此我们希望高出一种复合类型,可以把书的各种信息都包含进去,这时C语言就提供了一些自定义的类型,用户可以自己定义了类型。
自定义类型:
- 结构体
- 枚举
- 联合体
结构体的关键字是struct,他就表示结构体
14.1:如何定义一个结构体类型?
假设我们想描述一个学生,学生包含:姓名、性别、年龄。三个信息。下面代码就定义了一个学生类型:
struct Stu { char name[20];//用来存放姓名 char sex[5];//用来存放性别 int age;//用来存放年龄 };
其中定义的name、sex、age叫做结构体的成员
14.2:如何创建一个结构体类型的变量?
和创建整型变量、字符型变量、浮点型变量等的方法一样,我们需要有它的类型和变量名,如下面代码中,学生类型就用struct Stu 来表示,变量名是s
struct Stu { char name[20]; char sex[5]; int age; }; int main() { struct Stu s; return 0; }
14.3:结构体列类型的初始化
struct Stu s = {"zhangsan","男",20};
此时我们就初始化了一个学生变量s,它的名字叫zhangsan,性别是男,年龄为20岁。
14.4:如何取到结构体的成员?
s.name//取名字 s.sex//取性别 s.age//取年龄
具体实例:打印出s的姓名、性别、年龄
可见如果要得到结构体里的成员用 . 这个操作符就可以。结构体变量. 成员名,就可以
假如我们有了结构体变量s的地址,我们还可以用下面这两种方法来得到结构体里的成员
struct Stu* ps = &s;//这里定义了一个结构体类型的指针变量ps,用来存放结构体类型变量s的地址 (*ps).name,(*ps).sex, (*ps).age//方法一:通过指针变量的解引用操作*ps就等于s,然后再用.操作符来取到结构体中的成员 ps->name,ps->sex,ps->age//方法二:用->来得到结构体成员
实例:
结构体的指针->成员名
初识C语言的分享到这里就正式结束啦!
今天就分享到这里啦,喜欢的话可以点赞、评论和收藏哟!