c语言结构体概念及作用,C语言结构体

预处理,宏定义->编译指令

结构体,联合体,动态数据结构

逻辑运算符,递归函数

预处理

编译有4个步骤,.c文件->.i文件 预处理 ->.s文件 编译 -> .o文件 汇编 ->可执行文件 链接

gcc -o hello.i hello.c -E-E表示gcc只进行预处理

预处理的第一步是展开头文件

宏定义

#define R 10 定义宏,预处理的时候将宏直接替换,但是将R作为字符串10,然后后面比如int a = R;这里发生的是字符串替换,然后发生了类型转换,宏只是单纯的字符串替换。

#include

#define R 10

#define M int main(

M){

int a = R;

printf("a=%d\n",a);

printf("helloworld\n");

return 0;

}```

反复使用的常量和数组buffer的大小,为了便于修改,`int a[R];`因为不能用变量进行确定大小。

- 宏函数

`#define N(n) n*10 int b = N(a);`

宏替换在预处理阶段只是单纯的替换,而不会进行运算,所以注意四则运算的优先级

include

define R 10

define M int main(

define N(n) n*10

define ADD(a,b) (a+b)

M){

int a = R;

printf("a=%d\n",a);

printf("helloworld\n");

int b = N(a);

printf("b=%d\n",b);

int c = ADD(a,b) * ADD(a,b);

printf("c=%d\n",c);

return 0;

}```

typedef

给变量类型起别名,typedef int tni;是C语句,typedef int* p;

通常对自定义的数据类型起别名,size_t其实是typedef unsigned long size_t;

作用域是在大括号里面,但是宏定义是在整个代码文件中都是起作用的。

结构体的声明和定义

不同类型数据的集合,数组是相同数据类型的集合。

#include

struct weapon{

char name[20];

int atk;

int price;

}weapon_2;//声明和定义在一起,全局变量

//创建了结构体类型

struct{

char name[20];

int atk;

int price;

}weapon_3;//直接定义了变量,后面不能使用来定义新的变量

int main(){

//使用结构体类型声明一个变量

struct weapon weapon_1;//声明和定义分离的方法

return 0;

}```

- 结构体的初始化和引用

include

struct weapon{

char name[20];

int atk;

int price;

}weapon_2;//声明和定义在一起,全局变量

//创建了结构体类型

int main(){

//使用结构体类型声明一个变量

//初始化列表

struct weapon weapon_1={"weapon_name",100,200};//声明和定义分离的方法

printf("%s\n",weapon_1.name);

//结构体数组

struct weapon w[3]={"weapon_4"};//初始化时候需要指定9个常量

printf("%s\n",w[0].name);

return 0;

}```

结构体指针

#include

struct weapon{

char name[20];

int atk;

int price;

}weapon_2;//声明和定义在一起,全局变量

//创建了结构体类型

int main(){

//使用结构体类型声明一个变量

//初始化列表

struct weapon weapon_1={"weapon_name",100,200};//声明和定义分离的方法

printf("%s\n",weapon_1.name);

//结构体数组

struct weapon we[3]={{"weapon_4"},{"weapon_5"}};//初始化时候需要指定9个常量

printf("%s\n",we[0].name);

//结构体指针变量

struct weapon *w;

w = &weapon_1;

printf("name=%s\n",(*w).name);//使用w->name指向运算符来替换(*w).name

printf("name=%s\n",w->name);

//指向结构体数组

struct weapon *p;

p = we;

printf("%s\n",p->name);

p++;

printf("%s\n",p->name);

return 0;

}```

- 共用体

不同类型的变量共享同一块内存地址,结构体大小有一个字节对齐的概念。

include

union data{

int a;

char b;

int c;

};

struct data1{

int a;

char b;

int c;

};

int main(){

union data data_1;

data_1.b = 'C';

data_1.a = 10;

//b会被覆盖掉,共用体长度为最多的决定

printf("%lu\n",sizeof(struct data1)); //12

printf("%lu\n",sizeof(union data)); // 4

return 0;

}```

动态数据结构-静态链表

#include

struct weapon{

int price;

int atk;

struct weapon *next;

};

int main(){

struct weapon a,b,c,*head;

a.price = 100;

a.atk = 100;

b.price = 200;

b.atk = 200;

c.price = 300;

c.atk = 300;

head = &a;

a.next = &b;

b.next = &c;

c.next = NULL;

struct weapon *p;

p = head;

while(p){

printf("%d,%d\n",p->atk,p->price);

p = p->next;

}

return 0;

}```

- 动态链表

include

include

struct weapon{

int price;

int atk;

struct weapon next;

};

struct weapon create(){

//定义3个指针变量

struct weapon head;

struct weapon p1,p2;

int n = 0;

//开辟内存

p1 = p2 = (struct weapon)malloc(sizeof(struct weapon));//分配内存

scanf("%d,%d",&p1->price,&p1->atk);

head = NULL;

while(p1->price != 0){

n++;//元素个数加1

if(n==1){

head = p1;

}else{

p2->next = p1;

}

p2 = p1;

p1 = (struct weapon*)malloc(sizeof(struct weapon));

scanf("%d,%d",&p1->price,&p1->atk);

}

p2->next = NULL;

return head;

}

int main(){

struct weapon *p;

p = create();

while(p){

printf("%d,%d\n",p->price,p->atk);

p = p->next;

}

return 0;

}```

按位与

& | ^ ~ << >>

作用,迅速清零,a&0,保留指定位置,a&128,判断奇偶,a&1

#include

int main(){

int a = 4;

int b = 7;

int c = a&b; //4

printf("%d\n",c);

return 0;

}```

- 按位或

设定数据的指定位置,`a|0xFF`

include

int main(){

int a = 9;// 00001001

int b = 5;// 00000101

int c = a|b;// 00001101

printf("%d\n",c);

return 0;

}```

按位异或

异或,相异才是1,定位翻转,a^0xFF,数值交换a=a^b;b=b^a;a=a^b;

#include

int main(){

int a = 9;//00001001

int b = 5;//00000101

int c = a^b;//00001100

printf("%d\n",c);

return 0;

}```

- 左移右移

将数据对应的二进制值左移或者右移几位

include

int main(){

int a = 3;

a = a << 4;

printf("%d\n",a);

return 0;

}```

左移几位就相当于乘以2n,右移就是除以2n,如果有符号最高位不会变化,右移符号位是1,就会补1,乘法运算的话用左移就会速度更快。

递归调用

递归会牺牲效率

#include

//求阶乘

int jiecheng(int n){

if(n<0){

printf("error\n");

return -1;

}

if(n==1){

return 1;

}

return n*jiecheng(n-1);

}

int main(){

int n;

printf("please input n\n");

scanf("%d",&n);

int result;

result = jiecheng(n);

printf("%d\n",result);

return 0;

}```

- 递归原理

函数调用的过程中,函数体内又调用了自己,递归-栈

递推构造低阶规模

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值