C程序设计语言读书笔记(2)

    字符串常量是可以在编译时连接,常量表达式在编译时求值。

变量名首字符一定要为字母,下划线"_"被视为字母,但是库例程序名字通常以"_"开头,所以不建议使用"_"作为变量名首字母。

局部变量一般使用较短的变量名,尤其是循环变量。

但是外部变量应该使用较长且有意义的单词组合作为变量名。

带前缀0的整形常量表示八进制的数。

带前缀0X或0x的整型常量表示十六进制的数。

类似的可以将八进制或十六进制书写转义字符序列。

比如:

    '\ooo'  ooo代表1-3个八进制数字

    '\xhh'  hh代表1个或多个十六进制数字

测试程序:

#define A '\141'
#define B '\x62'

int main()
{
	int num = 0X12;
	printf("%d\n", num);

	num = 012;
	printf("%d\n", num);

	printf("%c\n", A);
	printf("%c\n", B);
	return 0;
} 

C语言在编译时可以将多个字符串常量连接起来。

printf("hello, world.\n");
printf("hello, ""world.\n");

以上两种写法是等价的。

    举是一个常量整型值的列表。

在没有显示说明的情况下,enum类型中第一个枚举名的值为0,第二个为1,以此类推。如果只指定了部分枚举名的值将依着最后一个指定值向后递增。

enum col {WHITE, BLACK, BLUE = 10, RED};  
int main()  
{  
    enum col color;  
    color = RED + 1; //RED + 1已经不是属于col范围的值,但还是合法的。  
    printf("%d\n", color); //RED为10+1=11,所以color等于12。  
    color = BLACK;   
    printf("%d\n", color);//WHITE默认为0,BLACK为1。  
    return 0;  
} 

C语言没有指定char类型的变量是signed还是unsigned。当将一个char类型转化成int的时候,结果是否为负数取决于机器。某些机器,char类型的最左为1,某些则是0。所以转化时,最左边添的数字也不同。为了保证可移植性,如果要在char类型的变量中存储非字符数据,最好指定signed或unsigned限定符。

#include <stdio.h>
int main()
{
	char a=-1;
	signed char b=-1;
	unsigned char c=-1;
	printf("a = %d\nb = %d\nc = %d\n",a,b,c);
	return 0;
}

以上程序可以测试在你的机器中,char等同于signed char还是unsigned char。

unsigned是一个很有用的类型,比如定义unsigned x;这样可以保证x >> 1无论在什么机器上运行,左边空出的位都用0填补,而不是符号位。

表达式中的float类型的操作数不会自动转换为double类型,这一点与最初的定义有所不同。float对于double类型而言,有点在于省时间和空间。

当表达式中包含unsigned类型的操作数时,转换规则要复杂一些。因为带符号与无符号值之间的比较运算是与机器相关的,因为它们取决于机器中不同整数类型大小。

#include <stdio.h>
int main()
{
	printf("%d %d %d %d\n", sizeof(int), sizeof(unsigned), sizeof(long), sizeof(unsigned long));
	printf("-1U < 1U : %d\n", (-1U < 1U));
	printf("-1L < 1U : %d\n", (-1L < 1U));
	printf("-1L > 1UL : %d\n", (-1L > 1UL));
	return 0;
}

对于不同类型的比较,首先要弄清楚它们在机器中但多少位,然后记住负数在机器中最高位为1即可。

#include <stdio.h>
#include <math.h>
int main()
{
	int n = 2;
	double ans;
	printf("size = %d\n", sizeof(n));
	ans = sqrt(n);
	printf("size = %d\n", sizeof(n));
	return 0;
}

    库函数sqrt的参数为double类型,在把n传递给函数sqrt之前先将其转为double类型。注意,强制类型转只是生成一个指定类型的n的值,n本身的值并没有改变,类型当然也没变。

C语言中的位运算只能作用于整数操作数,即只能作用于带符号或无符号的char short int long类型。

在做位运算时,要考虑代码的可移植性。即不能假定所有机器都是16位或者32位。举个具体的例子,x & ~077 要比 x & 0177700 的表达式要好,因为后者假定x是16位的数值。这种可移植性的形式并没有增加额外的开销,因为常量表达式都在编译时求值。

x *= y + 1的含义为 x = x * (y + 1) ,而不是x = x * y + 1。

赋值表达式的类型是它的做操作数的类型,其值是赋值操作完成后的值。

条件表达式可以编写出很简洁的代码。例如:

	for (i = 0;i < n;i++)
		printf("%6d%c", a[i], (i%10==9 || i == n - 1)? '\n' : ' ');
	printf("You have %d item%s.\n", n, n == 1 ? "" : "s");

    C语言中没有指定同一运算符中多个操作数的计算顺序(&& || ?: 和 ,运算符除外)。例如:x = f() + g(); f()可以在g()之前计算,也可以在g()之后计算。

C语言也没有指定函数各参数的求值顺序。

所以:

printf("%d %lf/n", ++n, pow(2, n));/*错*/

要写成:

++n;

printf("%d %lf/n"npow(2, n));

在任何一种编程语言中,如果代码的执行结果与求值顺序相关,则都是不好的程序设计风格。

写得很棒的简单C函数:

/* squeeze函数:从字符串s中删除字符c */
void squeeze(char s[], int c)
{
	int i, j;
	for(int i = j = 0; s[i] != '\0';i++)
		if (s[i] != c)
			s[j++] = s[i];
	s[j] = '\0'
}

/* strcat函数:将字符串t连接到字符串s的尾巴;s必须有足够大的空间*/
void strcat(char s[], char t[])
{
	int i, j;
	i = j = 0;
	while (s[i] != '\0')
		i++;
	while ((s[i++] = t[j++]) != '\0')
		;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值