c语言
\(updata : 2021.12.24\)
为了 \(c\) 语言考试 , 特意来水一篇博客
switch
\(① :\) 首先没有 default 也可以 , default只是所有的 case 不满足之后 , 才执行 default 之后的语句.
\(② :\) 没有 break .当一个 case 满足条件之后 , 但它的后面没有break , 那它会一直执行下一条case (无视 case 的条件) , 直到遇到一个case后面有 break , 或者运行完所有的 case (包括default ).
\(③ :\) default可以不放最后面 , 但要达到效果的化必须加上break , 不加 break 同理 \(②\) 情况.
赋值为右结合性
例如 a = b = c , 就是 \(c\) 赋值给 \(b\) , \(b\) 再赋值给 \(a\) .
输出格式
int a = 4 , b = 40;
printf("%5d\n%5d",a,b); // 保证右对齐 , 一共5位 , 当数字位数大于5则没有对齐效果.
printf("%-5d\n%-5d",a,b); // 保证左对齐.
printf("%o",) // 8进制
printf("%x",) // 16进制
printf("%u",) // 针对于unsigned
printf("%.nlf") //保留小数点后n位
运算符的优先级
() [] 大于 ++ -- 大于 * / % + - 大于 == !=
\(updata : 2021.12.29\) 突然发现 && 的优先级大于 || , ! 的优先级是大于 && .
数组的初始化 :
\(① :\) 一维数组的初始化
可以全部赋初始值
int a[5] = {1,2,3,4,5};
当然如果你数组长度只想定为 \(5\) 的话 , 可以省略成
int a[] = {1,2,3,4,5};
但如果你数组长度想定为 \(10\) , 就不能这样玩
int a[10] = {1,2,3,4,5}; // 给0 ~ 4赋初始值 , 其余为 0
初始值想赋值为 \(0\) 的话 ,
int a[5] = {0,0,0,0,0};
int a[5] = {0};
二维数组的初始化
可以这样 int a[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
也可以这样
int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12}; //编译系统会根据第二维自动分行
可以这样
int a[3][4] = { {1} , {5} , {9} };
//每行的第一个数才有值 , 其他的为零.
当然也可以这样 , 对一些特定位置赋值 , 其他的位置为零.
int a[3][4] = { {1,1} , {1,1,2} , {3} }
/*
1 1 0 0
1 1 2 0
3 0 0 0
*/
同样我们可以对行的初始值进行省略
int a[3][4] = {{1},{3,4}};
int a[3][4] = {{1},{},{9}};
同样我们知道第二维可以用来确定第一维的个数
int a[][4] = {1,2,3,4,5,6,7,8,9,10,11,12}; //个数不为4的倍数时,会用零补齐这一行
int a[][4] = {{0,0,3},{},{0,10}} //这里就明确了有3行
选择排序
for(int i=1;i<=n;++i){
for(int j=i;j<=n;++j)
if(a[j] < a[i]) swap(a[j] , a[i]);
}
//在剩下区域中选择一个最小的放在first_unsort位置上
冒泡排序
for(int i=1;i<=n;++i){
int flag = 0;
for(int j=n;j>i;--j){
if(a[j] < a[j-1]){
swap(a[j] , a[j-1]);
flag = 1;
}
}
if(!flag) break;
//排序时全员参与 , 没有变化时说明已经排好了 , 及时break;
}
字符
关于字符数组初始化 , 可以参考上文数值数组的初始化 , 注意使用 ' ' .
关于字符常用函数 , 可以参考这里
函数
主要分清楚形参与实参 ,有例子
void Swap(int &a,int &b){
int t ;
t = a , a = b , b = t;
}
void Swap(int a,int b){
int t ;
t = a , a = b , b = t;
}
数组作为函数的参数
用数组名传递函数参数 , 传递的是数组首元素的地址 , 且可以不必申请形参数组的大小
float arr(int a[10])
float arr(int a[])
多维数组名作函数参数
可以说明每一维的大小 , 也可以省略第一维的大小 , 但不能省略第 \(2\) 维以及其他高维的大小.
int max(int a[5][4] , b[][5]) // 二者均合法
int max(int a[5][] , b[][]) // 二者均不合法
同时在第二维相同的情况下 , 形实参数组的第一维大小可以不相同.
局部变量与全局变量
注意变量在复合语句中 ,函数中的有效性 , 脱离后系统会把它内存所占空间释放.
变量的储存方式与生存期
分为 \(auto\) , \(static\) , \(register\) , \(extern\) 四大类别
首先全局变量自动分配在静态区 ,而且不专门申明为 \(static\) , 数据都储存在动态存储区.
\(① : auto\)
\(auto\) 可以忽略不写 , 不写 \(auto\) 则默认自动存储类别 .
int f(int a){
auto int b , c;
}
\(② : static\)
全局变量属于 \(static\)
函数调用(或一次循环)后内存单元不会释放 , 且会保留上一次函数(循环)调用后的值
个人感觉主要在循环与函数中使用吧 (在主函数 \(main\) 中直接定义 \(auto\) 就好了 , 主函数外的话直接用全局变量即可)
注 : \(static\) 类型只能赋一次初值 , 如果不赋初值的话 , 编译时自动赋值为 \(0\) , 或者空字符 '\0' (对字符而言)
\(③ : register\)
把变量放在寄存器中 , 以前以为在卡常方面有用 ,但大部分编译器在这方面会自动优化.
\(④ : extern\)
针对于多个源程序文件的编译 , 多个文件用同一变量的时候 , 将变量的作用域扩展到文件外.
指针
作为函数参数 , 经典例子
int a , b , *p1 , *p2 ;
scanf("%d%d",&a,&b);
p1 = &a , p2 = &b;
Swap(p1 , p2);
void Swap(int *p1 , int *p2){
int temp;
temp = *p1 , *p1 = *p2 , *p2 = temp;
}
在一维数组中的应用
\(① :\) 初始化
int a[10] ;
int *p = &a[0]; //第一种
int *p = a; //第二种
int *p ; p = a 或 p = &a[0]; //第三种
\(② :\) 在循环中的应用
int a[10] , *p;
for(p=a;p<(a+10);++p) printf("%d ",*p);
for(i=0;i<10;++i) printf("%d ",*(a+i));
注意 a 是指针常量 , ++a 是不合法的.
\(③ :\) 注意事项
++ , * 优先级是相同的 , 但是注意结合方向是自右向左的.
*p++ , *++p 是有区别的 , 前者先取 \(*p\) 再自加 , 后者先自加再取 \(*p\) ;
用指针变量作为实参的话 , 必须先使指针变量有确定的值 , 指向一个确定的变量.
在字符串中的应用
前置 :\(c\) 语言中只有字符变量 , 没有字符串变量.
char *string = "I love china!"; // 将字符串的首地址给string
printf("%s\n",string); // 到字符结束标志'\0'为止.

浙公网安备 33010602011771号