C语言基础知识

  • 1 编程初步
    • 1.1 标识符
    • 1.2 main()函数
    • 1.3 头文件
    • 1.4 数据类型
    • 1.5 转义符
    • 1.6 算数运算
    • 1.7 变量和声明
    • 1.8 赋值
  • 2 输入和输出
    • 2.1 交互式输入
    • 2.2 格式化输出
  • 3 选择
    • 3.1 关系表达式
    • 3.2 if 语句
    • 3.3 if…else 语句
    • 3.4 if…else 链
    • 3.5 switch 语句
  • 4 循环
    • 4.1 while 语句
    • 4.2 for 语句
    • 4.3 do…while 语句
    • 4.4 break 语句和 continue 语句
  • 5 函数
    • 5.1 函数声明
    • 5.2 标准库函数
    • 5.3 变量的作用域
    • 5.4 变量存储类
    • 5.5 按引用传递
    • 5.6 递归
  • 6 数组
    • 6.1 一维数组
    • 6.2 二维数组
  • 7 字符串
    • 7.1 输入输出
    • 7.2 库函数
    • 7.3 格式化字符串
  • 8 数据文件
    • 8.1 声明、打开、关闭
    • 8.2 读取和写入文本文件
    • 8.3 随机文件访问

1 编程初步

1.1 标识符

三种类型:保留字、标准标识符、由程序员创建的标识符。

1.1.1 保留字
编程语言为特定用途而预先定义的一个字,而且保留字只能用特定的方式用于它的原本用途。

auto default float register struct volatile
break do for return switch while
case double goto short typedef
char else if signed union
continue extern long static void

1.1.2 标准标识符

是C语言中预先定义的字,它们具有预定义的用途,但程序员能够重新定义这个用途。

abs fopen isalpah rand strcpy
argc free malloc rewind strlen
argv fseek memcpy scanf tolower
calloc gets printf sin toupper
fclose isacii puts strcat ungetc

1.1.3 有程序员创建的标识符

C语言的标识符规则:
字母、数字、下划线的任意组合
1、首字符必须是字母或下划线
2、只有字母、数字、下划线可以跟在首字母之后,不允许有空格。不能是保留字。

注意:C语言是大小写敏感的编程语言。

1.2 main()函数

每个程序都必须有一个main()函数。

int main()
{//函数体return 0;
}

1.3 头文件

预处理器命令:#include

名称 函数类型
<assert.h> 诊断程序
<ctype.h> 单个字符测试
<errno.h> 错误检测
<float.h> 系统定义的浮点型界限
<limits.h> 系统定义的整数界限
<locale.h> 区域定义
<math.h> 数学
<stjump.h> 非局部的函数调用
<signal.h> 异常处理和中断信号
<stdarg.h> 可变长度参数处理
<stddef.h> 系统常量
<stdio.h> 输入/输出
<stdlib.h> 多种公用函数
<string.h> 字符串处理
<time.h> 时间和日期函数

1.3.1 <stdio.h>

原型 描述
int fclose (FILE *) 关闭一个文件流
int fflush (FILE *) 使任何被缓冲的但未被写入的输出数据写在输出上;没有定义输入
int fgetc (FILE *) 如果遇到文件结束,从文件返回下一个字符(被转换为一个整数)或EOF
int fgets (char *s, int n, FILE * ) 最多读取n-1个字符到s数组中;在包含在这个数组中的一个换行符停止。这个数组自动地用\0终止
FILE *fopen (char *fname, char *mode) 按指定的模式打开名为fname的文件
int fprintf (FILE * , char * format, args) 在格式字符串的控制下写入这个args到这个文件流
int fputc (int c, FILE *) 写入被转换为无符号字符的c到这个文件流
int fputs (char *s, FILE *) 写入字符串s到这个文件流
int fscanf (FILE *, char *format, &args) 在格式字符串的控制下从这个文件流读取
int fseek (FILE *, long offset, intorigin) 设置这个文件的位置;这个位置被设置从原点偏移字符;这个原点可能是SEEK_SET,SEEK_CUR或SEEK_END,他们分别是这个文件的开始、当前位置或结束
long ftell (FILE *) 如果有错误,返回这个当前文件的-1L的位置
int fgetc (FILE *) 作为一个宏写入fgetc()
int getchar (void) 与getc(stdin)相同
char *gets (char *s) 读取下一个输入行到s数组中,用\0取代换行符
void perror (char *s) 打印这个字符串s和一个与最后一个被报告的错误号(errno)相对应的编译器定义的错误信息
int printf (char *format, args) 在格式字符串的控制下写入输出到标准的输出;相当于fprintf (stdout, char * format, args)
int putc (int c, FILE *) 作为一个宏写入fputc()
int putchar (int c) 与putc (c, stdout)相同
int puts (char *s) 写入这个被一个换行字符跟随的字符串s到stdout
rewind (FILE *) int scanf (char *farmat, &args) 在格式字符串的控制下从标准输入读取;相当于 fscanf (stdin, char *format, &args)
int sscanf (char *s, char *format, &args) 除了输入被从这个s字符串读取之外,相当于scanf()
int sprintf (char *s, char *format, args) 除了输出被写到这个s字符串之外,相当于prinrf();这个字符串以\0结尾并且必须足够大以容纳这个数据
int ungetc (int c, FILE *) 把c(被转换成无符号字符)推回这个文件流之上

fopen的模式包括:
"r"为读取打开一个文件;
"w"为写入打开一个文件,如果文件存在,旧的内容被丢弃;
"a"为在这个文件末尾写入打开一个文件,如果文件不存在,创建一个新文件;
"r+"为读取和写入打开一个文本文件;
"w+"为更新创建一个文本文件,如果文件存在,旧的内容被丢弃;
"a+"为在这个文件末端写入打开一个文件;如果文件不存在,创建一个新文件

1.3.2 <ctype.h>

如果参数满足条件,则返回一个非0(真)整数;如果不满足,则返回一个0(假)数值。

原型 描述
int isalnum (int c) c是文字数字的(文字或数字)
int isalpha (int c) c是一个字母
int iscntrl (int c) c是一个控制字符
int isdigit (int c) c是一个数字
int isgraph (int c) c是可打印的(排除空格)
int islower (int c) c是小写字母
int isprint (int c) c是可打印的(包括空格)
int ispunct (int c) c是可打印的(除了空格、字母或数字之外)
int isspace (int c) c是一个空格、进纸、换行、退格或制表符
int isupper (int c) c是大写字母
int isxdigit (int c) c是十六进制数字
int tolower (int c) 转换c为小写字母
int toupper (int c) 转换c为大写字母

1.3.3 <math.h>

原型 描述
double asin (double x) x的反正弦
double acos (double x) x的反余弦
double atan (double x) x的反正切
double sin (double x) x的正弦
double cos (double x) x的余弦
double tan (double x) x的正切
double sinh (double x) x的双曲正弦
double cosh (double x) x的双曲余弦
double tanh (double x) x的双曲正切
double exp (double x) e的x次方
double fabs (double x) x的绝对值
double floor (double x) 大于x的最大整数
double ceil (double x) 不小于x的最小整数
double fmod (double x, double y) x/y的余数,用x的符号
double mod (double x, double * ip) x的小数部分,用x的符号,x的整数部分,用x的符号,都被ip指向x的y次方
double ldexp (x, n) x*2的n次方
double log (double x) ln(x)
double log10 (double x) log10(x)
double pow (x, y) x的y次方
double sqrt (double x) x的平方根

1.3.4 <stdlib.h>

原型 描述
int abs (int n) 整数的绝对值
long labs (long n) 长整数的绝对值
double atof (char *s) 转换s为双精度型
int atoi (char *s) 转换s为整型
int atol (char *s) 转换s为长整型
int rand (void) 伪随机整数
void srand (unsigned int seed) 伪随机整数用的种子
void *calloc (size_n, size_n) 为n个对象的数组分配空间,每个大小为n,初始化所有被分配的字节为0
void *malloc (size_tn) 为一个大小为n,内容保持与旧的相同,等于新的大小
void *realloc (void *p, size_n) 重新分配空间到大小为n,内容保持与旧的相同,等于新的大小
void free (void *p) 释放指向的空间
void exit (int status) 正常程序终止

1.3.5 <string.h>

原型 描述
char *strcat (char *d, char *s) 连接字符串s到字符串d
char *strncat (char *d, char *s, int n) 连接字符串s中至多n个字符到字符串d
char *strcpy (char *d, char *s) 复制字符串s到字符串d
char *strncpy (char *d, char *s, int n) 复制字符串s中至多n个字符到字符串d;如果s少于n个字符,用\0垫上
char *strcmp (char *d, char *s) 比较字符串d与字符串s;如果d<s,返回<0,如果d==s,返回0,如果d>s,返回>0
char *strncmp (char *d, char *s, int n) 比较字符串d中至多n个字符与字符串s;如果d<s,返回<0,如果d==s,返回0,如果d>s,返回>0
char *strchr (char *d, char *c) 返回一个指向字符串d中c第一次出现的指针,或者如果没有找到c,返回指向NULL的指针
char *strrchr (char *d, char *c 返回一个指向字符串d中c第一次出现的指针,或者如果没有找到c,返回指向NULL的指针
char *strstr (char *d, char *s) 返回一个指向字符串d中字符串s第一次出现的指针,或者如果没有找到s,返回指向NULL的指针
int strlen (char *d) 返回字符串d的长度,不包括终止符NULL
void *memcpy (void *d, void *s, int n) 从s复制n个字符到d
void *memmove (void *d, void *s, int n) 和memcpy相同,但即使d和s部分相同也运行
void *memcmp (void *d, void *s, int n) 比较d的首先n个字符与s;和strcmp的返回相同
void *memchr (void *d, char c, int n) 返回一个指向被d指向的n个字符c第一次出现的指针,或者如果没有找到c,返回指向NULL的指针
void *memset (void *d, char c, int n) c出现的地方用n填充d

1.4 数据类型

整型数据类型:
1、int(正负整数)
2、char(单个字符)
例如:‘A’ ‘!’(由一对单引号所包围的一个字母、数字、特殊符号)

浮点数据类型:(实数)
1、浮点型(float) 4.213f
2、双精度型(double) 4.213
3、长双精度型(long double) 4.213L

1.5 转义符

转义序列符 描述 含义
\n 换行符 移到一新行
\t 水平制表符 移到下一水平制表位
\v 垂直制表符 移到下一垂直制表位
\b 退格符 移回一个空格
\r 回车符 光标返回(把光标移到当前行的开始出——用于套印)
\f 换页符 发出一个换页指令
\a 警报 发出一个警报(通常是一个铃声)
\ 反斜线 插入一个反斜线字符
? 问号 插入一个问号字符
\ 单引号 插入一个单引号字符(把一个内单引号放置在一组外单引号内)
" 双引号 插入一个双引号字符(把一个内双引号放置在一组外双引号内)
\nnn 八进制数 数字nnn(n是一个数字)被认为是八进制数
\xhhhh 十六进制数 数字hhhh(h是一个数字)被认为是十六进制数
\0 空字符 出入一个空字符,它被定义为具有数值0

1.6 算数运算

1.6.1 转换控制序列

序列符 含义
%d 按十进制显示一个整数
%f 按小数点后六位数的小数形式显示这个浮点数
%lf 双精度浮点数
%c 显示一个字符
%s 显示一串字符串
%o 按八进制显示一个整数(023在C中是八进制数)
%x 按十六进制显示一个整数(0x在C中是十六进制数)
%p 地址

1.6.2 算数运算符总结

运算 运算符 类型 操作数 结果
+ 二元 两个都是整数 整数
一个操作数不是整数 双精度浮点数
- 二元 两个都是整数 整数
一个操作数不是整数 双精度浮点数
* 二元 两个都是整数 整数
一个操作数不是整数 双精度浮点数
/ 二元 两个都是整数 整数
一个操作数不是整数 双精度浮点数
% 二元 两个都是整数 整数
一个操作数不是整数 双精度浮点数
求反 B 一元 整数或浮点数 同操作数

1.6.3 优先级

1、括号()最高优先级
2、取反(从右到左)
3、乘法、除法、模运算(从左到右)
4、加法、减法(从左到右)

例子:

#include <stdio.h>
int main()
{printf("%f + %f = %f\n", 15.0, 2.0, 15.0 + 2.0);printf("%c\n", 'a');printf("%d\n", 'a');printf("%c , %d\n", 'A', 'A');return 0;
}

输出结果:

1.7 变量和声明

变量名称:

1、必须以字母或下划线开始,并且只能包含字母、下划线或数字,
不能包含任何空格、逗号或特殊字符。
2、不能是关键字

声明语句:

例:
int sum;
float grade;
char ch;
float grade1, grade2, total, average;

初始化:
int sum = 0;

符号常量(命名常量):
#define PI 3.14159
常用做法:将符号常量全部用大写字母表示。与声明语句中的变量声明区别。

1.8 赋值

1、赋值运算符=:
结合性是从右到左
a=b=c=25
即a=(b=(c=25))
即c=25;b=25;a=25;

2、自增字符++:
a = a + 1
即a++或++a

注意:
a++与++a的区别
1、a++是先取a的值做计算,再自加
2、++a是先自加,再取a的值做计算
例:int a=2,b;
b=a++;先取a的值赋值给b,则b=2,a值再自加,则a=3
b=++a;a先自加,则a=3,再赋值给b,则b=3

3、
a = a + 1;
a += 1;
a ++;
三条语句执行相同功能,存储需求一般第一条最高,第三条最低。
(a += 1; a -= 1; a *= 1; a /= 1;)
(a++; a–;)

4、
隐式类型转换:
等号右边表达式的值将被转换为等号左边变量的数据类型。

显式类型转换(强制转换):
(int) sum
若sum是一个双精度浮点型变量,则上述表达式的值是通过截去sum的小数部分获得的整数值。

2 输入和输出

2.1 交互式输入

scanf("%d %d", &num1, &num2);

注意:

两者无区别:
scanf("%f%f", &num1, &num2);
scanf("%f %f", &num1, &num2);
两者有区别:
scanf("%c%c%c, &ch1, &ch2,&ch3);
scanf("%c %c %c, &ch1, &ch2,&ch3);

输入字符串:

#include <stdio.h>
main()
{char fkey, skey;printf("Type in a character: ");scanf("%c%c", &fkey, &skey);printf("The keysrtoke just accepted is %d", fkey);printf("\nType in another character: ");scanf("%c", &skey);printf("The keystroke just accepted is %d\n", skey);return 0;
}

注意:
scanf()后按压的键都会被保留在缓冲区,直到遇到下一个scanf()直接获得剩下的。输入第一个字符后被保存,输入的回车键的数字码也被保存在缓冲区,上述程序是解决的一种办法。

用户输入验证:

处理无效数据输入,在输入数据期间或者输入之后就立即进行验证,并且如果数据无效的话,
还要为用户提供一个重新输入的途径。

2.2 格式化输出

整数:

例1:printf(“The sum of %3d and %4d is %5d.”, 3, 14, 17);
输出结果:The sum of **3 and **14 is **17.(此处表示空格)

例2:printf("%03d", 2);
输出结果:002

浮点数:
%5.2f等格式字符串一般形式为[标志][输出最小宽度][.精度][长度]

1、输出最小宽度:
用十进制整数来表示输出的最少位数。若实际位数多于定义的宽度,则按实际位数输出,若实际位数少于定义的宽度则补以空格或0。

2、精度:
精度格式以“.”开头,后跟十进制整数。如果输出数字,则表示小数的位数;如果输出字符,则表示输出字符的个数;若实际位数大于所定义的精度数,则截去超过的部分。

3、长度:
长度格式符为h、l两种,h表示按短整型量输出,l表示按长整型量输出。
例:prinrf("%10.3f", 25.67);
输出:****25.670(前面四个空格)

指定符 数字 显示 注释
%2d 1 *1 数字适合字段
%2d 12 12 数字适合字段
%2d 123 123 字段宽度被忽略
%2d 2.3 取决于编译器 浮点数在整数字段中
%5.2f 2.346 *2.35 字段宽度5,有2位小数位
%5.2f 23.4 23.40 数字适合字段
%5.2f 123.456 123.46 字段宽度被忽略但小数部分指定符被使用
%5.2f 123 取决于编译器 整数在浮点数字段中

格式修饰符:

左对齐(-):(不加-默认为右对齐)
printf("%-10d", 59);
输出:59^^^^^^^^(8个空格)

明确显示符号(+):(不加+只对负数显示符号)
printf("%+10d", 59);
输出:^^^^^^^+59(7个空格)

左对齐且明确显示符号:
printf("%±10d", 59);等价于printf("%-+10d", 59);
输出:+59^^^^^^^(7个空格)

3 选择

3.1 关系表达式

关系运算符:

关系运算符 含义
< 小于
> 大于
<= 小于等于
>= 大于等于
== 相等
!= 不相等

关系表达式的值总是两个可能的整数值之一(0或1),真1,假0。

逻辑运算符:

AND &&
OR
NOT !

优先级:(越向下优先级越低)

运算符 结合性
!,一元-,++,– 从右到左
*,/,% 从左到右
+,- 从左到右
<,<=,>,>= 从左到右
==,!= 从左到右
&& 从左到右
从左到右
+=,-=,*=,/= 从左到右

3.2 if 语句

Created with Raphaël 2.2.0开始条件为真吗语句结束yesno
if (表达式)语句1;

if (表达式)
{语句1;语句2;语句3;……;
}

3.3 if…else 语句

Created with Raphaël 2.2.0开始条件为真吗语句1结束语句2yesno
if (表达式)语句1;
else语句2;

if (表达式)
{语句1;语句2;……;
}
else
{语句a;语句b;……;
}

3.4 if…else 链

Created with Raphaël 2.2.0开始表达式1为真语句1结束表达式2为真语句2结束1语句3yesnoyesno
if (表达式1)语句1;
elseif (表达式2)语句2;else语句3;

if (表达式1)语句1;
else if (表达式2)语句2;
else语句3;

上面两种形式是一样的意思!

if(表达式1)语句1;
else if(表达式2)语句2;
else if(表达式3)语句3;
……
else if(表达式nn)语句n;
else最后的语句;

3.5 switch 语句

Created with Raphaël 2.2.0开始case数值1语句1break结束case数值2语句2breakcase数值3语句3breakdefaultyesnoyesnoyesno
switch (整型表达式)
{case 数值1:语句1;语句2;……;break;case 数值2:语句m;语句n;……;break;……case 数值n:语句w;语句x;……;break;default:语句aa;语句bb;……;
}

4 循环

4.1 while 语句

初始化语句;
while (表达式)
{语句;……;表达式改变语句;
}

4.2 for 语句

for (初始化列表;被测表达式;改变列表)
{语句;……;
}

4.3 do…while 语句

do语句;
while (表达式);

4.4 break 语句和 continue 语句

break语句:

强制从switch语句、while语句、for语句或者do…while语句中立即退出。

continue语句:

用于while语句、for语句、do…while语句。立即开始循环的下一次迭代。
while语句中,自动转移到循环的顶部并重新计算被测表达式的值。
for语句中,迫使控制传递到改变列表,由此会重新计算被测表达式的值。

空语句:

分号前面没有任何内容的语句。

5 函数

5.1 函数声明

函数原型:

返回数据类型 函数名(参数数据类型列表)
例:int fmax(int, int);
float roi(int, char, char, float);
void display(float, float); /不返回任何值/
可以放在#include <stdio.h>前或后,可应用于文件中的所有函数;
可以放在main()里面,只可应用于main()函数。

调用函数:

例:findMax(firstnum, secnum);
函数只接收这些变量值的副本。

函数首部行:

C语言函数由两部分组成:函数首部和函数体。

函数首部:
每一个函数都必须从函数首部行开始。
在函数首部行中列出的所有参数,必须用逗号分开,且必须分别声明他们的数据类型。
例:void findMax(float x, float y)
这个函数不直接返回任何值,且只要调用它,就需要接受两个浮点值。

函数体:
{
变量声明(如果有的话)
其他C语句
}

语句的放置:

预处理命令
符号常量
函数原型可以放置在这里
int main()
{函数原型可以放置在这里变量声明;其他可执行语句;return 数值;
}

5.2 标准库函数

1、数学库函数(头文件<math.h>)

2、rand()函数与srand()函数(头文件<stdlib.h)
srand()函数为rand()函数提供了一个开始的“种子”值。

3、比例放缩
产生a到b之间的随机数:a+(int)(rand()%(b-a+1))

4、输入/输出库函数(头文件<stdio.h>)
printf()、scanf()
专门用于字符型数据:getchar()、putchar()
例:inChar = getchar()等价于scanf("%c",&inChar)
purchar(‘a’)等价于printf("%c",“a”)

5、字符处理函数(头文件<ctype.h>)

6、转换函数(头文件<stdlib.h>)

5.3 变量的作用域

全局变量、局部变量
除了符号常量和函数原型以外,几乎从来不应该使用全局变量。

5.4 变量存储类

局部变量:

只能是auto(自动)、static(静态)、register(寄存器)存储类的成员。
(auto为默认存储类)
auto:函数结束前都是保留的,函数结束后就销毁
static:在函数执行完成时,变量中存储的最后值在下一次它被调用时是可获得的。
静态变量初始化只执行一次,第二次调用时不初始化。没有给出明确的初始化时都被设置为0。
register:与自动变量唯一不同的是变量存储区被分配的位置。很少使用

全局变量:

只能是static(静态)、extern(外部),但不能同时声明为这两种
extern:将一个源代码文件中声明的全局变量的作用域扩展到另外的源代码文件中。

5.5 按引用传递

指针变量(指针):能够存储地址的变量

地址运算符&:&num表示“num的地址”

间接运输符*:当*符号后面紧跟一个指针时,表示这是一个地址被存储在其中的变量

按值传递与按引用传递的区别:

按值传递最多只能返回一个值,按引用传递可返回多个值。

例子:

#include <stdio.h>
int main()
{void calc(float, float, float, float *, float *);float firstnum, secnum, thirdnum, sum, product;printf("Enter three numbers: ");scanf("%f %f %f", &firstnum, &secnum, &thirdnum);calc(firstnum, secnum, thirdnum, &sum, &thirdnum);printf("\nThe sum of the entered numbers is: %6.2f", sum)printf("\nThe product of the entered numbers is: %6.2f\n", product);return 0;
}void calc(float num1, float num2, float num3, float *sumaddr, float *productaddr)
{*sumaddr = num1 + num2 + num3;*productaddr = num1 * num2 * num3;
}

注意:C语言默认的是按值传递而不是按引用传递,从而精确地限制被调函数改变调用函数中变量的能力。因此,只要有可能,就应该坚持标准的安置调用过程,这意味着地址参数只应该用在实际要求多个返回值的极为严格的情形中。上述程序可用两个单独的函数来返回两个值。当排序一个数字列表或者名称列表,使其成为升序(增加)或降序(减少)时,返回多个值的函数是绝对必要的。

5.6 递归

直接递归:调用自身

间接递归(相互递归):函数能够调用第二个函数,反过来第二个函数也可以调用第一个函数。

递归与迭代的比较:

递归:用于解决方案可用同一问题的更简单版本表示的任何问题。
迭代:任何递归函数总是能够用一种使用迭代的非递归方法编写。
能用递归或迭代解决时,用迭代;只能用递归时,用递归。

6 数组

6.1 一维数组

声明:

声明语句给出了数组中项目的数据类型、数组(或列表)、数组中项目的个数
#define NUMELS 5
int grades[NUMELS];

注意:所有数组的开始索引值总是0。
grades[0]指的是保存在grades数组中的第一个数
grades[1]指的是保存在grades数组中的第二个数

初始化:

#define NUMGRADES 5
int grades[NUMGRADES] = {98, 87, 92, 79, 85};#define NUMCODES 6
char codes[NUMCODES] = {'s', 'a', 'm', 'p', 'l', 'e'};特点:当初始化值包含在声明语句中时,数组的大小可以省略。
int gallons[] = {16, 12, 10, 14, 11};
char codes[] = "sample";

数组作为函数实参:

1、将数组元素作为下标变量包含在函数调用的实参表中
findMin(grades[2], grades[6]);

2、传递一个完整的数组到函数
findMin(grades);
与传递变量不同,被调函数接收对实际数组的访问,而不是这个数组中的值的副本。
(改变被调函数中数组的值,就改变了调用函数中数组的值)

6.2 二维数组

声明:

#define NUMROWS 3
#define NUMCOLS 4
int val[NUMROWS][NUMCOLS];
数组val由3行4列组成。

初始化:

#define NUMROWS 3
#define NUMCOLS 4
int val[NUMROWS][NUMCOLS] = { {8, 16, 9, 52},{3, 15, 27, 6},{14, 25, 2, 10} };
或
int val[NUMROWS][NUMCOLS] = { 8, 16, 9, 52,3, 15, 27, 6,14, 25, 2, 10 };
或
int val[NUMROWS][NUMCOLS] = { 8, 16, 9, 52, 3, 15, 27, 6, 14, 25, 2, 10 };

传递二维数组到函数,是一个与传递一维数组相同的过程。
可以省略行长度,但列的大小必须包括。

内部数组元素定位算法:

数组元素i的地址=数组开始地址+偏移量
一维数组:偏移量=i单个元素的长度
二维数组:列索引值
单个元素的长度+行索引值在完整的一行中的字节个数
在完整的一行中的字节个数=指定的最大列数
单个元素的长度

7 字符串

7.1 输入输出

字符串输入和输出:(头文件<stdio.h>)

1、按完整单元处理字符串:gets()、puts()
2、单个字符的输入和输出:getchar()、putchar()
3、printf()、scanf()

字符串保存成由一个指定的字符串末端的名称为NULL的符号常量终止的字符型数组。
NULL常量的值是转义序列符\0,并且是标志字符串末端的标记。(要多预留一个位置保存\0)

按下回车键即产生一个换行符\n,这个字符被gets()函数解释为输入字符末端。
所有由gets()函数获得的字符,除了换行符,都被保存到数组中。
在输入时,\0取代\n;在输出时,\n取代\0

printf()总能代替puts()
scanf()不能代替gets()
scanf()遇到空格或换行符停止,gets()只有遇到换行符才停止。

注意:
scanf("%s", &message[0])等价于scanf("%s", message)
例:输入“This is a string”只有“This”被赋值给message数组。

7.2 库函数

字符串库函数:(头文件<string.h>)

strcpy()复制、strcat()附加、strlen()长度、strcmp()比较
例:
strcpy(str1, str2)
strcat(str1, str2)
strlen(string)
strcmp(str1, str2)

初始化:(下面几个声明的结果相同)

char test[5] = “abcd”;
char test[] = “abcd”;
chat test[5] = {‘a’,‘b’,‘c’,‘d’,’\0’};
chat test[] = {‘a’,‘b’,‘c’,‘d’,’\0’};

字符库函数:(头文件<ctype.h>)

int isalpha(char) 字母
int isupper(char) 大写
int islower(char) 小写
int isdigit(char) 数字
int isascii(char) ASCII字符
int isspace(char) 空格
int iscntrl(char) 控制字符
int ispunct(char) 标点字符
int toupper(char) 小写变大写(其他字符不受影响)
int tolower(char) 大写变小写(其他字符不受影响)

转换函数:(头文件<stdlib.h>)

int atoi(string) ASCII字符串转为整数
double atof(string) ASCII字符串转为双精度型数值
char[] itoa(string) 整数转为ASCII字符串

建立个人数据库:

例:头文件#include<C:\mylibrary\dataChecks.h>
注意:若dataChecks.h头文件中的函数要求stdio.h和stdlib.h函数,必须把它放在这两个之后

7.3 格式化字符串

右对齐:
printf("|%25s|", “Have a Happy Day”)
输出结果:|*********Have a Happy Day|(前面9个空格)

左对齐:
printf("|%-25s|", “Have a Happy Day”)
输出结果:|Have a Happy Day*********|(后面9个空格)

指定宽度和精度右对齐:
printf("|%25.12s|", “Have a Happy Day”)
输出结果:|*************Have a Happy|(后面13个空格)

指定宽度和精度左对齐:
printf("|%-25.12s|", “Have a Happy Day”)
输出结果:|Have a Happy*************|(后面13个空格)

指定精度不指定宽度:
printf("|%.12s|", “Have a Happy Day”)
输出结果:|Have a Happy|

内存中的字符串转换:

sprintf()、sscanf()

例:sprintf(disStrn, “%d %d”, num1, num2);
把num1和num2的数值写入disStrn中而不是在标准的输出终端上显示这些值。

例:sscanf(data, “%c%lf %d”, &dol, &price, &units);
将扫描保存到data数组中的字符串,并将它拆分为三个data项。

8 数据文件

8.1 声明、打开、关闭

文件:是保存到一个共同名称之下的数据集合,通常保存到磁盘、磁带或光盘上。
文件流:是用于连接保存到物理设备上的文件到一个程序的单向传输路径。

8.1.1 声明文件流:

FILE *inFile;
FILE *prices;
FILE *fp;
(FILE是特殊的数据结构类型,头文件<stdio.h>)

8.1.2 打开文件流:

fopen()函数(头文件<stdio.h>)
第一个参数是文件的外部名,第二个参数是使用文件的模式,必须放置在双引号中。
允许的模式有r(读)、w(写)、a(附加)。
如果外部名称首先保存到一个字符数组中或作为一个字符串被保存,
这个数组或字符串的名称不加双引号,也能够用做给fopen()函数的第一个参数。

例:
outFile = fopen(“prices.bnd”,“w”);
打开一个名称为prices.bnd的现在能够被写入的外部文件。
outFile = fopen(“prices.bnd”,“a”);
打开一个名称为prices.bnd的文件,并且使它可用于将数据添加到文件的末尾。
outFile = fopen(“prices.bnd”,“r”);
打开一个名称为prices.bnd的文件,并且使文件中的数据可用于输入。

使用完整的路径名:
fopen("\test\files\prices.dat", “r”)

注意:
用写入模式w打开的文件和用附加模式a打开的文件的唯一差别是数据被物理上放置在文件中
的位置。在w中,数据被写在文件的开始处;在a中,数据被写在文件结束处。对于新文件,两种
模式的效果相同。

模式指示符:
r 为读取(输入模式)打开一个现存的文本文件。
w 为写入(输出模式)创建一个文本文件;如果文件已存在,它的内容将丢失。
a 为写入(输出模式)打开一个文本文件,新加入的文本被写在现存文件的末尾。如果文件不存在,则会创建一个新文件。
r+ 为读和写打开一个现存的文本文件,如果文件存在,则它的内容被擦掉。
w+ 为读和写创建一个文本文件。
a+ 为读和写打开一个文本文件,文本被写在该文件的末尾,如果不存在文件,一个新文件为读和写被创建。

exit()函数:(头文件<stdlib.h>)
参数为0表示正常退出,非0表示异常退出。

注意:
调用fopen()函数时,检查它的返回值是重要的。

嵌入式文件名和交互式文件名:
用字符串保存外部文件名

8.1.3 关闭文件流:

fclose()函数:中断文件的外部名和内部名之间的连接。
参数:在文件被打开时使用的指针名。
所有的计算机在每次能够打开的最大文件数上有限制,关闭不需要的文件具有好的意义。

例:
fclose(inFile); /关闭inFile文件/

8.2 读取和写入文本文件

8.2.1 写入:

函数:(头文件<stdio.h>)
fputc(c, filename) 把一个字符写入文件
fputs(s, filename) 把一个字符串写入文件
fprintf(filename, “format”, args) 按照格式把一个参数的数值写入文件

例:
fputc(‘a’, outFile);
fputs(“Hello world!”, outFile);
fprintf(outFile, “%s %n”, descrip, price);

8.2.2 读取:

函数:(头文件<stdio.h>)
fgetc(filename) 从文件读取一个字符
fgets(stringname, n, filename) 从文件读取n-1个字符并把字符存储在给定的字符串名中
fscanf(filename, “format”, &args) 根据这个格式,从文件读取所列出的参数值

例:
fgetc(inFile);
fgets(message, 10, inFile);
fscanf(inFile, “%lf”, &price);

注意:结束标记
fgetc()、fscanf()函数返回名称为EOF的常量
fgets()函数返回一个NULL(\0)

8.3 随机文件访问

rewind(filename) 重置当前文件开始的位置,
fseek(filename, offset, origin) 允许程序员移动到文件中的任何位置
ftell(filename) 返回下一个将被读取或写入的字符的偏移量值

例:
fseek(inFile, 4L, SEEK_SET); /转向这个文件中的第5个字符/
fseek(inFile, 4L, SEEK_CUR); /向前移动5个字符/
fseek(inFile, -4L, SEEK_CUR); /向后移动5个字符/
fseek(inFile, 0L, SEEK_SET); /转向rewind()的相同文件的开始/
fseek(inFile, 0L, SEEK_END); /转向文件的结尾/
fseek(inFile, -10L, SEEK_END); /转向文件结尾之前的10个字符/

注意:fseek()的偏移量必须是一个长整数型。
fseek()函数的三个参数:文件的指针名、作为长整型的偏移量、偏移量从这个位置被计算的位置

程序:

#include <stdio.h>
#include <stdlib.h>int main()
{int ch, n;long int offset, last;FILE *inFile;inFile = fopen("text.dat", "r");if(inFile == NULL){printf("\nFailed to open the test.dat file.\n");exit(1);}fseek(inFile, 0L, SEEK_END); /*移到这个文件的结尾*/last = ftell(inFile); /*保存最后一个字符的偏移量*/for(offset = 0; offset <= last; offset++){fseek(inFile, -offset, SEEK_END);  /*向后移到下一个字符*/ch = getc(inFile);    /*得到这个字符*/switch(ch);{case '\n': printf("LF: ");break;case EOF: printf("EOF: ");break;default: printf("%c: ", ch);break;}}fclose(inFile);return 0;
}

假设文件text.dat包含数据:Bulbs 3.12
则输出:EOF:2:1:.:3:

C语言基础知识(学习笔记)相关推荐

  1. R语言基础知识-学习笔记汇总

    B站课程:生信必备技巧之R语言基础教程全集的代码笔记 1.R语言包安装 rm(list = ls()) # 设置镜像: options()$repos options()$BioC_mirror #o ...

  2. python基础知识学习笔记(1)

    python 基础知识学习笔记(1) 总结一下Python基础知识,以防忘记. 文章目录 python 基础知识学习笔记(1) 一.起步 1.python安装与编译环境 二.变量和简单数据类型 三.列 ...

  3. oracle数据库基础知识总结,oracle数据库基础知识学习笔记

    oracle数据库基础知识学习笔记 一.oracle数据库类型: Char:  字符型(最大长度2000,定长.不足时以空格补充) Varchar2:字符型 最大长度 4000,变长,实际长度由存储的 ...

  4. 图像基础知识学习笔记

    图像基础知识学习笔记 文章目录 图像基础知识学习笔记 前言 一.图像基础知识相关笔记 1.光学系统影响图像的结构主要包括什么? 2.常见噪声都有什么,其分类,及特点? 3.光圈,快门,景深? 4. I ...

  5. K8s基础知识学习笔记及部分源码剖析

    K8s基础知识学习笔记及部分源码剖析 在学习b站黑马k8s视频资料的基础上,查阅了配套基础知识笔记和源码剖析,仅作个人学习和回顾使用. 参考资料: 概念 | Kubernetes 四层.七层负载均衡的 ...

  6. 网络基础知识学习笔记

    网络基础知识学习笔记 参考菜鸟教程.个人学习整理,仅供参考.三年前学过,三年没用忘了,重新学习整理一下. 文章目录 网络基础知识学习笔记 OSI七层网络模型 IP地址 子网掩码及网络划分 网络协议 A ...

  7. C语言基础入门学习笔记

    前言 我是一个初中生,过完暑假就是一个高一的学生了.在这个暑假里,我学习了韦东山老师和唐佐林老师的课程,所以我写下这个笔记来记录自己的成长历程. C语言基础入门学习笔记 格式 #include < ...

  8. Python 基础知识学习笔记——NumPy

    Python基础知识学习笔记--NumPy 与 matlab 优秀的矩阵运算类似,python 提供了 numpy 库,这对熟悉 matlab 的用户来说非常友好.向量.矩阵和多维数组是数值计算中必不 ...

  9. Python 基础知识学习笔记——OpenCV(1)

    Python 基础知识学习笔记--OpenCV(1) OpenCV是一个开源的跨平台计算机视觉和机器学习软件库,它轻量而且高效,被广泛的使用. 整理一下OpenCV学习笔记,以防忘记. 文章目录 Py ...

  10. Python基础知识学习笔记——Matplotlib绘图

    Python基础知识学习笔记--Matplotlib绘图 整理python笔记,以防忘记 文章目录 Python基础知识学习笔记--Matplotlib绘图 一.绘图和可视化 1.导入模块 2.一个简 ...

最新文章

  1. AI一分钟 | 特斯拉再融46亿;腾讯AI Lab宣布开源多标签图像数据集
  2. 价值1.4万元的课程讲义开源,fast.ai发布新书源代码,登GitHub趋势榜第一
  3. cve-2019-11076 Cribl UI 1.5.0 未授权命令执行漏洞分析
  4. flask读取数据库(mysql)并展示表格(讲解获取表头的方法)【附上flask好看点的helloworld】
  5. linux mysql 最小安装,Linux最小化安装之安装mysql
  6. 2015蓝桥杯省赛---java---A---1(熊怪吃核桃)
  7. [Alpha]Scrum Meeting#5
  8. 网站安全之设置HttpOnly的方法
  9. js进阶 12-4 jquery键盘事件如何使用
  10. Commons-FileUpload上传组件
  11. ABBYY FineReader 超强OCR识别软件 V15.0.0 特别版
  12. Java教学视频下载(全集)
  13. HTML页面跳转的几种方式(重定向)
  14. 简化的围棋棋子规则(C++实现)
  15. mysql 重做日志原理_Oracle恢复内部原理(重做日志)
  16. ABP框架Web API跨域问题的解决方案
  17. 最近碰到的上架苹果4.3问题分析
  18. 【多目标优化】Pareto最优解很少
  19. Python数据可视化matplotlib(一)—— 图表的基本元素
  20. bitwarden_rs数据备份迁移到个人window电脑上

热门文章

  1. pandas 保存成excel,并 指定列宽
  2. 【English】【托业】【四六级】写译高频词汇
  3. 金山毒霸系统清理专家
  4. 【数据结构与算法分析1.2】编写一个程序求解字谜游戏问题
  5. 暑假将至,人贩子猖狂
  6. 计算机用户个人设置总是重启,联想电脑总是自动重启怎么回事
  7. Table表格边框线、样式
  8. 价格敏感度测试(PSM)模型及其在网游中的运用
  9. 在上海、苏州、深圳、长沙从“蜗居”到“安家”,8090后要付出多少?
  10. 为什么大容量的服务器SAS硬盘普遍都只有7200rpm的转速?