第十九讲 复合文字结构

    今天的内容不多,所以在讲今天的内容之前,先回答一个同学的提问,有个同学想要写个十进制数转换任何进制,我想大家如同细心的话应该记得我们在递归函数那一讲里面就用递归函数实现了一个十进制转换二进制的小程序,所以我们可以根据那个函数稍作修改便可得到这位同学想要的函数:
—————————–
void  to_anyscale (unsigned long n,int m)
{
int r;

r = n % m;

if (n >= m)
to_anyscale(n/m,m);

if(r<10)
putchar(‘0’+r);

else
putchar(r-10+’A’);

}
————————————
为了验证这个函数的可以性,我们写个main()函数来驱动这个函数试试:
—————————————
#include <stdio.h>#include <stdlib.h>
void  to_anyscale (unsigned long n,int m)
{
int r;

r = n % m;

if (n >= m)
to_anyscale(n/m,m);

if(r<10)
putchar(‘0’+r);

else
putchar(r-10+’A’);

}
int main()
{
unsigned long src;

int scale;

printf(“请输入需要转换的十进制数:n”);

while(scanf(“%d”,&

src))
{
printf(“请输入需要转换的进制数:n”);

scanf(“%d”,&

scale);

to_anyscale(src,scale);

printf(“若要继续,请输入另一个数,若要退出,请输入q或者Q:n”);

}

return 0;

}
—————————————
糟糕,不知道怎么回事,从春节开始微信公众平台似乎好像不能贴图了,也不知道是我浏览器出了问题还是怎么回事,改天用win7的笔记本试试。不过可以告诉大家,这个程序是可行的,大家可以尝试。
复合文字签发不仅适用于数组, 也适用于结构。可以使用复合文字创建一个被用来作为函数参数或被赋值给另一个结构的结构。语法是把类型名写在圆括号中,后跟一个用花括号括起来的初始化项目列表。例如, 下面是一个 struct bookphone 类型的复合文字:
—————————————–
     (struct bookphone)
{“Zhang San”, ”15911111111“ };

—————————————–
这是C99新添加的类型,所以有些编译器可能无法通过,就比如我现在所用的VS2012,他竟然也不支持这么写,但是Ubuntu的GCC却支持这种写法,只是我不太喜欢在Linux下编程,不过没关系,如果大家使用的是VS系列发现不能这么写的话,可以换种写法,在小括号和花括号间用”=“,如下面这种形式:
—————————————-
       struct BookPhone A={“Zhang San”,”15911111111″ };


—————————————-
 struct BookPhone{
char name[20];

char PhoneNumber[12];

};


—————————————
关于struct的声明,C99里面还添加了一个新功能,那就是伸缩型的数组类型。我们可以用伸缩型数组类型来重新定义我们上面的BookPhone结构。
——————————
 struct BookPhone{
char name[20];

char PhoneNumber[];

};


———————————
从上面的定义我们可以得出一个结论:
1. 伸缩型数组成员必须是最后一个数组成员.
2. 结构中必须至少有一个其他成员.
3. 伸缩型数组就像普通数组一样被声明, 除了它的方括号内是空的,其他和数组没有两样。
对于伸缩型的数组的使用我们可以像上面一样用复合字符结构来使用他,但是如果我们像下面这样使用的话,会是什么情况呢?
—————————————
struct BookPhone{
char name[20];

char PhoneNumber[];

};

int main()
{
struct BookPhone A;

printf(“请输入名字:n”);

gets(A.name);

printf(“请输入电话号码:n”);

gets(A.PhoneNumber);

printf(“%s : %sn”,A.name,A.PhoneNumber);

system(“PAUSE”);

return 0;

}
———————————–
因为我们用了一块来历不明的内存,所以会导致内存泄漏,那么怎么才能安全使用他呢?
要想安全使用这种伸缩型的结构,在声明对象的时候就要对他进去内存分配?怎么分配?当然用malloc了。
————————————–
      struct BookPhone* A = (BookPhone*)malloc(sizeof(BookPhone)+sizeof(char)*12);


—————————————–
malloc是C/C++标准库函数,不过也只是在C里面使,C++的话有更好用的new和delete操作符,不过由于我们现在还没说C++的特性,所以我们这里还是用malloc,malloc和new一样都是动态申请内存的,但是malloc是函数,他要配合free一起用,如果用malloc申请了一块内存,用完之后记得用free释放这块内存,否则就会出现内存泄漏。
从上面的例子,我们应该看得出malloc的使用方法,他需要一个size数据来做参数,这个参数就是需要申请的内存大小,malloc前面括号的类型对于C来说可有可无,但是为了和C++兼容,所以我们这里添加了,因为对于c++来说,这里是必须,否则他不知道会有不明确定义。
当然,在分配好这块内存后,在return之前记得将这块内存释放掉:
free(A);

说到这里,结构也算是说得差不多了吧,不过可能有人会问,那么结构里面可以使用我们自定义的类型吗(结构),当然是可以的,那么可以使用成员函数吗?我的回答是可以又不可以,可以是因为在C++里的结构确实是可以,但是在C里面却不可以,这就是C/C++的区别,那么C里面的结构和C++里面的class有什么区别呢?从设计初衷来说没有多少区别,都是让程序员自定义类型,但是c++的class是面向对象抽象设计的,派生和继承,代码的重用,使得开发过程中减少大量的工作量。当然这些以后再说,关于结构嵌套结构我们会在接下来我们实现一个简单链表中得到实现。
明天的内容:联合类型

发表评论