700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > #define 定义常量和宏 指针和结构体

#define 定义常量和宏 指针和结构体

时间:2021-07-15 09:39:25

相关推荐

#define 定义常量和宏 指针和结构体

目录

#define 定义常量和宏

#define 定义常量

#define 定义宏

指针

内存

指针变量的大小

结构体

#define 定义常量和宏

#define 定义常量

在变量和常量2,#define 定义的标识符常量中,就了解到#define可以定义常量。

定义一个符号叫做NUM,这里我们可以给它赋值,可以直接打印它的值,也可以创建一个数组,数组的大小用NUM(此时NUM是一个常量)。

#define NUM 100int main(){printf("%d\n", NUM);int n = NUM;printf("%d\n", n);int arr[NUM] = { 0 };return 0;}

运行证明,无论是直接打印,还是用NUM 创建一个数组都是没有问题的。

#define 定义宏

宏是有参数的

之前求两个数之和的时候,我们写了一个函数来求,这里我们写个宏来求两数之和。

#define ADD(x,y) ((x)+(y))定义一个宏叫做ADD,

ADD是宏名,(x,y)是宏的参数,参数是无类型的,((x)+(y)) 是宏体。

int Add(int x,int y) 这是函数的写法

{

return x + y;

}

#define ADD(x,y) ((x)+(y))int main(){int a = 10;int b = 20;int c = ADD(a, b);printf("%d\n", c);return 0;}

运行得到结果30,成功完成两数加和的任务。

宏和函数非常相似,但宏是宏,函数是函数,这里还是见识一下就可以了。

指针

内存

在说指针之前,不得不先说一下内存.

内存是电脑上特别重要的存储器,计算机中程序的运行都是在内存中进行的 。

这个我们在register-寄存器中就提到过。

control+alt+delete打开任务管理器,就能看到内存的使用情况,每一个程序都占有内存,都在使用内存,那这些程序是怎么使用的呢?首先要加载到内存里面去。

当我们买电脑时说8G/16G,那这8G/16G不可能直接使用吧,所以为了有效的使用内存,就把内存划分成一个个小的内存单元,每个内存单元的大小是1个字节

这一个个小的内存单元就像生活中一个个房间一样,每个房间都有一个地址。

此比如说有五层楼,每层十个房间,共五十个房间,这时如果我说我在某一个房间里,你是不是要一层一层转,一间一间的去找,但要这时给这五十个房间编号了,101,102,103……,我说我在305时305是门牌号,同时更是一个地址。

生活中是这样,内存同样如此,只要给内存每一个小的内存单元编号,这样我去找这些内存空间的时候就非常的方便。

内存会划分为一个个小的内存单元(一个内存单元的大小:1byte)每个内存单元都有一个编号。这时一个32位的电脑,地址是通过地址线通电生成的,通电就会产生电信号,电信号就是1/0(正脉冲或者负脉冲);32位的电脑上有32根地址线,这时32跟地址线,每根地址线都有电信号,那32根地址线同时产生电信号地址的可能是:

00000000000000000000000000000000——>0

00000000000000000000000000000001——>1

……

1111111111111111111111111111111111111

所有产生电信号的组合是有2的32次方

2的32次方个地址序列就是2的32次方个字节的空间

那到底是多大呢?我们打开电脑的计算器调到程序员,点击BIN也就是二进制,输入100000000000000000000000000000000

然后点击DEC也就是十进制,得到的数字也就代表4,294,967,296byte

然后除以1024就能得到KB,再除以1024就能得到MB,再除以1024得到GB

最后我们算出,如果一个内存单位是一个字节,那么在32位的电脑上,管理的就是4GB的内存

当前我们都是64位的电脑,所以电脑内存是8G/16G/32G都是很常见的。

这里有人要问一个内存单位为什么不用一个bit比特位呢?

因为1bit不太合理,比如我创建一个变量c,char c; c就得1byte,1byte就是8bit

想象一下1bit一个内存单元,光一个c就占8bit,八个地址,char已经是C语言中最小的类型,那int呢,那不32个地址就没了,就跟生活中寄快递一样,我给你放到宿舍第五个平方米上,是不是没有必要,寄到房间是不是就可以了。

所以出于各种综合考虑,最后规定一个内存单位是1byte。

为什么要说内存呢,因为创建变量就是像内存申请空间

int a = 10;这个代码的含义就是向内存申请4个字节,储存10。

&a;取a的地址,&是取地址符号

按F10调试,并打开窗口监视,输入a,值是10,输入&a,就能查看a的地址

同时还可以查看内存,也是点击调试——窗口——内存(注意:只有先调试才能看到)

因为不知道地址是什么,在地址窗口输入&a,回车,看到0x0116fd60,就是a的地址,然后把列调成4,一行就是4个字节——0a 00 00 00。

十进制是由0~9的数字组成的,八进制是由0~7的数字组成的,十六进制本来应该是0~15的数字组成,但后面的10~15是不是就会重复,所以这里用a~f分别对应10~15,所以10就用a表示

所以内存中的0a 00 00 00,存的就是10(至于为什么是倒着存,我们后面说,现在只要知道现在看内存倒着往回看就是你存的数字就可以了)

a的地址也可以打印出来,打印整型用%d,打印地址用%p,printf("%p\n", &a);

这时a的地址就是002CFF1C,因为每一次运行程序,a变量都会重新创建,所以地址变化了,和上一次不一样,因为二进制打印起来太长,看起来不够方便,所以用十六进制打印出来。

那地址能不能存起来?当然可以,那怎么写呢

int* p = &a;把a的地址放到一个变量p里面,p的类型叫做int*

这里的p就叫做指针变量

为什么叫指针变量呢?

前面我们说到了内存单元,内存单元有编号,编号就是地址,地址也被称为指针

所以指针就是地址,就是内存单元的编号,而p是用来存这个地址,这个编号的,那也意味着用来存指针的,所以把用来存放指针(地址)的变量叫做指着变量

注意:变量的名字叫p,而不是*p,而p的类型是int*

依此类推,那这时创建char ch = 'w'

pc =&ch; 那这时pc的类型是什么,是char*

int* p = &a; p里存放了a的地址,那p就有机会能找到a,那怎么找呢

*p = 20;*是解引用操作符,意思就是通过p中存放的地址,找到p所指向的对象,*p就是p指向的对象。

打印出了20,证明我们通过指针里的地址,然后解引用找到了a,并成功改掉了a的值。

这里就说了,在操作符中单目操作符漏掉的两个操作符——&*。

注意:辨析指针和指针变量,指针就是地址,指着变量是用来存放地址的,像我们口头语说的p是个指针,这个指针其实指的是一个指针变量,注意口头语的表达

指针变量的大小

int* p;char* p2;指针的创建有不同的类型,那不同类型的大小是什么样的呢

运行结果我们发现都是4,那为什么都是4呢?

因为不管是什么类型的指针,都是在创建指针变量,指针变量是用来存放地址的,指针变量的大小取决于一个地址存放的时候需要大多空间。32位机器上的地址:32bit位 - 4byte,所以指针变量的大小是4个字节,64位机器上的地址:64bit位 - 8byte,所以指针变量的大小是8个字节。

上面得到4,是在X86下运行的的结果(X86的意思就是32位平台),这时将其改成X64(就是64位平台),结果就成8了。

最后说一下创建指针变量的写法:char* pc;char *pc;

vs编译器喜欢char* pc;这样写,当你写完加上分号时,会自动跳成这样,这样写char*合在一起是一个类型,但连续定义多个指针时,int* p1, p2, p3; 你认为int*定义的p1, p2, p3都是指针吧,其实并不是,*只是给p1用了,p2, p3都只是拿到了int类型,你要想p1, p2, p3都是指针,就要int *p1, *p2, *p3;这样写,这时*跟着更能让你理解,p2,p3并不是指针。

这两种写法没有绝对的好,主要看个人习惯

结构体

前面我们说了数据类型(char,short,int,long,float,double),你用这些类型表示一个数完全没有问题,但现在要用这些类型表示一个人,人是一个复杂对象,要想表示一个人得有名字,年龄,地址,电话……,那再表示一本书,书得有书名,作者,出版社,定价,书号……

我们就发现这些复杂对象,不能简单用这种内置类型来描述了,这时C语言就给了自定义的能力,

自定义的类型中有一种叫结构体,而结构体的关键字叫做struct。

结构体是吧一些单一类型组合在一起的做法。

这时我们描述一个学生

先定义struct用{}把需要描述的变量括起来(注意{}后的不能掉),然后创建一个主函数

结构体访问它的对象用的是.操作符(结构体对象.成员名),这种用法的前提条件是得到一个结构体对象。

struct Stu{//成员char name[20];int age;char sex[10];char tele[12];};int main(){struct Stu s = {"zhangsan", 20, "nan", "15596668862"};//结构体对象.成员名printf("%s %d %s %s\n", s.name, s.age, s.sex, s.tele);return 0;}

不想直接打印,取出s的地址,传给print函数。

void print(struct Stu* ps){printf("%s %d %s %s\n", (*ps).name, (*ps).age, (*ps).sex, (*ps).tele);}int main(){struct Stu s = {"zhangsan", 20, "nan", "15596668862"};print(&s);return 0;}

觉得这样写太麻烦,改成

void print(struct Stu* ps){//结构体指针变量->成员名printf("%s %d %s %s\n", ps->name, ps->age, ps->sex, ps->tele);}int main(){struct Stu s = {"zhangsan", 20, "nan", "15596668862"};print(&s);return 0;}

这里又学了一个操作符->,用法:结构体指针变量->成员名(这种用法的前提条件是得到了一个指针)

到这里,C语言基础语法概览就说完了,相信大家对C语言有哪些知识应该有一个轮廓了,只是这些知识没那么深入,没关系,后面再逐步抽丝剥茧,一点点去说。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。