c语言在for函数下加范围,C学习之for循环/定义函数/变量/数据类型/运算符

1.在学习“九九口诀表”的时候,对for循环突然有了很严重的认知缺陷。

for语句的一般形式:

for(循环变量赋初值;循环条件;循环变量增值)

例如:for(s=2;s<=10;s++){ }

表达式1 表达式2 表达式3 都可以省略。

表达式1省略:此时应在for语句之前给循环变量赋初值。

表达式2省略:既不判断循环条件,循环无终止的进行下去,也就是表达式2始终为真。

表达式3省略:但此程序设计者应另外保证循环能正常结束。

注:省略表达式时,它后边的“ ;”不能省略。

源代码:

#include 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;

}

但是只看源代码看不出for循环中参数的变化,所以在里边的特定位置加上打印来查看,如下:

#include int main()

{

int n;

scanf("%d", &n);

int i,j=0;

for(i = 1; i <= n; i++)

{

printf("j=%d\n",j);

for(j = 1; j <= i; j++)

{

printf("for i=%d,j=%d",i,j);

printf("%d*%d=%-3d", j, i, i * j);

}

printf("\n");

}

return 0;

}

取n=2,输出如下:

sunyuhang@666:~/c$ gcc 1.c -o 1

sunyuhang@666:~/c$ ./1

2

j=0

for i=1,j=11*1=1

j=2

for i=2,j=11*2=2 for i=2,j=22*2=4

2.定义函数然后调用函数

#include#includeint nums(int x) //定义函数

{

int i;

if(x==1)

{

return 0;

}

for(i=2;i*i<=x;i++)

{

if(x%i==0)

{

return 0;

}

}

return 1;

}

int main()

{

int m,n,j;

scanf("%d %d",&m,&n);

int count=0;

int sum=0;

for(j=m;j<=n;j++)

{

if(nums(j)==1) //调用函数

{

count++;

sum+=j;

}

}

printf("%d %d",count,sum);

return 0;

}

3.从函数中返回

3.1

int max(int a, int b)

{

int ret;

if(a>b){

ret=a;

}else{

ret=b;

}

return ret; //只有一个return,符合单一出口

}

此处定义了函数max,它返回一个int类型。

return语句:return停止函数的执行,并返回一个值。

3.2 没有返回值的函数

形式:void 函数名(参数表)

不能使用带值的return;可以没有return;调用的时候不能做返回值的赋值。

如果函数有返回值,则必须使用带值的return。

void sum(int begin, int end)

{

int i;

int sum=0;

for(i=begin; i

4.函数参数

如果函数要使用参数,则必须声明接受参数值的变量。这些变量称为函数的形式参数。

形式参数就像函数内的局部变量,在进入函数时被创建,退出函数时被销毁。

当调用函数时,有两种向函数传递参数的方式:

1.传值:

该方法把参数的实际值复制给函数的形式参数。在这种情况下,修改函数内的形式参数不会影响实际参数。

#includevoid 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的值。

2.传指针:

通过指针传递方式,形参为指向实参地址的指针,当对形参的指向操作时,就相当于对实参本身进行的操作。

传递指针可以让多个函数访问指针所引用的对象,而不用把对象声明为全局可访问。

#includevoid 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的值。

C语言在调用函数时,永远只能传值给函数。这意味着函数内的代码不会改变用于调用函数的实际参数。

所以:

1.每个函数都有自己的变量空间,参数也位于这个独立的空间中,和其他函数没有关系。

2.过去,对于函数参数表中的参数,叫做“形式参数”(如上述代码swap函数的int后边的a和b);调用函数时给的值,叫做“实际参数”(如上述swap(a,b)这条语句中的a和b)。

5.局部(本地)变量/全局变量

5.1 局部(本地)变量

在某个函数或块的内部声明的变量称为局部变量,它们只能被该函数或该代码块内部的语句使用。局部变量在函数外部是不可知的。如下所示,a,b,c是main()函数的局部变量。

#include int main ()

{

/* 局部变量声明 */

int a, b;

int c;

/* 实际初始化 */

a = 10;

b = 20;

c = a + b;

printf ("value of a = %d, b = %d and c = %d\n", a, b, c);

return 0;

}

5.2 静态本地变量

在本地变量定义时加上static修饰符就成为静态本地变量;

当函数离开的时候,静态本地变量会继续存在并保持其值;

静态本地变量的初始化只会在第一次进入这个函数时做,以后进入函数时会保持上次离开时的值;

静态本地变量实际上是特殊的全局变量;

静态本地变量具有全局的生存期,以及作为本地变量所具有的函数内的局部作用域。

#includeint 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

5.3 全局变量

定义在函数外部,通常是程序的顶部。全局变量在整个程序的生命周期内都是有效的,在任意的函数内部都能访问全局变量。

即,全局变量在声明后在整个程序中都是可用的。

没有做初始化的全局变量会得到0值,指针会得到NULL值;它们的初始化发生在main函数之前。

#include /* 全局变量声明 */

int g;

int main ()

{

/* 局部变量声明 */

int a, b;

/* 实际初始化 */

a = 10;

b = 20;

g = a + b;

printf ("value of a = %d, b = %d and g = %d\n", a, b, g);

return 0;

}

在程序中,局部变量和全局变量的名称可以相同,但是在函数内,如果两个名字相同,会使用局部变量值。如下所示:

#include /* 全局变量声明 */

int g = 20;

int main ()

{

/* 局部变量声明 */

int g = 10;

printf ("value of g = %d\n", g);

return 0;

}

输出为:value of g = 10

tips:

返回本地变量的地址是危险的,返回全局变量或静态本地变量的地址是安全的;

不要使用全局变量来在函数间传递参数和结果;

使用全局变量和静态本地变量的函数是线程不安全的,所以尽量避免使用全局变量和静态本地变量。

6.学习数据类型

6.1 二进制负数

一个字节可以表达的数:0000 0000 - 1111 1111(0-255)

补码:

考虑-1,希望-1+1->0。如何做到?

0 -> 0000 0000 ; 1 -> 0000 0001

1111 1111 + 0000 0001 -> 10000 0000

结果多出了一个1,溢出不算。

因为 0-1 -> -1,所以 -1 = (1)0000 0000 - 0000 0001 -> 1111 1111

1111 1111被当作纯二进制看待时是255,被当作补码看待时是-1;同理,对于-a,其补码就是0-a,实际是2^n-a,n是这种类型的位数。

补码的意义就是拿补码和原码可以加出一个溢出的0。

数的范围:

对于一个字节(8位),可以表达的是:0000 0000 - 1111 1111;

其中,0000 0000 -> 0;

1111 1111 ~ 1000 0000 -> -1 ~-128;

0000 0001 ~ 0111 1111 -> 1~127。

所以,有如下的图来看加1减1时,数的变化。其中,逆时针表示的是加1,顺时针表示的是减1。

01c3348edf86e175f83f587df27420cc.png

6.2 选择整数类型

没有特殊需要,就选择int。

现代的编译器一般会设计内存对齐,所以更短的类型实际在内存中也是占据一个int的大小,虽然sizeof告诉你更小。

unsigned与否只是输出不同,内部计算一样。

6.3 浮点的输入输出

f2d313d9ce0bb26831379ef73114460b.png

如果没有特殊需要,只使用double。

6.4 运算符

901cdb8dbd4be2b78d18d91e0920308b.png

6185261b3eb50ce9cbed46658a06daef.png优先级:

02f97ffb3969e0e1e360623064415404.pngdf3d8cc1d40ab1b237d3f27321de0247.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值