2021-02-05

结构体的参数传递

结构体的形参或实参传递和和一般的程序一样:

#include<stdio.h>
#include<string.h>
 
struct student      #结构体定义
{
    char name[10];
    int age;
    double height;
};
void chack(struct student *s) #和一般的程序一样也要改成指针
{
    strcpy(s->name,"LiLin");
    s->age=80;
    s->height=180;
}
  
int main()
{
    struct student monitot={"WangLu",10,100};
    printf("改变之前:name=%s age=%d height=%.2f\n",monitot.name,monitot.age,monitot.height);
    chack(&monitot);  #取结构体地址
    printf("改变之后:name=%s age=%d height=%.2f\n",monitot.name,monitot.age,monitot.height);
    return 0;
}

文件的包含

#include <stdio.h>

#include "stdio.h"

使用了<>符号,如#include <stdio.h>,表示系统会到默认目录(编译器及环境变量、工程文件所定义的头文件寻找目录)中寻找要包含的文件stdio.h

使用""符号,如#include "stdio.h"表示系统先到用户当前目录,即项目所在目录查找所包含的文件stdio.h,如果找不到,再到默认目录中寻找所要包含的文件。

大小端和字节序

字节序,是指的超过一个字节的数据类型在内存中存储的顺序

例如:0x12345678,其中0x12为高地址位,0x78为低地址位。

大端字节序:高位字节数据存放在低地址处,低位数据存放在高地址处;

小端字节序:高位字节数据存放在高地址处,低位数据存放在低地址处;

判断方法:

#include <stdio.h>
        
int main (int argc, char **argv)
{      
     unsigned int    a  = 0x12345678;
      unsigned char  *c  =  (unsigned char *)&a;
   
     if(*c == 0x78)
        printf("Little endian\n");
    else if(*c == 0x12)
         printf("Big endian\n");
     else         
         printf("Not know");
    return 0;  
 }              

位域

在结构体定义时,我们可以指定某个成员变量所占用的二进制位数(Bit),这就是位域。

struct bs{
    unsigned m;
    unsigned n: 4;
    unsigned char ch: 6;
};

:后面的数字用来限定成员变量占用的位数。成员 m 没有限制,根据数据类型即可推算出它占用 4 个字节(Byte)的内存。成员 n、ch 被:后面的数字限制,不能再根据数据类型计算长度,它们分别占用 4、6 位(Bit)的内存。

C语言标准规定,位域的宽度不能超过它所依附的数据类型的长度。通俗地讲,成员变量都是有类型的,这个类型限制了成员变量的最大长度,:后面的数字不能超过这个长度。

位域的存储

1) 当相邻成员的类型相同时,如果它们的位宽之和小于类型的 sizeof 大小,那么后面的成员紧邻前一个成员存储,直到不能容纳为止;如果它们的位宽之和大于类型的 sizeof 大小,那么后面的成员将从新的存储单元开始,其偏移量为类型大小的整数倍

#include <stdio.h>
int main(){
    struct bs{
        unsigned m: 6;
        unsigned n: 12;
        unsigned p: 4;
    };
    printf("%d\n", sizeof(struct bs));
    return 0;
}

2) 当相邻成员的类型不同时,不同的编译器有不同的实现方案,GCC 会压缩存储,而 VC/VS 不会。

#include <stdio.h>
int main(){
    struct bs{
        unsigned m: 12;
        unsigned char ch: 4;
        unsigned p: 4;
    };
    printf("%d\n", sizeof(struct bs));
    return 0;
}

3)如果成员之间穿插着非位域成员,那么不会进行压缩。

struct bs{
    unsigned m: 12;
    unsigned ch;
    unsigned p: 4;
};

无名位域

位域成员可以没有名称,只给出数据类型和位宽

struct bs{
    int m: 12;
    int  : 20;  //该位域成员不能使用
    int n: 4;
};

函数指针

一个函数不仅可以带回一个整型数据的值,字符类型值和实型类型的值,还可以带回指针类型的数据,使其指向某个地址单元。

返回指针的函数,一般定义格式为:

类型标识符 *函数名(参数表)

int *f(x,y);

其中x,y是形式参数,f是函数名,调用后返回一个指向整型数据的地址指针。f(x,y)是函数,其值是指针。

#include 'stdio.h'
main()
{
char *ch(char *,char *);
char str1[]='I am glad to meet you!';
char str2[]='Welcom to study C!';
printf('%s',ch(str1,str2));
}
char *ch(char *str1,char *str2)
{
int i;
char *p;
p=str2

if(*str2==NULL) exit(-1);
do
{
       *str2=*str1;
       str1++;
       str2++;
}while(*str1!=NULL);
return(p);
}

通过分析可得

函数指针是一个指向函数的指针,而指针函数只是说明他是一个返回值为指针的函数,

函数指针可以用来指向一个函数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值