1. c语言的特性
A: c语言是一种底层语言
B: c 语言是一种小型语言
C: c 语言一种包容性语言,c语言假设用户知道自己做什么,
所以她提供了更为广阔的自由度。
优点:
高效
可移植性,c语言编译器规模小,容易编写。
功能强大
灵活
标准库
与UNIX 系统结合紧密
缺点:
出错率高
难理解
难以修改
2. gcc
gcc( GNU Compiler Collection)
基本用法: gcc [options] [filenames]
-c 只编译,生产.o 为后缀的目标文件,通常用于编译
不包含主程序的子程序文件。
-o output_filename 确定输出文件的名称为
-g 产生符号调试工具gdb 所必要的符号资讯
-O 大写哦对程序进行优化编译
-O2 比-o 更好的优化编译
-std 例如: -std= c89 或者-std=c99
c程序(小全)宏观认识(代码角度,和内存角度)
一个较为完整的程序中,可以包含哪些部分?【描述记忆】
//系统头文件
#include...
//宏定义
#define....
//全局变量
int data = 1;
//自定义函数的声明
int main() //主函数
{
//局部变量 local
int data=2;
for() //if switch while
{
//块变量
int data = 3;
}
}
//自定义函数
。。。。。
C程序在内存中的分布?
程序段
:代码段存放程序代码的一段区域,程序段是只读的。
数据段
:存放已经初始化的全局变量。
bss段
:通常用来存放程序中未初始化的全局变量和静态变量的一块内存区域
堆
堆:保存进程中被动态分配的内存
申请:malloc remalloc(new) OC(alloc new init)
释放:free delete OC(release)
栈
栈:存储了程序中临时创建的局部变量
变量,生命周期,作用域
1.1 局部变量:【准确记忆】
我们把在函数体中定义的变量叫做这个函数的局部变量。
Int main()
{
Int a,b,c,d........//局部变量
}
Int test()
{
Int a; //局部变量
}
局部变量的特点;
1 生命周期:从定义这个局部变量的地方开始,到函数的结束。
- 作用域(访问范围):在定义这个局部变量的函数内(定义这个变量的以下语句);
1.2 静态局部变量
Static 修饰的局部变量:
特点【描述记忆】
1 生命周期:整个程序
2 作用域:和普通变量一样。
- 值:数值就是上一次函数调用结束之后的数值。
#include <stdio.h>
int test(){
static int i=0;
i++;
printf("i = %d\n",i);
return 0;
}
int main()
{
int i=0; //这里的i和test里面的i不一样
for(;i<6;i++)
{
test();
}
return 0;
}
结果如下:
1.3 全局变量
:定义在整个程序中的变量称为全局变量
- 生命周期:整个程序的生命周期之内
- 作用域(访问范围):整个程序的范围内都可以访问
- 值:没有初始化的全局变量的数值是0.
1.4 块变量
:定义在语句块里面的变量叫做块变量。
程序块(语句块):使用{}括起来的一组语句。
块变量的特性:
- 生命周期:定义变量的地方开始,程序块结束的地方消失
- 作用域(访问范围):程序块内
for(......)
{
Int i = 0; //块变量
}
If(......)
{
Int temp = i ; // 块变量
}
变量优先级:局部优先原则
#include <stdio.h>
int data = 1;
int main()
{
printf("data = %d\n",data);
int data = 2; //局部变量
printf("data = %d\n",data);
if(1)
{
int data = 3; //块变量
printf("data = %d\n",data);
}
return 0;
}
结果如下:
关键字修饰变量
Auto static register
Static 修饰全局变量
访问范围:只能在本文件访问。
即使在其他文件中使用extern声明也不能使用
Static 修饰函数
访问范围:
这个函数只能在本文件中使用
什么是自动变量?
普通局部变量(static除外)都是auto ,auto 一般省略。
Auto int i;
Register: 寄存器变量
:告诉编译器这个变量会被频繁的使用,请保存到寄存器中。
使用限制【描述记忆】
- 必须能被cpu的寄存器接受(32位= 4个字节)
- 不能对寄存器变量取地址 &
概念:
类型:每个变量都必须声明她的类型。C可分为基本数据类型和复合数据类型
声明:任何变量在使用之前必须进行声明。如:数据类型变量名称
初始化:
- 自动变量未初始化的时候访问,其数值是一个随机数值。
#include <stdio.h>
int main()
{
int day;
printf(“day = %d\n”,day);
return 0;
}
标识符:在编写程序的时候,需要对变量,函数,宏,以及其他实体进行命名,这些名称成为:标示符。
标示符有五条命名规则:
- 以字母,下划线开头;
- 可以包含字母,下划线,数字
- 大小写敏感
- 不能和关键字冲突
关键字:
特性:
有特殊含义的一串字符
全部小写
标准库中函数名全部小写
字符串
字符串的三种表示方式的区别?
- 字面值。存在于全局区,不可改变。在内存中只有一个。
- Char 数组存在于内存中函数栈,数值可以改变
Char str[] = “abcde”;
//赋值的时候
Str = “abcde”;
3. Char * 既可以指向字面值,也可以指向char 数组里面的元素。
格式化输入/输出:
printf( 格式字符串,表达式1,表达式2,。。。。) //可变长参数
格式字符串可分为两个部分:普通字符和转换说明
转换说明包含以下几部分:
完整格式: % - 0 m.n l或者h 格式字符
1. % 占位符 不能省略
2. - 左对齐,省略右对齐
3. 0 代表空位填0 省略代表空位不填
4. m 域宽 n 精度
5. l 整数long, 浮点数double ; h为 short;
6. i /d 输出十进制整数
O 无符号的八进制整数
X 十六进制
u 无符号的十进制
c 输出一个字符
s 输出一个字符串
f 输出一个浮点数
e 以指数的形式输出浮点数
g 在f和e格式之间选择一个较短格式输出
P 输出一个地址
%m 输出全局error中错误
2 %i%d
在printf里面没有区别
在scanf 有区别
%d 只匹配十进制
%i 八进制 十进制,十六进制
3 如何输出%
%%
4. 4 scanf() 从键盘输入
绝大数情况下,scanf 只包含转换说明。
scanf(格式字符串,地址列表);
例如:scanf(“%f%f%f”, &s1, &s2, &s3);
整数在内存中的存储? 【准确记忆】
整型在内存中的存储是按照补码形式存储的。整数的补码与源码相同,
负数的补码就是其绝对值的二进制形式按位取反,然后整个数值加 1.
进制转换 【理解描述】
sizeof 是c语言的一个关键字,不是函数。
sizeof(变量的名字) 或者sizeof (类型)
sizeof 返回一个对象或者类型所占的内存字节数
sizeof 三种语法方式 b*****b 【准确记忆】
1. sizeof(类型)
2. sizeof(变量名)
3. sizeof(表达式)
int i=5;
sizeof(i=10);
运算符:
算数运算符:+ - * / %
- / 0不能做除数,两个整数相除,取结果的整数部分。
- % 要求操作数都为整数,如果其中一个不是整数,编译将无法通过。
赋值运算符
Int i,j;
复合赋值 += -= *= /= %=
自增、自减
比较运算符: ==
推荐写法:if(15 == data)
逻辑运算符的
短路特性 b*****b【准确描述】
&& || ?:
例子:
#include <stdio.h>
int main()
{
int i=0, j=0;
if(++i || ++j);
if(--i && ++j);
printf("i = %d,j = %d\n",i,j);
return 0;
}
位运算符
按位取反~3
按位与 &
用途: b***b 【记忆描述】
经常用来屏蔽某些二进制位(置0)。也可以知道某个二进制位是1还是0。
按位或 |
用途: b***b【记忆描述】
经常用来将某些二进制位(置1)。也可以知道某个二进制位是1还是0。
按位异或 ^
运算规则:b*****b 【准确记忆】
对应的二进制位上的数字相同则为0,否则为1。
例子:判断某个整数二进制格式倒数第三位是0还是1?
If(data &4) ==4) 倒数第三位1
左移
规则: b*****b 【准确记忆】
左移的时候右边的空位补零
右移
规则:b*****b 【准确记忆】
右移的时候左边补上符号位。
取地址运算
条件运算符
表达式1?表达式2:表达式3
语句
if else 语句
switch 语句
结构
Switch(控制表达式)
{
Case 常量表达式1 :语句1;
Case 常量表达式2 : 语句2;break;
....
Default: .....
}
注意:
控制表达式:计算结果是整型
常量表达式:不能包含变量或者函数调用,最终结果必须是整数。
例如:n+10 不是常量表达式(除非n是表示常量的宏),
每个分支中可以包含多条语句,可以不使用{}
循环语句:
for(表达式1;表达式2;表达式3)
{
语句;
}
执行流程 表达式1 ==》 表达式2==〉循环语句==》表达式3==〉表达式2==》。。。
注意:可以这样写for(;;){....}
for(i=0;i<10;i++){...}
C99 第一个表达式可以为声明例如:
for(int i=0; i<10; i++){....}
for(i=0,j=0;i<10; printf(),i++,j++){....}
for循环可以嵌套
C语言中两种常用的无限循环(死循环)方式?
while(1)
for(;;)
do-while 循环
从键盘读入: scanf
键盘--》 键盘缓冲区--〉 输入缓冲区--》程序。
#include<stdio.h>
int main()
{
int data_1 = 0, data_2 = 0;
printf("请输入两个整数:");
scanf("%d",&data_1);
scanf("%d",&data_2);
printf("您输入的两个整数是:%d %d\n",data_1,data_2);
return 0;
}
分析: scanf 失败的原因: 类型不匹配
改成如下:
#include<stdio.h>
int main()
{
int data_1 = 0, data_2 = 0;
printf("请输入两个整数:");
if(scanf("%d",&data_1) == 0)
{
scanf("%*[^\n]");
scanf("%*c");
}
if(scanf("%d",&data_2) == 0)
{
scanf("%*[^\n]"); //读走\n之前的所有字符
scanf("%*c");//读走字符包括之前匹配到的(*) c代表字符
}
printf("您输入的两个整数是:%d %d\n",data_1,data_2);
return 0;
}
输出缓冲区
程序--》输出缓冲区--〉屏幕
程序的输出可以到达屏幕的条件: b*****b 【描述记忆】
1,\n
- 程序结束
- 输出缓冲区满(4kb)
- 人工刷新(fflush)
例子:
#include <stdio.h>
int main()
{
printf("welcome!");
while(1);
}
结果:没有输出
#include <stdio.h>
int main()
{
printf("welcome!");
fflush(stdout); //新增加的人工刷新
while(1);
}
字符串
读取一个字符串放到字符数组中,然后打印
scanf(“%s”,&name);
scanf 遇到空白字符结束
gets(name)
从输入设备读取一行字符回来,放到name中
危险:gets 不会考虑name的大小,可能导致name的溢出。
fgets(name,20,stdin);
fgets会在整个字符串的后面添加\n
操作字符串的库函数
Strcpy
Strcat
Strncpy
Strncat
Strlen:
strcmp:
数组和结构 (聚合类型)
数组:
一维数组初始化
Int a[5] = {1,2,3} ; //【可描述】如果初始化里面常量表达式个数小于数组元素的个数,剩余的元素初始化为零。
指定初始化
Int a[30] = { [19] = 54, [9]=> 14, [29] = 45 };
#include <stdio.h>
int main()
{
int a[10];
printf("sizeof(a[0]) = %d\n",sizeof(a[0]));
printf("sizeof(a) = %d\n",sizeof(a));
char c[10];
printf("sizeof(c[0]) = %d\n",sizeof(c[0]));
printf("sizeof(c) = %d\n",sizeof(c));
return 0;
}
结果如:
获取数组的个数?
宏带参数的宏:
#define sz(a) sizeof(a)/sizeof(a[0])
c99中的变长数组
Int n;
Scanf(“%d”, &n);
Int a[n]; //c99变长数组
函数
函数的返回值
:函数的返回值必须和return 返回值的类型一致
- 如果函数没有返回值指定为void
- C语言的返回值类型可以省略默认为int
隐式声明:如果函数在使用之前没有进行声明,编译器会创建一个隐式声明,返回值类型为int
值传递:c语言中实际参数和形式参数之间采用值传递的方式来传递数据。
#include <stdio.h>
void swap(int a,int b){
int t=a;
a=b;
b=t;
printf("swap:交换中:a = %d b=%d\n",a,b);
}
int main()
{
int x=5,y=7;
printf("main:交换之前:x= %d y= %d\n",x,y);
swap(x,y);
printf("main:交换之后:x= %d y= %d\n",x,y);
return 0;
}
结果如下:
什么时候使用const来修饰形参?【描述记忆】
如果形参传递的是地址,又不希望在被调用函数更改地址上的内容这个时候可以使用const修饰形参。
例如:
Int test(const int r[],int len)
{
r[len-1] = 100;
}
指针作为返回值
注意:【描述记忆】
不要返回自动变量的地址。因为自动变量在函数结束之后所使用的内存会被释放。
预处理
1.1 文件包含
#include <xxx.h>
#include “xxx.h”
区别:
<>到系统指定的路径寻找一般是:/usr/include
“” 优先从当前目录开始,一般适用于自定义头文件。
宏
1 简单的宏
2.带参数的宏
//使用宏判断两个整数中最大的那个
#define MAX(x,y) (x)>(y)?(x):(y)
注意: todo;
参数不能是多次计算之后的数值
MAX(i++,j++) //这是错误的
应该在每个参数的外面加上()
在整个表达式的外面加上()
例子:
#include <stdio.h>
#define MUL(x,y) x*y
int main()
{
printf("结果:%d\n",MUL(3,5));
printf("结果:%d\n",MUL(1+2,2+3));
return 0;
}
结果:
8不对呀!
#define MUL(x,y) (x)*(y)
改成上面这样就对了
printf(“结果:%d\n”,30/MUL(3,5));
应该是2结果是50;
还要改,改成下面:
#define MUL(x,y) ((x)*(y))
宏运算符# 和##
- #
#运算符有许多用途,这里只来讨论其中的一种。#运算符将宏的一个参数转换为字符串字面量。#运算符所执行的操作可以理解为“字符串化(stringization)”
#define PRINT_INT(n) printf(#n " = %d\n",n)
会变成:
printf("i/j" " = %d\n",i/j);
等价为printf("i/j = %d\n",i/j);
如果要被“字符串化”的参数包含“或\字符,#运算符会将"转换为\",\转换为\\。考虑下面的宏:
#define STRINGIZE(x) #x
预处理器会将STRINGIZE("foo")替换为”\“foo\""。
- ## 将两个标识符粘贴在一起形成一个标识符
#define MAX(type) type max_##type()
MAX(float) 对应如下:float max_float()
#define MK_ID(n) i##n
int MK_ID(1),MK_ID(2),MK_ID(3);
预处理后这一声明变为:int i1,i2,i3;
注意:##的宏通常不能嵌套调用
#define cat(x, y) x ## y那么,宏调用cat(var, 123)将生成var123。但是,宏调用cat(cat(1,2),3)没有定义
预定义的宏
1 __LINE__
2 __FILE__
3 __DATE__
4 __TIME__
5 __STDC__ //判断编译器是否符合c 标准 返回0或者1
1.5 条件编译:
条件编译就是根据预处理器的执行结果来包含或者排除某一段程序。
#if #endif
defined : 判断一个宏(有没有定义过这个宏)
#define Debug
#ifdefined Debug
....
#endif
3 #ifdef // 等价于 #if defined
4 #else
#if ...
代码
#elif ...
代码
#else
代码
#endif
为什么要用条件编译?
【描述记忆】
1,编写多种硬件环境或者多操作系统上运行的可移植程序。
2,编写用于不同编译器的程序。
#if __STDC__
函数
#else
函数
#endif
3. 产品的调试与发布
4. 为宏提供定义
多源文件的程序编译方法?
1 首先对每一个源文件只编译不连接
gcc -c .....
生成xx.o 文件
2 连接成为一个可执行程序
gcc *.o
自定义的头文件
- 共享宏定义
- 全局变量的声明
- 类型定义共享
extern int r //告诉编译器,该变量已经在其他文件
例子:
解决方法:把test.c中的添加一行 extern int speed;
重复包含一个头文件,可能会导致编译错误。怎么做呢?
【描述记忆】
正确的自定义头文件的编写。
例如:
Test.h
#ifndef TEST_H
#define TEST_H
#include <stdio.h>
#define DISTANCE 1270
#define OIL 13
#endif
makefile
描述:makefile 由很多规则组成,一条规则可以分为:
目标文件:依赖文件
命令(生成目标文件所执行的指令,可以是多条)
结构
定义:
typedef struct
{
成员列表
} 别名;
使用结构指针作为函数的参数和返回值的时候,可以使程序的效率提高!
结构体位段
位段/位域
struct s{
Int i:3; //指定i在内存中占用3个二进制位。
Int b:1;
.....
}
例子:
#include <stdio.h>
//结构体类型的声明
struct test
{
char c1:1;
char c2:2;
char c3:3;
};
int main()
{
printf("sizeof(struct test) = %d\n",sizeof(struct test));
return 0;
}
结果如下:
联合
1, 可以有多个不同类型的成员的组成
2,通过成员的名字访问成员
3,所有成员公用起始地址相同的一段内存
#include <stdio.h>
union
{
int i;
double d;
} test;
int main()
{
printf("sizeof(union test) = %d\n",sizeof(test));
return 0;
}
结果:
大端:低地址存储高位数据
小端:低地址存储低位数据
大小端更详细说明: http://blog.csdn.net/u013862108/article/details/78961961
枚举类型
规则:enum 枚举名{枚举常量}; //枚举常量之间使用逗号分隔
#include <stdio.h>
int main()
{
enum color {RED,BLUE,GREEN};
//本质上枚举常量就是整数
enum color c;
c = 0; //仅限c语言中
c = BLUE;
printf("RED=%d BLUE=%d GREEN=%d\n",RED,BLUE,GREEN);
return 0;
}
结果如下:
内存分配
自动变量:内存都是操作系统维护的。
堆:自己申请自己释放
栈:自动分配自动释放
动态分配内存的函数malloc calloc realloc
Malloc -- 分配内存块,不会对分配的内存进行初始化
Calloc -- 分配内存块,对内存进行清零
Realloc -- 调整先前已经分配的内存块的大小
malloc :
Void * malloc(size_t size)
malloc 分配size字节的内存,返回指向这块内存的指针
#include <stdio.h>
#include <stdlib.h>
int main()
{
int n = 0, i=0;
printf("请输入数组的大小:");
scanf("%d",&n);
int *q = (int *)malloc(n*sizeof(int));
if(q == NULL)
{
//分配失败
printf("error:分配失败\n");
return 0;
}
for(;i<n;i++)
{
q[i] = i+1;
}
for(i=0; i<n; i++)
{
printf("%d ",q[i]);
}
printf("\n");
free(q); //释放动态内存
q = NULL; //置为空指针
return 0;
}
结果:
字符串的malloc分配
Char *q = (char *)malloc(n+1);
结构体的malloc分配
Struct employee *e = (struct employee *)malloc(sizeof(struct employee));
Void * calloc(size_t nmemb, size_t size);
Calloc 为nmemb个元素分配内存,每一个元素都是size 个字节大小,自动清零
realloc
:可以根据需求动态的调整已经分配好的内存。
参数几种情况:
- 内存扩张,realloc 不会初始化扩张的内存
- 失败了,返回空指针,不会影响原来块中的数据
- 第一个参数NULL, 相当于malloc
- 第二个参数0,释放原来的内存块
文件
文件指针:就是指向FILE结构体的指针。
FILE * fp; //fp就是一个文件指针
文件的操作
fopen: 打开一个文件
fclose: 关闭一个文件
文件的读写
Int fputs() 将一个字符写到文件中
fgetc(); //从文件中读一个字符出来 ?
#include <stdio.h>
int main(int argc ,const char *argv[])
{
FILE *fp = NULL;
if(argc<2 || argc>2)
{
printf("命令的格式不对\n");
printf("Useage:command filename\n");
return 0;
}
if((fp = fopen(argv[1],"r")) == NULL)
{
printf("文件打开失败:%m\n");
return 0;
}
char c;
while(1)
{
c = fgetc(fp);
if(c==EOF)
break;
else
printf("%c",c);
}
fclose(fp);
return 0;
}
例子: fgetc, fputs 文件的复制功能?
/*文件复制*/
#include <stdio.h>
int main(int argc ,const char *argv[])
{
if(argc !=3)
{
printf("格式不对\n");
return 0;
}
FILE *fp1 = NULL;
FILE *fp2 = NULL;
if((fp1 = fopen(argv[1],"r")) == NULL)
{
printf("打开%s失败\n",argv[1]);
return 0;
}
printf("成功打开%s文件\n",argv[1]);
if((fp2 = fopen(argv[2],"w")) == NULL)
{
printf("打开%s失败\n",argv[2]);
fclose(fp1);
return 0;
}
printf("成功打开%s文件\n",argv[2]);
char c;
while(1)
{
c = fgetc(fp1);
if(c== EOF)break;
else
fputc( c,fp2);
}
fclose(fp1);
fclose(fp2);
return 0;
}
C语言提供的读写数据块的函数
Size_t fread(buffer,size,count,fp)
Size_t fwrite(buffer,size,count,fp)
使用fwrite 写两个整数到文件中?
/*文件复制*/
#include <stdio.h>
int main(int argc ,const char *argv[])
{
int i=15, j=63;
FILE * fp = NULL;
if((fp = fopen("c.txt","w")) == NULL)
{
printf("fail to open the file:%m\n");
return 0;
}
printf("success to open the file\n");
fwrite(&i,sizeof(i),1,fp);
fwrite(&j,sizeof(i),1,fp);
fclose(fp);
return 0;
}
查看写入的结果:
使用fread 读出来?
/*文件复制*/
#include <stdio.h>
int main(int argc ,const char *argv[])
{
int i = 0,j = 0;
FILE *fp = NULL;
if((fp = fopen("c.txt","r")) == NULL)
{
printf("fail to open the file:%m\n");
return 0;
}
printf("success to open the file\n");
if(fread(&i,sizeof(i),1,fp)!=1)
{
printf("读取失败\n");
}
if(fread(&j,sizeof(j),1,fp)!=1)
{
printf("读取失败\n");
}
printf("i = %d j=%d\n",i,j);
fclose(fp);
return 0;
}
执行结果如下:
文件的定位 rewind
Rewind 函数使位置指针回到文件的开头。
Fseek 函数
Int fseek (FILE *stream,long offset, int whence)
Stream: 文件指针
Offset: 位移量
Whence: 起始点
文件开头0 SEEK_SET
当前位置1 SEEK_CUR
文件末尾2 SEEK_END
保存三个员工的信息(struct) 到文件中,然后显示出来?
#include <stdio.h>
typedef struct
{
int ID;
char name[30];
float salary;
} employee;
int main(int argc ,const char *argv[])
{
employee e[3] = {{1, "赵志",500},{2,"月月",500.5},{3,"阿龙",600}};
FILE *fp = NULL;
if((fp = fopen("d.txt","w+")) ==NULL)
{
printf("fail to open the file:%m\n");
return 0;
}
printf("success to open the file\n");
int count = 0;
if((count = fwrite(e,sizeof(employee),3,fp))<3)
{
printf("write error:%m\n");
}
fseek(fp,-3*sizeof(employee),SEEK_CUR); //rewind
employee temp;
int i = 0;
for(;i<3;i++){
fread(&temp,sizeof(employee),1,fp);
printf("工号:%d 姓名:%s 薪资:%g\n",temp.ID,temp.name,temp.salar
y);
}
fclose(fp);
return 0;
}
运行结果如下:
文件读写的其他函数
Fgets fputs
从指定文件中读取或者写入一个字符串
char str[500] //fgets(str,n,fp) n 为指定读取字符的个数,但是fp只能读出n-1 最后加’\0’
fputs
fprintf 和fscanf 格式化读写注意:效率低,大量数据用fread fwrite
标准库
stdlib.h
无法划归到其他头文件中的
字符串,数字,产生随机数,内存管理 系统通信搜索排序等
c语言的声明
声明int *p[3]; 使用如:*p[i] , “声明的形式和使用的形式相似” 这种用法可能是C 语言独创的,其他语言没有采取这种方法。贝尔实验室学者们也承认批评有理,但他们坚决死扛原来的决定,至今依然。
声明是如何构成的?
声明器declaratory) : 就是标示符以及与它组合在一起的指针,函数括号,数组下表等。
数量 |
C语言中名字 |
出现的形式 |
零个或多个 |
指针 |
下列形式之一: *const volatile *volatile * * const *volatile const |
有且只有一个 |
直接声明器 |
标示符 标示符[下标] 标示符(参数) (声明器) |
零个或一个 |
初始化内容 |
= 初始值 |
不合规则的声明,或声明中存在的限制条件?
-
-
-
- 函数的返回值不能是一个函数
- 函数的返回值不能是一个数组
- 数组里边不能有函数 。如foo[]() 是非法的
-
-
结构的声明
例如:
struct { 内容。。。} plum , pomegranate, pear;
struct fruit_tag { 内容。。。} plum ,pomegranate, pear;
更常用的,或更建议的声明方式是:
struct veg { int weight, price_per_lb; }; //类型声明,可与php中类对比类的声明,实例化
struct veg onion,radish, turnip; //变量的声明
联合的声明?
联合一般是作为大型结构的一部分存在的。联合一般被用来节省空间
实际工作中,结构的使用的次数将远远大于联合。
枚举的声明?
一般来说,用枚举的地方都可以用#define 来解决。
enum 可选标签{ 内容。。。}可选变量定义;
枚举和#define 对比:枚举具有一个有点:#define 定义的名字一般在编译时被丢弃,枚举名字则通常一直在调试器中可见,可以在调试代码时使用他们。