程序语言中的控制流语句用于控制各计算操作执行的次序。控制流结构有:(1)顺序结构(2)分支结构(3)循环结构
if...else语句是经典的分支结构控制语句,同样"switch (表达式)...case 常量表达式" 语句也可以实现分支处理。"表达式"可以是任何表达式,"常量表达式"也可以是任何常量表达式。case分支一般包含多条语句时也不必用大括号括起来,因为每一个case分支只会给出switch分支结构中语句执行的开始位置,而不确定终止位置。switch分支结构的结束依靠switch分支结构结尾右大括号 或者 break语句。
for语句是典型的循环结构控制语句。for语句可以用来按照一组数字的变化过程做出循环,循环变量随时代表了变化中的某个值。
while和do...while是更具一般性的循环结构控制语句。while后面跟的循环条件测试语句不可以为空,但是for允许为空,当for循环的循环条件测试语句置空时,默认为真。
注:
循环中我们可以使用continue;语句直接跳到循环体右大括号,这样她事实上实现了让循环直接进入下一轮循环的目的。
循环中可以使用break;语句直接砸碎循环,击毙循环。
/*
* 程序语言中的控制流语句用于控制各计算操作执行的次序。控制流结构有:(1)顺序结构(2)分支结构(3)循环结构
* while和do...while循环结构控制语句比for循环结构控制语句更具一般性
* 以下是一个while例程
*/
#include <stdio.h>
main()
{
int shu_zi = 0, ge_shu = 0;
printf("Input an integer:");
scanf("%d", &shu_zi);
/*
while (shu_zi) {//这个循环所涉及语句执行顺序可以看成(我们用{}代表循环体所有语句):[shu_zi, {}] [shu_zi, {}] [shu_zi, {}] ...
shu_zi /= 10;
ge_shu++;
}
*/
do {//相比上面注释中的while循环,该循环避免了当用户输入整数0时候程序计算错误的尴尬
shu_zi /= 10;
ge_shu++;
} while (shu_zi);//这个循环所涉及语句执行顺序可以看成(我们用{}代表循环体所有语句): [{}, shu_zi] [{}, shu_zi] [{}, shu_zi] ...
printf("Integer %d 共 %d 位\n", shu_zi, ge_shu);
}
/*
* 死循环
* */
#include <stdio.h>
main()
{
int counter = 0;
for (;;) {
printf("%d\n", counter++);
}
/*
for语句是典型的循环结构控制语句。for语句可以用来按照一组数字的变化过程做出循环,循环变量随时代表了变化中的某个值。
while和do...while是更具一般性的循环结构控制语句。while后面跟的循环条件测试语句不可以为空,但是for允许为空,当for循环的循环条件测试语句置空时,默认为真。
while (1) {
printf("%d\n", counter++);
}
*/
}
稍微简单的复杂数据类型:数组
计算机程序处理的对象是数据信息(计算机中的信息包括数据信息和控制信息),计算机内存可以存储大量信息,姑且可以认为只有存储在内存中的数据信息才是可以使用的。内存由操作系统管理,程序要使用内存存储空间需要向操作系统申请并被成功分配后才可以使用,C语言提供的变量声明(定义)语句可以实现向操作系统申请存储空间。
C语言提供的变量声明(定义)语句实现向操作系统申请存储区(存储空间),变量名有"两个代表",一是代表所申请到的存储区,一是代表存储区里面存放的数据信息。数组声明(定义)语句可以实现一次性向操作系统申请成倍的存储空间,数组名有"两个代表",一是代表所申请到的(整个)存储区,二是代表着获得的成倍存储空间的首存储单元首地址。要注意的是:数组名根本不能代表所申请的全部存储区里面存放的数据信息。数组的"数组名"和函数的"函数名"非常类似,数组名代表数组首元素的首地址,函数名代表函数中首条代码的地址(我们知道,程序语句可以分组,顶级分组就是函数)。
附:
/*
* 函数指针:指向函数的指针
*
* 函数名称代表函数本身整个存储区,函数名称还代表着函数中的第一条语句的地址。函数名取址是函数地址,是整个函数的地址。这和数组名称一样,数组名称代表数组本身的整个存储区,数组名称还代表数组第一个元素的地址。数组名取址是整个数组的地址。
*
* 函数地址。 从地址信息上看函数地址就是函数中第一条语句所在的地址。
*
* */
#include <stdio.h>
int main()
{
int add(int , int);
printf("add是%p\n", add);
printf("&add是%p\n", &add);
int (*p_f)(int, int);
p_f = add;
printf("p_f(1, 1)是%d\n", p_f(1, 1));
return 0;
}
int add( int value, int value1)
{
return value + value1;
}
关于数组的分析:
int integer_arr[100];
//当一次性成功申请了100倍的可以放整型数据的存储空间后,integer_arr一是代表所申请的整个存储区(看看sizeof(integer_arr)就知道了),integer_arr再就是代表着获得的成倍存储空间的首存储单元的首地址(具体就是&integer_arr[0])。
//因为integer_arr代表着整个存储区,所以&integer_arr是整个数组的地址(可以想象这个地址值是和integer_arr一样的,值都是&integer_arr[0])
分析:
integer_arr + 1和&integer_arr + 1的区别
函数
程序语句可以分组,分组可以一层又一层的进行下去,顶级分组就是函数。函数实现了对程序语句的分组。不同的函数通过函数名区分,函数名有"两个代表",一是代表整个函数所在代码区,二是代表函数所在代码区里的首条语句首地址。
函数分为函数头和函数体,函数头单独出现叫做函数声明。
注意:传统上C语言(C89)是不支持变长数组功能的,也就是说数组长度是在编译期间就确定下来的,不能在运行期改变。不过在C99标准中已经允许定义变长数组。然而,C99所允许的变长数组是使用是有限制的。
由于变长数组的长度是在编译时无从得知的,因此变长数组的存储空间位于栈中。