还是来讲讲c

之前说过一个问题,函数传参是副本机制。但是数组是一个例外,用数组做参数,传递的是一个地址。也就是说,数组这个东西是直逼内存地址的。

数组作为函数参数,会退化为一个指针,一级指针作为函数形式参数传递地址

 

小程序:程序执行20秒以后,实现即时退出,通过控制台来展示信息

int main()

{

int i = 0;

 

while (1)

{

i++;

char str[50];

 

if (i > 20)

{

exit(0);

}

//黑窗口的信息是通过system来进行输出的,要格式化好了在输出

sprintf(str, "title 程序运行%d秒", i);

system(str);//往控制台输出信息

Sleep(1000);

}

 

system("pause");

return 0;

}

下面我们来说一下什么是空指针,什么是野指针。

没有初始化的指针就是野指针,指向了内存里面的垃圾数据。随便指,乱指。

空指针就是让指针指向NULL这个地方,也就是000000

注意,空指针是不可以取值的,因为它指向的是操作系统大哥所用的数据。

 

 

system的处理情况可以直接传入一个字符指针,然后它会遍历里面的值,进行打印输出。

char str[20] = "notepad";

char *p = str;

system(p);

上面这种就会打开记事本

char str1[20] = "notepad";

char str2[20] = "tasklist";

 

void ChangePoint(char** str)

{

//用二级指针保存指针的地址

*str = str1;

}

int main()

{

char *p = str2;

ChangePoint(&p);//函数有副本机制

system(p);//这里指针就被改变了指向

system("pause");

return 0;

}

 

下面来说一下字符串的封装问题。

我们需要自己写一个库,可以对字符串查找,删除,添加,修改等操作。

我们需要建立一个头文件,来声明我们的函数,还有我们需要一个.c文件来来实现里面声明的函数与定义的库。最后我们的主体文件要包含我们的头文件。

字符串封装单独用一个文件来说。

下面来说一下,什么是结构体。

结构体就是多种数据在一起的一个组合。

我们把结构体看成一种数据的集合。

比如一个字符串,用结构体来表示,可以存放它的地址,存放它的长度。

 

结构体分配的内存空间都是独立的。它里面的数据也是你一片连续的内存空间。里面的每个数据存储都是独立的

结构体只又有在创建变量的时候才分配内存。

注意,结构体字符串的复制,只有用sprintf或者strcpy函数复制进去,不能直接进行赋值

结构体变量名与成员名完全可以重名。

无名结构体。

无名结构体也可以叫贵宾结构体,它无法在外部创建一个变量进行访问成员变量,它只能在定义结构体时就定义好变量。相当于是限量发行结构体。

struct

{

char name[20];

int height;

}people1 = { "蒲向鑫", 178 }, people2 = {"唐甜",177};

 

int main()

{

//上面就是初始化了连个匿名结构体

printf("%s,%d\n", people1.name, people2.height);

system("pause");

return 0;

}

 

下面说一下,结构体变量用大括号来赋值,只有在创建并且初始化的时候才可以。

可以将一个结构体变量赋值给另外一个结构体变量,前提是必须是同一个结构体类型。

下面来简单说一下结构体嵌套的使用。

struct Mystruct

{

char str[20];

int num;

};

 

struct Youstruct

{

int data;

char you[20];

struct Mystruct my1;//嵌套一个结构体类型。

};

 

int main()

{

//我们知道嵌套结构体是通过点去访问的,那么嵌套就是双点

struct Youstruct you1;

sprintf(you1.my1.str, "love");

you1.my1.num = 520;

printf("%s,%d,\n", you1.my1.str, you1.my1.num);

system("pause");

return 0;

}

两个相同同结构体之间字符串是不可以单独直接进行赋值的。

 

下面来说一下,结构体内部嵌套结构体的使用。

struct FatherPeo

{

int data;

char name[20];

struct Beijing

{

char str[20];

int num;

};

};

 

int main()

{

//上面就是结构体内嵌结构体

struct FatherPeo t1;

t1.data = 80;

t1.num = 20;

sprintf(t1.name, "pxx");

sprintf(t1.str, "zhangsan");

printf("%d %d %s %s\n", t1.data, t1.num, t1.name, t1.str);

system("pause");

return 0;

}

结构一体内部嵌套一个结构你,内部的结构体成员就像普通成员一样访问就可以了。

注意嵌套一个结构体与嵌套一个结构体变量是不一样。

嵌套一个结构体变量,我们需要用双点去访问。

下面来说一下,结构体数组的问题。

结构体数组无非就是,数组里面的每一个元素都是一个结构体。

初始化按照元素个数进行初始化就可以了。

 

struct People

{

char name[20];

int height;

};

 

int main()

{

struct People p1[2] = { { "pxx", 178 }, { "tt", 177 } };

printf("%x %x %x\n", p1, &p1[0], &p1[1]);//p1与p1[0]的地址都是一样的

//说明结构体数组中的成员在内存里面是一片连续的存储空间

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

system("pause");

return 0;

}

下面来说一下,指针与结构体

结构体的指针是保存结构体变量的地址的。然后可以通过->的形式去访问里面的数据。

结构体指针有两种方法来访问结构体中的数据

第一种->成员名

第二种*p.成员名

 

下面来做一个小例子,用结构体指针做函数参数,改变结构体成员里面的值

struct People

{

char name[20];

int height;

};

void ChangeStructData(struct People *p)

{

//用结构体指针作为函数参数,指针保存的是结构体变量的地址,直逼内存地址,然后修改数据

sprintf(p->name, "tt");

p->height = 120;

}

int main()

{

struct People p1;

sprintf(p1.name, "pxx");

p1.height = 170;

printf("%s %d\n", p1.name, p1.height);//pxx 170

ChangeStructData(&p1);

printf("%s %d\n", p1.name, p1.height);//tt 120

system("pause");

return 0;

}

这里我们必须注意一下。内存必须保证有足够的带大小来存放数据,不管是结构体数据还是数组数据,都要保证有足够的大小来存放这样的数据。

 

这里来说一下,结构体大小的问题

1.结构体的总大小必须是最宽基本类型(char int double float)成员的整数倍。

2.内存要进行字节对齐,字节不对齐,内存地址计算就不规律了,内存寻址时间就会加大。

3.肯定是大于等于所有成员大小和

4.结构体成员的偏移量必须是当前成员的整数倍

 

下面来说一下共用体。

union

大致结构体的很多类似

来说一下,它的内存空间大小。

它里面最大成员空间内存是多大,它就是多大。

这里我来说两个问题:

第一:共用体在任何时候只有一个成员变量存在。那么是什么呢,就是在内存里面,最先赋值的成员变量保留,其他打印出来全都是垃圾数据

第二:共用体的内存==最长成员的内存大小,如果是数组,就按照数组的内存大小来为其分配内存。当然,为了寻址,可能要进行字节填充。注意,必须可以被最小字节整除。

 

共用体什么值会存在于内存当中,就是先赋值的值会存在与内存当中。后面赋的值打出来就是乱码

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值