c primer plus第14章总结:结构和其他数据形式
2016-07-15 18:00
429 查看
结构声明:
struct book{ char title(MAX); char author(MAX); float value; };
定义结构变量:
声明:struct book library; 初始化:struct book library = { "abd",// 用逗号隔开 "asd", 1.95 };
访问成员:
gets(library.title); // 不需要带结构名
scanf(“%f”, &library.value); // library.value为float类型
// gets()读取换行符,但舍弃,不会对后续的输入造成影响;优先选择;
结构数组:
struct book library[NAXBOOK]; gets(library[count].title); gets(library[count].title[0]); printf("%s", library[index].title);
嵌套结构:
struct name{ char first[LEN]; char last[LEN]; }; struct guy{ struct name handle;// 声明一个name变量,嵌套; char favfood[LEN]; char jio[LEN]; float income }; struct guy fellow; printf("%s", fellow.handle.first); printf("%s", fellow.job);
指向结构的指针:
struct guy fellow[2]; struct guy* him; him = &fellow[0];// 同一结构类型,不需要带结构名称; printf("%s", him -> handle.first); printf("%s", him -> job); // 指针him->与fellow.的作用等效;
补充
引用:http://www.cnblogs.com/vace/archive/2011/04/14/2015754.htmlC的结构体和C++结构体的区别
(1)C的结构体内不允许有函数存在,C++允许有内部成员函数,且允许该函数是虚函数。所以C的结构体是没有构造函数、析构函数、和this指针的。
(2)C的结构体对内部成员变量的访问权限只能是public,而C++允许public,protected,private三种。
(3)C语言的结构体是不可以继承的,C++的结构体是可以从其他的结构体或者类继承过来的。
以上都是表面的区别,实际区别就是面向过程和面向对象编程思路的区别:
C的结构体只是把数据变量给包裹起来了,并不涉及算法。而C++是把数据变量及对这些数据变量的相关算法给封装起来,并且给对这些数据和类不同的访问权限。C语言中是没有类的概念的,但是C语言可以通过结构体内创建函数指针实现面向对象思想。
C++的结构体和C++类的区别
(1)C++结构体内部成员变量及成员函数默认的访问级别是public,而c++类的内部成员变量及成员函数的默认访问级别是private。
(2)C++结构体的继承默认是public,而c++类的继承默认是private。
函数指针:
void (*p)(char* ); // pf 是一个指向函数的指针; void *pf (char* ); // pf 是返回一个指针的函数;
可以把适当类型的函数地址赋值给函数指针,函数名能表示函数地址;
void ToUpper(char* ); void ToLower(char* ); void (*pf) (char * ); // 声明一个函数指针,可以用来指向ToUpper、ToLower; pf = ToLower; // 赋值;
函数指针用法:
void show (void (* fp )(char *), char * str) { (* fp)( str); // 把函数传给str puts(str); // 显示调用该函数的输出结果 }
补充
引用:http://blog.csdn.net/wujiangguizhen/article/details/17153495
http://blog.csdn.net/newtonnl/article/details/7724649
http://www.cnblogs.com/processakai/archive/2011/06/24/2089345.html
函数指针的好处:
(1)提供调用的灵活性。设计好了一个函数框架,但是设计初期并不知道自己的函数会被如何使用。比如C的”stdlib”中声明的qsort函数,用来对数值进行排序。显然,顺序还是降序,元素谁大谁小这些问题,库程序员在编写qsort的时候不可能决定。这些问题是要在用户调用这个函数的时候才能够决定。那边qsort如何保证通用性和灵活性呢?采用的办法是让函数的使用者来制定排序规则。于是调用者应该自己设计comparator函数,传给qsort函数。这就在程序设计初期保证了灵活性。尽管使用函数指针使得程序有些难懂,但是这样的牺牲还是值得的。
(2)回调函数。Windows编程中的事件handle函数,即回调函数,在事件队列都是一个函数指针来保存的:
typedef void (*event_handler) (unsigned int para1, unsigned int para2);
struct event {
unsigned int ev_id;
event_handler handler;
};
struct event event_queue[MAX_EVENT_SIZE];
程序可以通过扫描这个事件队列来获取每个事件对应的处理函数,然后调用它,即为回调函数。
课后习题
//第11题 transform()接受是个参数,定义一个指针函数,用于接受用户选择的函数;#include "stdafx.h" #include <string.h> #include <ctype.h> #include <stdlib.h> #include <math.h> #include <time.h> #define LEN 100 char showmenu(void); void eatline(void); double add(double x); // 自定义+1函数 double square(double x); // 自定义求平方函数 void transform(double source[], double target[], int n, double (*pfun)(double)); int main(void) { double (*pfun)(double) = NULL; // 指向一个函数,该函数接受source[]的一个double元素; // 返回一个double值,预赋给target[]; double source[LEN] = {0}; double target[LEN] = {0}; int n = LEN; char choice; srand((unsigned)time(0)); for(int i = 0; i < n; i++) { source[i] = rand()/(double)(RAND_MAX/20); //(rand() % 200) / 10.; // rand取得0~INT_MAX随机值,%200取得0~200的整数随机值,除以10得到0~20之间保留一位有效数字的double printf("%.2lf ", source[i]); if ((i + 1) % 10 == 0) printf("\n"); } printf("\n"); while ((choice = showmenu()) != 'n') { switch (choice) // 设置指针 { case 'a' : pfun = add; break; case 's' : pfun = square; break; case 'c' : pfun = ceil; break; // math.h自带函数 case 'f' : pfun = fabs; break; // math.h自带函数 default: break; } transform(source, target, n, pfun); } puts("Bye!"); return 0; } char showmenu(void) { char ans; puts("Enter menu choice:"); puts("a) add c) ceil"); puts("s) square f) fabs"); puts("q) quit"); ans = getchar(); ans = tolower(ans); // 转换用户输入,为小字母 eatline(); while (strchr("acsfq", ans) == NULL) { puts("Please enter a \"a\", \"c\", \"s\", \"f\", or \"q\":"); ans = tolower(getchar()); eatline(); } return ans; } void eatline(void) { while (getchar() != '\n') continue; } void transform(double source[], double target[], int n, double (*pfun)(double)) { for (int i = 0; i < n; i++) { target[i] = pfun(source[i]); } printf("source\ttarget\t\n"); for(int i = 0; i < n; i++) { printf("%.1lf\t%.2lf\n",source[i], target[i]); } } double add(double x) { return x + 1; } double square(double x) { return x * x; }
相关文章推荐
- 基础总结篇之二:Activity的四种launchMode
- git reset --hard 和 git revert
- SQLServer无法删除登录名'***',因为该用户当前正处于登录状态
- UESTC 982质因子分解
- [7.15] 森林,电线杆,和外星人
- 需求分析细节总结2
- 中国剩余定理 不互质
- URAL 2091
- 糗事百科简单爬虫
- URAL 2095
- 2015ACM/ICPC亚洲区上海站 LCM Walk
- vim 查看函数列表
- vim 查看函数列表
- vim 查看函数列表
- serve-static
- vim 查看函数列表
- vim 查看函数列表
- CodeForces 631C
- vim 查看函数列表
- **PHP** 表单(2)-表单完成