C Primer+Plus(十四)结构和其他数据形式

第14章 结构和其他数据形式

基础概念性的内容在谭浩强C的笔记里已经记录过,不再抄记。选出以下重点巩固:

1、结构的指定初始化项目

C99支持该功能;对于:

struct stu

   char name[10];

    int age;

    float score;

}

可以在定义其结构变量时候初始化该变量的某几项数据,如下:

struct stu s1={.name[10]="Tommy",.score=97.5};

struct stu s2={.age=15};

2、结构数组

对于上述stu结构,创建其变量数组:

struct stu s[10];

成员的引用标识:

s[0].name[10];s[9].score;

3、指向结构的指针

对于上述stu结构,创建其指针变量:

struct stu *ps;

结构指针变量对成员的引用标识:

ps->name[10];ps->score;

若有:struct stu fx,s[10];

则可如下对结构指针变量进行初始化;

ps=&fx;

ps=&s[i];//0<=i<=9;

4、结构信息作为函数参数

(1)结构成员信息作为参数

(2)如下例:

a:以结构地址(指针)作为参数

struct stu
{  
   char name[10];
   int age;
   float score;
}     //结构原型
struct stu *ps,s1;   //结构变量和结构指针变量声明
s1={"tommy",15,87.5};   //结构变量赋值
ps=&s1;   //结构指针变量赋值
void show_age(struct stu *);  //函数声明
show_age(ps);
void show_age(struct stu *p)
{
   printf("age=%d.
",p->age);
}           //函数原型

b:直接以结构作为参数

struct stu
{  
   char name[10];
   int age;
   float score;
}     //结构原型
struct stu s1;   //结构变量声明
s1={"tommy",15,87.5};   //结构变量赋值
void show_age(struct stu x);  //函数声明
show_age(s1);
void show_age(struct stu m)
{
   printf("age=%d.
",m.age);
}           //函数原型

5、结构变量之间的直接赋值
struct stu s1,s2;

s1={"wangming",16,99.0};

s2=s1;  //可直接赋值整个结构

6、使用结构数组的函数

注意:结构变量名不等同于结构变量的首地址;而数组名等同于该数组首地址。

对于结构数组而言,其首先是一个数组,故结构数组名等同于该结构数组首地址。

7、联合(union)

联合是一个能在同一个存储空间内,但不同时,存储不同类型数据的数据类型。

如下联合模板例子:

union hold{

    int digit;

    double bigfl;

    char letter;

}

关键词union限定该数据类型在一个时刻只能含有三个成员中的其中一个。

union hold A;

A.letter="R";

union hold B=A;

union hold C={88};

union hold D={.gibfl=118.2};

B.letter="A";   //可以更改值

B.digit=15;   //也可以更换成员类型,此时内存消除之前的A字符,使用2字节存储15数字

B.bigfl=15.09;   //此时消除15,使用4字节存储浮点数据15.09

8、枚举类型(enumerated type)

9、typedef

可以用typedef创建某一类型的名字,如:

type unsigned char Byte;   //为unsigned char类型创建了Byte名称

Byte a;      //创建Byte类型的变量a

10、指向函数的指针

void ToUpper(char *);  //空返回值的函数

void (*pf)(char *); //指针,指向空返回值的函数

void *pf(char *);//函数,返回值是一个指针

void ToUpper(char *);
void ToLower(char *);
int round(double);
void (*pf)(char *);
void X1(int *);
pf
=ToUpper; //合法,pf指向为空返回值和字符型参数的函数,符合ToUpper描述 pf=ToLower; //合法,同上原因 pf=X1; //不合法,参数不匹配
pf
=round; //不合法,pf指向空返回值的函数,而round是一个返回值为整型的函数 pf=ToLower(); //不合法,pf是指针变量,ToLower()标识的是函数的返回值

综上,要使用一个指向函数的指针,首先要定义,在使用的时候,要使该指针指向某一函数,并且该函数的返回类型和参数类型均须与函数指针定义时候一致。

考虑下面这个函数:

void show(void (*pf)(char *),char *str);

函数show有两个参量:函数指针pf(指向一个空返回值和字符参量的函数)、字符指针str。

例14-16的另一种实现方案:

  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<ctype.h>
  4 int showmenu(void);
  5 typedef void(*V_fp)(char *);  //自定义一个函数指针类型
  6 void eatline(void);   //读至行末
  7 void show(V_fp fp,char *str);
  8 void ToUpper(char *);  //把字符串转为大写
  9 void ToLower(char *);  //把字符串转为小写
 10 void Transpose(char *);  //大小写置换
 11 void Dummy(char *);     //不改变
 12 
 13 int main(void)
 14 {
 15   char line[81];
 16   char copy[81];
 17   int choice;
 18   V_fp pfun;
 19   V_fp x[4]={ToUpper,ToLower,Transpose,Dummy};
 20   puts("Enter a string(empty line to quit):");
 21   while(gets(line)!=NULL&&line[0]!='') //将输入赋给line
 22   {
 23      choice=showmenu();
 24      while(choice>=0&&choice<4)
 25      {
 26           strcpy(copy,line);
 27       show(x[choice],copy);
 28           choice=showmenu();
 29      }
 30      puts("Enter a string(empty line to quit):");
 31    }
 32    puts("Bye!");
 33    return 0;
 34 }
 35 
 36 int showmenu(void)
 37 {
 38   char ans;
 39   int i;
 40   puts("Enter menu choice:");
 41   puts("u)uppercase  l)lowercase");
 42   puts("t)transposed case  o)original case");
 43   puts("n)next string");
 44   ans=getchar();
 45   ans=tolower(ans);
 46   eatline();  //消化缓冲区内字符
 47   while(strchr("ulton",ans)==NULL)      //若选项不在预设内
 48   {
 49     puts("please enter a u,l,t,o,or n:");
 50     ans=tolower(getchar());
 51     eatline();
 52   }
 53   switch(ans)
 54   {
 55    case 'u':i=0;break;
 56    case 'l':i=1;break;
 57    case 't':i=2;break;
 58    case 'o':i=3;break;
 59    case 'n':i=4;break;
 60   }
 61   return i;
 62 }
 63 void eatline(void)
 64 {
 65    while(getchar()!='
')
 66      continue;
 67 }
 68 void ToUpper(char *str)
 69 {
 70   while(*str)
 71   {
 72      *str=toupper(*str);
 73      str++;
 74   }
 75 }
 76 void ToLower(char *str)
 77 {
 78    while(*str)
 79    {
 80       *str=tolower(*str);
 81       str++;
 82    }
 83 }
 84 void Transpose(char *str)
 85 {
 86    while(*str)
 87    {
 88       if(islower(*str))
 89          *str=toupper(*str);
 90       else if(isupper(*str))
 91          *str=tolower(*str);
 92       str++;
 93     }
 94 }
 95 void Dummy(char *str)
 96 {
 97 }
 98 void show(void(*fp)(char *),char *str)
 99 {
100    (*fp)(str);
101    puts(str);
102 }
原文地址:https://www.cnblogs.com/tsembrace/p/3166699.html