结构体的参数传递
结构体的形参或实参传递和和一般的程序一样:
#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);
}
通过分析可得
函数指针是一个指向函数的指针,而指针函数只是说明他是一个返回值为指针的函数,
函数指针可以用来指向一个函数。