目录
1. for循环
2. 全局变量和局部/本地变量:
静态本地变量
3. 函数
3.1 有返回值的函数:
3.2 没有返回值的函数:
3.3 函数参数
形参和实参:
(1)传值:
(2)传指针:
4. 数据类型
选择整数类型
浮点的输入输出
运算符
运算符优先级:
for语句的一般形式:
for(循环变量赋初值;循环条件;循环变量增值)
{}
例如:for(s=2;s<=10;s++){ }
表达式1 表达式2 表达式3 都可以省略。
注:省略表达式时,它后边的“ ;”不能省略。
九九口诀表:
int main()
{
int n;
scanf("%d", &n);
int i,j;
for(i = 1; i <= n; i++)
{
for(j = 1; j <= i; j++)
{
printf("%d*%d=%-3d", j, i, i * j);
}
printf("\n");
}
return 0;
}
- 全局变量定义在函数外部,通常是程序的顶部。
- 全局变量在整个程序的生命周期内都是有效的,在任意的函数内部都能访问全局变量。
- 局部变量的存储空间在每次函数调用时分配,在函数返回时释放。
- 全局变量在定义时不初始化,则初始值是0,也就是说,整型是0,字符型是’\0’,浮点型是0.0,指针会得到NULL值,它们的初始化发生在main函数之前。
- 局部变量在使用前一定要先赋值,不管是通过初始化还是赋值运算符,如果局部变量在定义时不初始化,则初始值是不确定的。
- 不能返回本地变量的地址,但是可以返回全局变量或静态本地变量的地址。
- 虽然全局变量用起来很方便,但一定要慎用,能用函数传参代替的就不要用全局变量。
- 使用全局变量和静态本地变量的函数是线程不安全的,所以尽量避免使用全局变量和静态本地变量。
在程序中,局部变量和全局变量的名称可以相同,但是在函数内,如果两个名字相同,会使用局部变量值。如下所示:
#include
/* 全局变量声明 */
int g = 20;
int main ()
{
/* 局部变量声明 */
int g = 10;
printf ("value of g = %d\n", g);
return 0;
}
输出为:
value of g = 10
局部变量可以用任意类型相符的表达式来初始化,而全局变量只能用常量表达式初始化。
eg:全局变量pi的初始化如下,
double pi = 3.14 + 0.0016; //合法的
double pi = acos(-1.0); //不合法的
但是局部变量这样初始化是可以的。全局变量的初始值要求保存在编译生成的目标代码中,所以必须在编译时就能计算出来,然而上面第二种Initializer的值必须在生成了目标代码之后在运行时调用acos
函数才能知道,所以不能用来初始化全局变量。
在C语言中,任何可以放“语句”的地方都既可以是一条语句,也可以是由{}括起来的若干条语句组成的语句块(Statement Block),如果是语句块则不需要在{}后面加;号。
语句块也可以定义局部变量,就像函数体一样。
void foo(void)
{
int i = 0;
{
int i = 1;
int j = 2;
printf("i=%d, j=%d\n", i, j);
}
printf("i=%d\n", i); /* cannot access j here */
}
语句块可以用在任何允许放语句的地方,不一定非得用在if
语句中,单独使用语句块通常是为了定义一些比函数的局部变量更“局部”的变量。
- 在本地变量定义时加上static修饰符就成为静态本地变量;
- 当函数离开的时候,静态本地变量会继续存在并保持其值;
- 静态本地变量只会在第一次进入这个函数时初始化,以后进入该函数时会保持上次离开时的值;
- 静态本地变量实际上是特殊的全局变量;
- 静态本地变量具有全局的生存期,以及作为本地变量所具有的函数内的局部作用域。
#include
int f(void);
int gall=12;
int main(int argc, char const *argv[])
{
f();
f();
f();
return 0;
}
int f(void)
{
static int all = 1;
printf("in %s all=%d\n", __func__, all);
all += 2;
printf("agn in %s all=%d\n", __func__, all);
return all;
}
输出为:
in f all=1
agn in f all=3
in f all=3
agn in f all=5
in f all=5
agn in f all=7
如下所示,定义了函数max,返回一个 int 类型。
return语句:return停止函数的执行,并返回一个值。如果函数有返回值,则必须使用带值的return。
int max(int a, int b)
{
int ret;
if(a>b){
ret=a;
}else{
ret=b;
}
return ret; //只有一个return,符合单一出口
}
形式:void 函数名(参数表)
不能使用带值的return;可以没有return;调用的时候不能做返回值的赋值。
void sum(int begin, int end)
{
int i;
int sum=0;
for(i=begin; i
如果函数要使用参数,则必须声明接收参数值的变量,这些变量称为函数的形式参数。形式参数就像函数内的局部变量,在进入函数时被创建,退出函数时被销毁。
确切地说,当我们讨论函数中的hour
这个参数时,我们所说的“参数”是指形参(Parameter),当我们讨论传一个参数23
给函数时,我们所说的“参数”是指实参(Argument),但是我习惯都叫参数而不习惯总把形参、实参这两个文绉绉的词挂在嘴边儿(事实上大多数人都不习惯),读者可根据上下文判断我指的到底是形参还是实参。
记住这条基本原理:形参相当于函数中定义的变量,调用函数传递参数的过程相当于定义形参变量并且用实参的值来初始化。
当调用函数时,有两种向函数传递参数的方式:传值、传指针。
该方法把参数的实际值复制给函数的形式参数。在这种情况下,修改函数内的形式参数不会影响实际参数。
void swap(int a, int b);
int main()
{
int a=5;
int b=6;
swap(a,b);
printf("a=%d, b=%d\n", a,b);
return 0;
}
void swap(int a, int b)
{
int t=a;
a = b,
b = t;
}
输出为:
a=5, b=6
可以看出,上述代码并不能交换a和b的值。
解析:
当上述代码在做swap(a,b)时,只是把a和b的值传给了swap函数中的a和b。除此之外,swap函数中的a,b和main中的a,b完全没有关系。所以,在swap函数中对参数a和b做的任何事情,和main中的a和b没有任何关系。因此,不能交换a和b的值。
通过指针传递方式,形参为指向实参地址的指针,当对形参的指向操作时,就相当于对实参本身进行操作。
传递指针可以让多个函数访问指针所引用的对象,而不用把对象声明为全局可访问。
void swap(int *x, int *y); //函数声明
int main()
{
int a=100; //局部变量定义
int b=200;
printf("交换前a的值:%d\n", a);
printf("交换前b的值:%d\n", b);
swap(&a, &b); //调用函数来交换值
printf("交换后a的值:%d\n", a);
printf("交换后b的值:%d\n", b);
return 0;
}
//定义函数
void swap(int *x, int *y)
{
int temp;
temp = *x;
*x = *y;
*y = temp;
return;
}
输出为:
交换前a的值:100
交换前b的值:200
交换后a的值:200
交换后b的值:100
该实例表明,与传值调用不同,传指针调用不但在函数内部改变了a和b的值,实际也改变了函数外a和b的值。
有如下的图来看加1减1时,数的变化。其中,逆时针表示的是加1,顺时针表示的是减1。
没有特殊需要,就选择int。
现代的编译器一般会设计内存对齐,所以更短的类型实际在内存中也是占据一个int的大小,虽然sizeof告诉你更小。
unsigned与否只是输出不同,内部计算一样。
如果没有特殊需要,只使用double。