字符串常量的存储位置
char s1[] = "aaaaaaaaaaaaaaa"; //数组和字符串都在栈
char *s2 = "bbbbbbbbbbbbbbbbb"; //指针在栈,字符串在常量区
aaaaaaaaaaa是在运行时刻赋值的;
而bbbbbbbbbbb是在编译时就确定的;
但是,在以后的存取中,在栈上的数组比指针所指向的字符串(例如堆)快。
//转义字符
\a 响铃
\b 退格,将当前位置移到前一列
\n 换行,将当前位置移到下一行开头
\r 回车,将当前位置移到本行开头
//简单的if-else分支语句
if (判断条件) {
语句块1;
} else {
语句块2;
}
//多个if-else分支语句
if(判断条件1) {
语句块1;
} else if (判断条件2) {
语句块2;
} else if (判断条件3) {
语句块3;
} else {
语句块4;
}
意思是从上到下,依次检测判断条件,当某个判断条件成立时,则执行其对应的语句块,然后跳到整个if else语句之外继续执行其他代码,如果所有判断条件都不成立,则之后最后else的语句块4(n),然后继续执行后续代码。
也就是说一旦遇到能够成立的判断条件,则不再执行其他的语句块,所以最终只能有一个语句块被执行。
#include
int main (void)
{
char ch;
ch = getchar();
if (ch < 32) {
puts("ch is a control character.");
} else if (ch >= 48 && ch <= 57) {
puts("ch is a number.");
} else if (ch >= 65 && ch <= 90) {
puts("ch is a capital character.");
} else if (ch >= 97 && ch <= 122) {
puts("ch is a small character.");
} else {
puts("ch is other character.");
}
return 0;
}
if语句的嵌套调用
#include
int main (void)
{
char ch;
ch = getchar();
if (ch < 32) {
puts("ch is a control character.");
} else if (ch >= 48 && ch <= 57) {
puts("ch is a number.");
if (ch == '9') {
puts("ch is number nine.");
} else {
puts("ch is other number.");
}
} else if (ch >= 65 && ch <= 90) {
puts("ch is a capital character.");
} else if (ch >= 97 && ch <= 122) {
puts("ch is a small character.");
} else {
puts("ch is other character.");
}
return 0;
}
if 语句嵌套时,要注意 if 和 else 的配对问题。C语言规定,else 总是与它前面最近的 if 配对,例如:
if(a!=b) // ①
if(a>b) printf("a>b\n"); // ②
else printf("a); // ③
//③和②配对,而不是和①配对。
运算符——按操作数的个数分:
1. 单目运算符:++,–
2. 双目运算符:+ - * /
3. 三目运算符:?:
比如 a>b?a:b;
逻辑运算符
为什么有了逻辑运算符——前面学到if-else结构,当一个if语句里面嵌套了多个判断条件就需多个if语句,显然这样的代码不够清晰。利用逻辑运算符可以整合判断条件。
各运算符优先级:
赋值= < &&和|| < 关系运算符 < 算术运算符 < 非
switch语句
为什么会有switch语句,主要是当有多个if语句时,代码不够清晰且易错,尝试写下面的代码就能感受的到
#include
int main (void)
{
int a;
scanf("%d", &a);
if (a == 1) {
puts("Today is Monday.");
} else if (a == 2) {
puts("Today id Tuesday.");
} else if (a == 3) {
puts("Today is Wednesday.");
} else if (a == 4) {
puts("Today is Thursday.");
} else if (a == 5) {
puts("Today is Friday.");
} else if (a == 6) {
puts("Today is Saturday.");
} else if (a == 7) {
puts("Today is Sunday.");
} else {
puts("A illegal number.\nPlease input a number between 1 and 7....");
}
return 0;
}
关于switch语句
switch结构1:
switch(表达式){
case 整型数值1: 语句 1;
case 整型数值2: 语句 2;
......
case 整型数值n: 语句 n;
default: 语句 n+1;
}
它的执行过程是:
1) 首先计算“表达式”的值,假设为 m。
2) 从第一个 case 开始,比较“整型数值1”和 m,如果它们相等,就执行冒号后面的所有语句,也就是从“语句1”一直执行到“语句n+1”,而不管后面的 case 是否匹配成功。
3) 如果“整型数值1”和 m 不相等,就跳过冒号后面的“语句1”,继续比较第二个 case、第三个 case……一旦发现和某个整型数值相等了,就会执行后面所有的语句。假设 m 和“整型数值5”相等,那么就会从“语句5”一直执行到“语句n+1”。
4) 如果直到最后一个“整型数值n”都没有找到相等的值,那么就执行 default 后的“语句 n+1”。
需要重点强调的是,当和某个整型数值匹配成功后,会执行该分支以及后面所有分支的语句。
break是C语言的一个关键字,专门用于跳出switch语句,所谓跳出,是指一旦遇到break,就不再执行,switch中的任何语句,包括当前分支中的语句和其他分支中的语句;也就是说,整个switch执行结束了,接着会执行整个switch后面的代码。
switch语句结构2:
switch(<条件>)
{
case 1:<语句体>;break;
case 2:<>;break;
......
default:<>;break;
}
需要注意的是:
1. 只能针对基本数据类型使用;其他类型必须用if
2. case 标签必须是常量表达式(整数或字符)
3. 由于 default 是最后一个分支,匹配后不会再执行其他分支,所以也可以不添加break;语句。
4. default 不是必须的。当没有 default 时,如果所有 case 都匹配失败,那么就什么都不执行。
条件运算符
表达式1?表达式2:表达式3
首先判断表达式1,若为真,则将表达式2的值作为整个条件表达式的值;若为假,则将表达式3的值作为整个条件表达式的值。条件表达式通常用于赋值语句中。
需要注意的是:
1. 条件运算符的优先级是小于关系运算符和算术运算符的,高于赋值运算符:max = (a>b)?a:b
等价于 max = a>b?a:b
2. 条件运算符的结合方向是自右向左的,条件表达式嵌套的理解:
a>b?a:c>d?c:d;
等价 a>b?a:(c>d?c:d)
在C语言中,共有三大常用的程序结构:
顺序结构:代码从前往后执行,没有任何“拐弯抹角”;
选择结构:也叫分支结构,重点要掌握 if else、switch 以及条件运算符;
循环结构:重复执行同一段代码。
循环结构
while 循环
while(表达式) {
语句块;
}
执行过程是:先计算表达式的值,若为真,执行语句块;再计算表达式的值,若为真,继续执行语句块,再计算表达式的值,直到表达式的值为假,就退出循环,执行while后面的代码。
while 循环的整体思路是这样的:设置一个带有变量的循环条件,也即一个带有变量的表达式;在循环体中额外添加一条语句,让它能够改变循环条件中变量的值。这样,随着循环的不断执行,循环条件中变量的值也会不断变化,终有一个时刻,循环条件不再成立,整个循环就结束了。
for循环的产生
#include
int main(){
int sum = 0;
int i = 1; //语句①
while(i <= 100 /*语句②*/ ){
sum += i;
i++; //语句③
}
printf("%d\n", sum);
return 0;
}
可以看到,语句①②③被放到了不同的地方,代码结构较为松散。为了让程序更加紧凑,可以使用 for 循环来代替,如下所示:
#include
int main(){
int sum = 0;
for(int i = 1/*语句①*/; i <= 100/*语句②*/; i++/*语句③*/){
sum += i;
}
printf("%d\n", sum);
return 0;
}
for循环的一般形式是
for (表达式1; 表达式2; 表达式3) {
语句体;
}
运行过程:先计算表达式1,再计算表达式2,若表达式2的值为真,则执行语句体,再计算表达式3,再计算表达式2的值,若为真,执行语句体;若为假,结束整个for循环语句。
“表达式1”仅在第一次循环时执行,以后都不会再执行,可以认为这是一个初始化语句。“表达式2”一般是一个关系表达式,决定了是否还要继续下次循环,称为“循环条件”。“表达式3”很多情况下是一个带有自增或自减操作的表达式,以使循环条件逐渐变得“不成立”。
C语言跳出循环
使用while和for循环时,如果想提前结束循环(在不满足结束条件的循环下结束循环),可以使用break或continue关键字
break关键字:
之前有学到,用于跳出switch语句;
用于while 、 for循环时,会终止循环而执行整个循环语句后面的代码,break关键字通常和if语句一起使用,即满足条件时,便跳出循环。
在多层循环中,一个while语句只跳出一层循环
continue关键字:
continue 语句的作用是跳过循环体中剩余的语句而强制进入下一次循环。continue语句只用在 while、for 循环中,常与 if 条件语句一起使用,判断条件是否成立。
break与continue的对比:break 用来结束所有循环,循环语句不再有执行的机会;continue 用来结束本次循环,直接跳到下一次循环,如果循环条件成立,还会继续循环
循环结构的嵌套
//输出一个4x4的矩阵
#include
int main(void)
{
for (int j = 1; j <= 4; j++) {
for (int i = 1; i <= 4; i++) {
printf("%d ", i*j);
}
printf("\n");
}
return 0;
}
//输出九九乘法表
#include
int main(void)
{
for (int i = 1; i <= 9; i++) {
for (int j = 1; j <= i; j++) {
printf("%d*%d=%-4d", i, j, i*j);
}
printf("\n");
}
return 0;
}