1:共用体是一种特殊的数据类型,允许您在相同的内存位置存储不同的数据类型
2:您可以定义一个带有多成员的共用体,但是任何时候只能有一个成员带有值
3.共用体占用的内存应足够存储共用体中最大的成员
总结:共用体取成员最大字节,存储多种不同类型数据,但是每次存储,都会影响之前存储的数据,
#include
#include
union Data
{
int i;
float f;
char str[20];
};
int main(int argc, char const *argv[])
{
union Data data;
data.i = 10;
printf("data.i : %d\n", data.i);
data.f = 220.5;
printf("data.f : %f\n", data.f);//data.i值不能在用
strcpy(data.str, "C Programming");
printf("data.str : %s\n", data.str);
system("pause");
return 0;
}
自定义内存空间,使用场景:如果程序的结构中包含多个开关量,只有 TRUE/FALSE 变量,但在实际上,在每个变量中,我们只存储 0 或 1,可以使用位域。
简单说:C语言中没有true/false,只有0和1,定义true/false,完全可以用一个字节
struct
{
unsigned int widthValidated : 1; //超过1位的数,则不能完成,比如3,0x11
unsigned int heightValidated : 1;
} status;
注意:status大小位四字节,首先位域,先取的unsigned int 4字节,32位,尽管只用到了2位,但是会分配一个unsigned内存空间,如果超过32字节,则会再分配unsigned int 4字节。
struct bs{
int a:8;
int b:2;
int c:6;
}data;
——————int ,4字节,32位, 占用4字节
struct bs{
unsigned a:4;
unsigned :4; /* 空域 */
unsigned b:4; /* 从下一单元开始存放 */
unsigned c:4
}
typedef unsigned char BYTE;//unsigned char 类型定义为BYTE
BYTE b1, b2;
#include
#include
#include
typedef struct Books
{
char title[50];
char author[50];
char subject[100];
int book_id;
} Book;
int main()
{
Book book;
strcpy(book.title, "C 教程");
strcpy(book.author, "Runoob");
strcpy(book.subject, "编程语言");
book.book_id = 12345;
printf("书标题 : %s\n", book.title);
printf("书作者 : %s\n", book.author);
printf("书类目 : %s\n", book.subject);
printf("书 ID : %d\n", book.book_id);
system("pause");
return 0;
}
define是宏定义,本质是替换,常量表中并没有用define定义的常量,系统不为它分配内存。
define定义的常量,预处理时只是直接进行了替换,因此在编译时不能进行数据类型检验。
const可以定义常量,于define不同
于typedef区别:
typedef 仅限于为类型定义符号名称
#define 不仅可以为类型定义别名,也能为数值定义别名,本质是替换
#include
#define TRUE 1
#define FALSE 0
int main( )
{
printf( "TRUE 的值: %d\n", TRUE);
printf( "FALSE 的值: %d\n", FALSE);
return 0;
}
1.scanf, 命令行输入
#include
#include
int main(int argc, char const *argv[])
{
float f;
printf("Enter a number: ");
scanf("%f", &f);
printf("Value = %f", f);
system("pause");
return 0;
}
2.getchar() 输入一个字符,返回整数ASII码
putchar,将整数对应于ASII码
#include
#include
int main(int argc, char const *argv[])
{
int c;
printf("Enter a value :");
c = getchar();
printf("%d\n", c);
printf("\nYou entered: ");
putchar(c);
printf("\n");
system("pause");
return 0;
}
3.gets() & puts() 函数
char *gets(char *s) 函数从 stdin 读取一行到 s 所指向的缓冲区,直到一个终止符或 EOF。
int puts(const char *s) 函数把字符串 s 和一个尾随的换行符写入到 stdout。
总结:适合多个字符,也就是字符串
#include
#include
int main( )
{
char str[100];
printf( "Enter a value :");
gets( str );
printf( "\nYou entered: ");
puts( str );
system("pause");
return 0;
}
4.scanf() 和 printf() 函数 ,连续输入
int scanf(const char *format, …) 函数从标准输入流 stdin 读取输入,并根据提供的 format 来浏览输入。
int printf(const char *format, …) 函数把输出写入到标准输出流 stdout ,并根据提供的格式产生输出。
#include
#include
int main( )
{
char str[100];
int i;
printf( "Enter a value :");
scanf("%s %d", str, &i);
printf( "\nYou entered: %s %d ", str, i);
printf("\n");
system("pause");
return 0;
}
与java一致,文件存在,则打开,文件不存在,则创建新的文件
FILE *fopen( const char * filename, const char * mode );
mode:为模式,
模式 | 描述 |
---|---|
r | 打开一个已有的文本文件,允许读取文件。 |
w | 打开一个文本文件,允许写入文件。如果文件不存在,则会创建一个新文件。在这里,您的程序会从文件的开头写入内容。如果文件存在,则该会被截断为零长度,重新写入。 |
a | 打开一个文本文件,以追加模式写入文件。如果文件不存在,则会创建一个新文件。在这里,您的程序会在已有的文件内容中追加内容。 |
r+ | 打开一个文本文件,允许读写文件。 |
w+ | 打开一个文本文件,允许读写文件。如果文件已存在,则文件会被截断为零长度,如果文件不存在,则会创建一个新文件。 |
a+ | 打开一个文本文件,允许读写文件。如果文件不存在,则会创建一个新文件。读取会从文件的开头开始,写入则只能是追加模式。 |
wb | 以只写方式打开或新建一个二进制文件,只允许写数据 |
---|---|
wb+ | 以读/写方式打开或建立一个二进制文件,允许读和写 |
ab+ | 以读/写方式打开一个文本文件,允许读或在文本末追加数据 |
如果处理的是二进制文件,则需使用下面的访问模式来取代上面的访问模式:
"rb", "wb", "ab", "rb+", "r+b", "wb+", "w+b", "ab+", "a+b"
int fputc( int c, FILE *fp );
函数 fputc() 把参数 c 的字符值写入到 fp 所指向的输出流中。如果写入成功,它会返回写入的字符,如果发生错误,则会返回 EOF。您可以使用下面的函数来把一个以 null 结尾的字符串写入到流中:
int fputs( const char *s, FILE *fp );
函数 fputs() 把字符串 s 写入到 fp 所指向的输出流中。如果写入成功,它会返回一个非负值,如果发生错误,则会返回 EOF。您也可以使用 int fprintf(FILE *fp,const char *format, …) 函数把一个字符串写入到文件中。尝试下面的实例:
**注意:**请确保您有可用的 tmp 目录,如果不存在该目录,则需要在您的计算机上先创建该目录。
/tmp 一般是 Linux 系统上的临时目录,如果你在 Windows 系统上运行,则需要修改为本地环境中已存在的目录,例如: C:\tmp、D:\tmp等。
tmp临时,改成其他也可以的。
#include
#include
int main(int argc, char const *argv[])
{
FILE *fp = NULL;
fp = fopen("tmp/test2.txt", "w+");//打开文件
fprintf(fp, "This is testing for fprintf...\n");//输入字符串
fputs("This is testing for fputs...\n", fp);//输入字符串,二者等价
fclose(fp);//关闭文件
system("pause");
return 0;
}
int fgetc( FILE * fp );
fgetc() 函数从 fp 所指向的输入文件中读取一个字符。返回值是读取的字符,如果发生错误则返回 EOF。下面的函数允许您从流中读取一个字符串:
char *fgets( char *buf, int n, FILE *fp );
函数 fgets() 从 fp 所指向的输入流中读取 n - 1 个字符。它会把读取的字符串复制到缓冲区 buf,并在最后追加一个 null 字符来终止字符串。
如果这个函数在读取最后一个字符之前就遇到一个换行符 ‘\n’ 或文件的末尾 EOF,则只会返回读取到的字符,包括换行符
int fscanf(FILE *fp, const char *format, ...)
函数来从文件中读取字符串,但是在遇到第一个空格和换行符时,它会停止读取
#include
#include
int main(int argc, char const *argv[])
{
FILE *fp = NULL;
char buff[255];
fp = fopen("tmp/test2.txt", "r");
fscanf(fp, "%s", buff); //遇到空格,换行符,停止
printf("1: %s\n", buff);
fgets(buff, 255, (FILE *)fp); //遇到换行符停止
printf("2: %s\n", buff);
fgets(buff, 255, (FILE *)fp);
printf("3: %s\n", buff);
system("pause");
return 0;
}
fwrite()
size_t fwrite(const void* buffer, size_t size, size_t count, FILE* stream);
注意:这个函数以二进制形式对文件进行操作,不局限于文本文件
返回值:返回实际写入的数据块数目
(1)buffer:是一个指针,对fwrite来说,是要获取数据的地址;
(2)size:要写入内容的单字节数;
(3)count:要进行写入size字节的数据项的个数;
(4)stream:目标文件指针;
(5)返回实际写入的数据项个数count。
fread()
size_t fread ( void *buffer, size_t size, size_t count, FILE *stream) ;
返回值:返回实际写入的数据块数目
从文件流中读数据,最多读取count个项,每个项size个字节,如果调用成功返回实际读取到的项个数(小于或等于count),如果不成功或读到文件末尾返回0
buffer 用于接收数据的内存地址
size 要读的每个数据项的字节数,单位是字节
count 要读count个数据项,每个数据项size个字节.
stream 输入流
fseek()
int fseek(FILE *stream, long offset, int fromwhere);
函数设置文件指针stream的位置。如果执行成功,stream将指向以fromwhere(偏移起始位置:文件头0(SEEK_SET),当前位置1(SEEK_CUR),文件尾2(SEEK_END))为基准,偏移offset(指针偏移量)个字节的位置。如果执行失败(比如offset超过文件自身大小),则不改变stream指向的位置。
(1)stream:文件指针
(2) offset:为偏移量,正数表示正向偏移,负数表示负向偏移
(3) fromwhere:从文件的哪里开始偏移,可能取值为:SEEK_SET,SEEK_CUR、 SEEK_END (对应0 、 1 、 2)