C语言知识点总结

有段事件没有写C程序了,有些地方有些生疏了。这两天事情比较少,准备再系统的看一边C的基础知识。这里再总结一下平时没太注意的知识要点。 1、C语言的语句块 在C语言中,任何允许出现语句的地方既可以是由;号结尾的一条语句,也可以是由{}括起来的若干条语句或声明组成的语句块(Statement Block),语句块和上一章介绍的函数体的语法相同。注意语句块的}后面不需要加;号。如果}后面加了;号,则这个;号本身又是一条新的语句了,在C语言中一个单独的;号表示一条空语句(Null Statement)。

6 int main(void) 7 { 8     printf("hello\n"); 9     {};  //这里相当于两个空语句了 10 11     int i= 0; 12     { 13         int i = 1; 14         int j = 2; //每次进入语句块时为变量<code>j</code>分配存储空间,每次退出语句块时释放变量<code>j</code>的存储空间。 15         printf("i=%d, j=%d\n",i,j); 16     } 17     printf("i=%d\n", i); //can't access j here 22     return 0; 23 }

2、取模运算%

C99规定,如果ab是整型,b不等于0,则表达式(a/b)*b+a%b的值总是等于a。结合整数除法运算要Truncate Toward Zero,可以得到一个结论:%运算符的结果总是与被除数同号(想一想为什么)。其它编程语言对取模运算的规定各不相同,也有规定结果和除数同号的,也有不做明确规定的。

写一个函数,参数是整型变量x,功能是打印x的个位和十位:

25 void quwei(int x) 26 { 27     int tmp; 28 29     tmp = x%10; 30     printf("个位数为:%d\n",tmp); 31 32     tmp = (x%100)/10; 33     printf("十位数为:%d\n", tmp); 34 }

3、float和double类型

7 int main() 8 { 9      float x = 0;  //当x定义为double时候出错,问题如何解决 10     printf("input x:\n"); 11 12     scanf("%f", &x); 13 14     printf("the x is:%f\n", x); 15     printf("the ceil:%f\n", ceil(x)); 16     printf("the floor:%f\n", floor(x)); 17 18 //  printf("the result is:%f\n", myround(x)); 19 20     return 0; 21 }

问题发现:当x定义为double类型时,上面程序错误,x读取的值有误。但是编译时需要加上-Wall选项才能发现原来是类型不匹配。

如何读取double类型变量?

4、结构体的初始化

5 int main() 6 { 7     //定义复数 8     struct temp 9     { 10         double real; 11        double img; 12     }; 13 14     double x = 2.0; 15     //初始化复数 16     struct temp z1 = {x,3.0};//z1.real=2.0, z1.img=3.0 17     struct temp z2 = {3.0,};//z2.real=3.0, z2.img=0.0 18    struct temp z3 = {0};//z3.real=0.0, z3.img=0.0 19 20     return 0; 21 }

注意:z1必须是局部变量才能用另一个变量x的值来初始化它的成员,如果是全局变量就只能用常量表达式来初始化。这也是C99的新特性,C89只允许在{}中使用常量表达式来初始化,无论是初始化全局变量还是局部变量。

{}这种语法不能用于结构体的赋值,例如这样是错误的:

20     struct temp z1; 21     z1 = {3.0, 4.0};

以前我们初始化基本类型的变量所使用的Initializer都是表达式,表达式当然也可以用来赋值,但现在这种由{}括起来的Initializer并不是表达式,所以不能用来赋值。

有些时候结构体或数组中只有某一个或某几个成员需要初始化,其它成员都用0初始化即可,用Designated Initializer语法可以针对每个成员做初始化(Memberwise Initialization),很方便。Designated Initializer是C99引入的新特性,用于初始化稀疏(Sparse)结构体和稀疏数组很方便。例如:

struct temp z1 = { .y = 4.0 };

结构体变量之间使用赋值运算符是允许的,用一个结构体变量初始化另一个结构体变量也是允许的,例如:

struct complex_struct z1 = { 3.0, 4.0 }; struct complex_struct z2 = z1; z1 = z2;

同样地,z2必须是局部变量才能用变量z1的值来初始化。既然结构体变量之间可以相互赋值和初始化,也就可以当作函数的参数和返回值来传递。

struct temp add_complex(struct temp z1, struct temp z2) {      z1.x = z1.x + z2.x;      z1.y =z1.y + z2.y;      return z1; }

由.运算符组成的表达式能不能做左值取决于.运算符左边的表达式能不能做左值。在上面的例子中,z是一个变量,可以做左值,因此表达式z.x也可以做左值,但表达式add_complex(z, z).x只能做右值而不能做左值,因为表达式add_complex(z, z)不能做左值。

5、枚举

4 int main() 5 { 6     enum my_type {RED, YELLOW}; 7     int RED = 1; 8     printf("%d\t%d\n",RED, YELLOW); 9 10     return 0; 11 }

结构体的成员名和变量名不在同一命名空间中,但枚举的成员名却和变量名在同一命名空间中,所以会出现命名冲突。以上代码是不合法的:

本文参考《Linux C编程 一站式学习》

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值