C语言复习---零散补充
一:double和float使用scanf获取数据
1 printf输出float和double都可以用%f,double还可以用%lf。 2 scanf输入float用%f,double输入用%lf,不能混用。
double a, b; scanf("%lf", &a); //正确 scanf("%f", &b); //错误,导致8字节数据中有随机数据,所以数据输出错误
%f 是浮点型(单精度),占4字节 %lf 是浮点型(双精度),占8字节
二:scanf和gets获取字符串
gets(s)函数与 scanf("%s",&s) 相似,但不完全相同。 使用scanf("%s",&s) 函数输入字符串时存在一个问题,就是如果输入了空格会认为字符串结束,空格后的字符将作为下一个输入项处理。 但gets()函数将接收输入的整个字符串直到遇到换行为止。
1.scanf()
所在头文件:stdio.h 语法:scanf("格式控制字符串",变量地址列表); 接受字符串时:scanf("%s",字符数组名或指针);
2.gets()
所在头文件:stdio.h
语法:gets(字符数组名或指针);
1.不同点:
scanf不能接受空格、制表符Tab、回车等;
而gets能够接受空格、制表符Tab和回车等;
2.相同点:
字符串接受结束后自动加'\0'。
三:不同类型间运算
double total = 0; int fz = 2; int fm = 1; int temp; for (int i = 1; i <= 20;i++) { total += (double)fz / fm; printf("%d/%d=%lf\n", fz, fm, (double)fz / fm); temp = fz; fz = fz + fm; fm = temp; }
正确:
total += (double)fz / fm;
错误:
total += (double)(fz / fm); //因为fz,fm是整型int,fz/fm也是一个取整数(整数),所以我们再使用double进行转换只是在后面加上.000000
四:数组常量表达式问题(一维数组为例)
类型符 数组名[常量表达式]
常量表达式:
常量表达式可以包括常量和符号常量 int a[3+5]是合法的 #define MAX 10 int a[MAX]也是合法的
c语言不允许对数组的大小做动态定义,即数组的大小不依赖于程序运行过程中的变量的值。 int n; scanf("%d",&n); //企图在程序中临时输入数组的大小,这是不允许的额 int a[n];
补充:
如果在被调用的函数(非主函数中)定义数组,其长度可以是变量或者非常量表达式: void func(int n) { int a[2*n]; ... }
五:数组初始化问题(一维数组为例)
一般当我们定义数组大小后需要尽快进行初始化,若不去初始化,数组中的值可能是随机值(原来该位置内存中的值)。
注:只有在静态区中的全局变量和static静态变量才会被系统自动初始化为0;
int f[20]; for (int i = 0; i < 20;i++) { printf("%d ", f[i]); }
-858993460 -858993460 -858993460 -858993460 -858993460 -858993460 -858993460 -85 8993460 -858993460 -858993460 -858993460 -858993460 -858993460 -858993460 -85899 3460 -858993460 -858993460 -858993460 -858993460 -858993460
我们进行初始化的方法
1.在定义数组的时候对全部数组元素赋予初值 int a[10] = {0,1,2,3,4,5,6,7,8,9} 2.可以只给某一部分赋初值 int a[10] = {0,1,2,3,4} 注意:这里其实会对后面我们没有处理的数组数据也进行赋初值,将后面的所有数据赋值为0 3.若是想全部初始为0,可以使用简介方法(只对于0有效,换成其他的会变成2中情况) int a[10]={0}
六:二级指针的创建和memset初始化
int n; scanf("%d", &n); int **arr = (int **)malloc(n*sizeof(int*)); for (int i = 0; i < n; i++) { arr[i] = (int *)malloc(n*sizeof(int)); memset(arr[i], 0, n*sizeof(int)); } for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) printf("%2d", arr[i][j]); printf("\n"); }
memset(void *s,int ch,size_t n):将s所指向的某一块内存中的后n个 字节的内容全部设置为ch指定的ASCII值, 第一个值为指定的内存地址,块的大小由第三个参数指定,这个函数通常为新申请的内存做初始化工作, 其返回值为s。
七:二维数组和二级指针的关系:没关系,别瞎想(重点)
C语言复习---二维数组和二级指针的关系:没关系,别瞎想(重点)
八:extern的使用:用于定义外部函数和变量
(一)file1.c
#include <stdio.h> int A, B, C; int max() { int m = A > B ? A : B; if (m < C) m = C; return m; }
(二)file2.c
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> int main() { extern A, B, C; int m; scanf("%d %d %d", &A, &B, &C); m=max(); printf("max:%d", m); system("pause"); return 0; }
(三)总结
我们要使用其他文件中的全局变量,需要在自己文件中使用extern去声明,表示该变量来自于其他文件,编译器你去外面找找看。
注意:我们这里使用了外部函数max但是没有使用extern,因为在定义函数时,可以省略extern,默认该函数时外部函数。我们可以使用static将函数生命周期放在该文件中