文档章节

C程序设计语言--第二章:类型,运算符与表达式

fzyz_sb
 fzyz_sb
发布于 2013/09/27 21:44
字数 2083
阅读 115
收藏 0
点赞 0
评论 0

变量和常量是程序处理的两种基本数据对象.声明语句说明变量的名字及类型,也可以指定变量的初值.运算符指定将要进行的操作.表达式则把变量与常量组合起来生成新的值.对象的类型决定该对象可取值的集合以及可以对该对象执行的操作.

2.1 变量名

名字是由字母和数字组成的序列,但第一个字符必须为字母.下划线'_'被看作是字母.

由于库例程的名字通常以下划线开头,因此变量名不要以下划线开头.变量名使用小写字母,符号常量名全部使用大写字母.

选择的变量名要能够尽量从字面上表达变量的作用,这样做不容易引起混淆.局部变量一般使用较短的变量名(尤其是循环控制变量),外部变量使用较长的名字.

2.2 数据类型及长度

C语言只提供下列几种基本数据类型:

char    字符型,占用一个字节,可以存放本地字符集中的一个字符

int        整型,通常反映了所用机器中整数的最自然长度

float    单精度浮点型

double    双精度浮点型

C语言也提供了限定符:short和long用于限定整型,类型限定符signed与unsigned可用于限定char类型或任何整型.

习题2-1:备注:这里unsigned要用%u来输出,long要用%l来修饰:


#include <stdio.h>
#include <limits.h>

int main(void)
{
	signed char schar;
	unsigned char uschar;
	signed short sshort;
	unsigned short ushort;
	signed int sint;
	unsigned int usint;
	signed long slong;
	unsigned long ulong;

	schar = 0;
	while ( schar >= 0 ){
		schar++;
	}
	printf("%d\n", schar );
	printf("%d\n", -schar - 1 );
	uschar = -1;
	printf("%u\n", uschar );

	sshort = 0;
	while ( sshort >= 0 ){
		sshort++;
	}
	printf("%d\n", sshort );
	printf("%d\n", -sshort - 1 );
	ushort = -1;
	printf("%u\n", ushort );

	sint = 0;
	while ( sint >= 0 ){
		sint++;
	}
	printf("%d\n", sint );
	printf("%d\n", sint - 1 );
	usint = -1;
	printf("%u\n", usint );

	slong = 0;
	while ( slong >= 0 ){
		slong++;
	}
	printf("%d\n", slong );
	printf("%d\n", slong - 1 );
	ulong = -1;
	printf("%lu\n", ulong );

	printf("\n----------------------\n");

	printf("%d\n", SCHAR_MIN );
	printf("%d\n", SCHAR_MAX );
	printf("%u\n", UCHAR_MAX );

	printf("%d\n", SHRT_MIN );
	printf("%d\n", SHRT_MAX );
	printf("%u\n", USHRT_MAX );

	printf("%d\n", INT_MIN );
	printf("%d\n", INT_MAX );
	printf("%u\n", UINT_MAX );

	printf("%d\n", LONG_MIN );
	printf("%d\n", LONG_MAX );
	printf("%lu\n", ULONG_MAX );

	return 0;
}
程序输出:


2.3 常量

一个字符常量是一个整数,书写时将一个字符括在单引号中,如'x'.

某些字符可以通过转义字符序列(如换行符\n)表示为字符和字符串常量(转移字符怎么表示字符串常量??)

转移字符序列看起来像两个字符,但只表示一个字符.另外,我们可以用'\000'表示任意的字节大小的位模式,其中000代表1~3个八进制数字.也可以使用'xhh'来表示,而hh代表1~2个十六进制数字.


#define VTAB '\013'    /*ASCII纵向制表符*/
#define BELL '\007'    /*ASCII响铃符*/

当然,也可以写成十六进制:

#define VTAB '\xb'    /*ASCII纵向制表符*/
#define BELL '\x7'    /*ASCII响铃符*/
C语言中全部转移字符如下:
\a		响铃符
\b		回退符
\f		换页符
\n		换行符
\r		回车符
\t		横向制表符
\v		纵向制表符
\\		反斜杠
\?		问号
\'		单引号
\"		双引号
\000	        八进制
\xhh	        十六进制
字符常量'\0'表示值为0的字符,也就是空字符(null).我们通常用'\0'的形式代替0,以强调某些表达式的字符属性,但其数字值为0.

常量表达式是仅仅只包含常量的表达式.这种表达式在编译时求值(如宏定义).

字符串常量也叫字符串字面值,是用双引号括起来的0个或多个字符组成的字符序列.

枚举常量是另外一种类型的常量.枚举是一个常量整型值的列表,例如:

enum boolean { NO, YES };
在没有显式说明的情况下,enum类型中第一个枚举名的值为0,第二个为1,依此类推.

枚举为建立常量值与名字之间的关联提供了一种便利的方式.相对于#define语句来说,它的优势在于常量可以自动生成.尽管可以声明enum类型的变量,但编译器不检查这种类型的变量中存储的值是否为该枚举的有效值.不过,枚举变量提供这种检查,因此枚举比#define更有优势.此外,调试程序可以以符号形式打印出枚举变量的值.

2.4 声明

所有变量都必须先声明后使用.尽管某些变量可以通过上下文隐式声明.一个声明指定一个变量类型,后面所带的变量表可以包含一个或多个该类型的变量.

还可以在声明的同时对变量进行初始化.默认情况下,外部变量与静态变量将初始化为0.未经显示初始化的自动变量的值为未定义值(即无效值).

任何变量的声明都可以使用const限定符限定.该限定符指定变量的值不能被修改.对数组而言,const限定符指定数组所有元素的值都不能被修改.

for ( i = 0; i < lim - 1; i++ ){
	if ( ( c = getchar() ) != '\n' ){
		if ( c != EOF ){
			s[ i ] = c;
		}
	}
}
2.7 类型转换

习题2-3:

#include <stdio.h>

int htoi( char *s )
{
	int num = 0;
	int tempNum = 0;
	if ( '0' == s[ 0 ]  && ( 'x' == s[ 1 ] || 'X' == s[ 1 ] ) ){
		s += 2;
	}
	while ( '\0' != *s ){
		if ( *s >= 'a' && *s <= 'f' ){
			tempNum = *s - 'a' + 10;
		}
		else if ( *s >= 'A' && *s <= 'F' ){
			tempNum = *s - 'A' + 10;
		}
		else{
			tempNum = *s - '0';
		}
		num = num * 16 + tempNum;
		s++;
	}

	return num;
}

int main(void)
{
	printf("%d\n", htoi( "0x1b2" ) );
	printf("%d\n", htoi( "0xff" ) );
	printf("%d\n", htoi( "0x1abc" ) );

	return 0;
}
程序输出:


2.8 自增运算符与自减运算发

习题2-4:

#include <stdio.h>

void squeeze( char *s1, char *s2 )
{
	char *temp = s1;		//用于存储每次修改的值
	char *newstr = temp;	//用于初始化修改后的值
	while ( '\0' != *s2 ){
		s1 = newstr;
		temp = newstr;
		while ( '\0' != *s1 ){
			if ( *s1 != *s2 ){
				*temp++ = *s1++;
			}
			else{
				s1++;
			}
		}
		*temp = '\0';
		s2++;
	}
}

int main(void)
{
	char s1[] = "hello world i love this world";
	char s2[] = "els";
	squeeze( s1, s2 );
	printf("%s\n", s1 );

	return 0;
}
程序输出:

习题2-5:

#include <stdio.h>

int any( char *s1, char *s2 )
{
	char *temp = s1;
	char *newStr = s1;
	while ( '\0' != *s2 ){
		s1 = newStr;
		while ( '\0' != *s1 ){
			if ( *s2 == *s1 ){
				return s1 - temp;
			}
			s1++;
		}
		s2++;
	}

	return -1;
}

int main(void)
{
	printf("%d\n", any( "hello world", "owd" ) );

	return 0;
}
程序输出:

习题2-6:

#include <stdio.h>

unsigned int setbits( int x, int p, int n, int y )
{
	return ( ( x >> p ) & ( ~( ~0 << n ) ) | ( ( y >> n ) << n ) );
}

int main(void)
{
	printf("%d\n", setbits( 94, 3, 4, 164 ) );

	return 0;
}
程序输出:

习题2-7:

#include <stdio.h>

unsigned int invert( int x, int p, int n )
{
	return ( x >> ( p + n ) << ( p + n ) ) + ( ( ~( x >> p ) & ~( ~0 << n ) ) << p ) + ( x & ( ~( ~0 << p ) ) ); 
}

int main(void)
{
	printf("%d\n", invert( 94, 3, 4 ) );

	return 0;
}
程序输出:

2-8:

#include <stdio.h>

unsigned int rightrot( int x, int n )
{
	int tempNum = x;
	int numOfBit = 0;
	while ( tempNum ){
		numOfBit++;
		tempNum /= 2;
	}
	while ( n-- ){
		x = ( ( x & ~( 1 << ( numOfBit - 1 ) ) ) << 1 ) + ( x >> ( numOfBit - 1 ) );
	}

	return x;
}

int main(void)
{
	printf("%d\n", rightrot( 94, 4 ) );

	return 0;
}
程序输出:

习题2-9:

#include <stdio.h>

int bitcount( unsigned x )
{
	int b;
	for ( b = 0; x != 0; x &= x - 1 ){
		b++;
	}

	return b;
}

int main(void)
{
	printf("%d\n", bitcount( 94 ) );

	return 0;
}
程序输出:

举例来说,如果x = 1011,则关键不是在x & ( x - 1 )中x目前的值(1011),因为谁都明白x=1010,减少了一个1,关键是在对于末尾为0的时候,如何进行计数!

当x为1010的时候,x & ( x - 1 )的操作会使最右边的1消失(试想一下,x为1010,x-1为1001,在这种情况下进行&操作,是不是将最右边的1置零了呢?).于是就达到了计算1的个数的目的.

习题2-10:

#include <stdio.h>

void myLower( char *str )
{
	while ( '\0' != *str ){
		*str = ( *str >= 'A' && *str <= 'Z' ) ? ( *str + 'a' - 'A' ) : *str;
		str++;
	}
}

int main(void)
{
	char str[] = "HElLo, WoRlD";
	myLower( str );
	printf("%s\n", str );

	return 0;
}
程序输出:

2.12 运算符优先级与求值次序

x = f() + g();
f()可以在g()之前计算,也可以在g()之后计算.因此,如果函数f或g改变了另一个函数所使用的变量,那么x的结果可能会依赖于这两个函数的计算顺序.

函数调用,嵌套赋值语句,自增与自减运算符都有可能产生"副作用"---在对表达式求值的同时,修改了某些变量的值.

© 著作权归作者所有

共有 人打赏支持
fzyz_sb
粉丝 407
博文 209
码字总数 447144
作品 0
武汉
程序员
C语言-第二章、C基础与顺序结构程序设计

2_1 C语言的字符集与标识符 _1-1.C的字符集 1-2.C的标识符 注:规定:用户定义的标识符必须以字母或下划线“”“”开头,不能含有除字母、数字和下划线外的其他字符。 分类:(1)关键字 (2...

南风末
2016/10/30
14
0
Python学习笔记-Day1

初识Python 第1章 初识Python 1.1什么是编程? 编程的目的就是:让机器按照人们事先为其编写好的程序自发地去工作。 1.2编程语言分为哪些种类? 1.2.1机器语言 机器语言是用二进制代码表示的...

白马探花M10
2017/07/07
0
0
清华大学视频课件:面向对象程序设计(C++)(自主模式)

清华大学视频课件:面向对象程序设计(C++)(自主模式) 课程简介 C++是从C语言发展演变而来的一种面向对象的程序设计语言。面向对象的程序设计方法将数据及对数据的操作方法封装在一起,作...

dragonscroll
2017/11/16
0
0
读懂 ECMAScript 规格

一、概述 规格文件(specification)是计算机语言的官方标准,详细描述语法规则和实现方法。 一般来说,没有必要阅读规格,除非你要写编译器。因为规格写得非常抽象和精炼,又缺乏实例,不容...

阮一峰
2015/11/12
0
0
关东升的《从零开始学Swift》3月9日已经上架

大家一直期盼的《从零开始学Swift》于3月9日已经上架,它是关东升老师历时8个月的呕心沥血所编著,全书600多页,此本书基于Swift 2.x,通过大量案例全面介绍苹果平台的应用开发。全书共分5 部...

tony关东升
06/26
0
0
C语言-第三章、选择结构程序设计

_1.1关系运算符:<、<=、>、>=、==和!=。 _1.2关系表达式: 形式:表达式 关系运算符 表达式 如:a+b>c-d _2.1逻辑运算符:&&、 、!。 逻辑表达式:表达式 逻辑运算符 表达式 如:a&&b&&c...

南风末
2016/10/31
5
0
期末复习之C语言编程基础知识梳理

C语言是面向过程的,而C++是面向对象的 C和C++的区别: C是一个结构化语言,它的重点在于算法和数据结构。C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得到...

小辰带你看世界
03/18
0
0
关东升的《《从零开始学Swift》即将出版

大家好: 苹果2015WWDC大会发布了Swift2.0,它较之前的版本Swift1.x有很大的变化,所以我即将出版《从零开始学Swift》《从零开始学Swift》将在《Swift开发指南》第1版的基础上添加Swift2.0的...

智捷课堂
2015/08/17
0
0
《Python从小白到大牛》简介

本书是一部系统论述Python编程语言、OOP编程思想以及函数式编程思想的立体化教程(含纸质图书、电子书、教学课件、源代码与视频教程)。为便于读者高效学习,快速掌握Python编程方法。本书作...

tony关东升
06/26
0
0
第一章 数组与指针概念剖析

数组与指针生来就是双胞胎,多数人就是从数组的学习开始指针的旅程的。在学习的过程中,很自然就会经常听到或见到关于数组与指针的各种各样的看法,下面我节选一些在各种论坛和文章里经常见到...

北极心
2016/08/11
4
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

NNS域名系统之域名竞拍

0x00 前言 其实在官方文档中已经对域名竞拍的过程有详细的描述,感兴趣的可以移步http://doc.neons.name/zh_CN/latest/nns_protocol.html#id30 此处查阅。 我这里主要对轻钱包开发中会用到的...

暖冰
今天
0
0
32.filter表案例 nat表应用 (iptables)

10.15 iptables filter表案例 10.16/10.17/10.18 iptables nat表应用 10.15 iptables filter表案例: ~1. 写一个具体的iptables小案例,需求是把80端口、22端口、21 端口放行。但是,22端口我...

王鑫linux
今天
0
0
shell中的函数&shell中的数组&告警系统需求分析

20.16/20.17 shell中的函数 20.18 shell中的数组 20.19 告警系统需求分析

影夜Linux
今天
0
0
Linux网络基础、Linux防火墙

Linux网络基础 ip addr 命令 :查看网口信息 ifconfig命令:查看网口信息,要比ip addr更明了一些 centos 7默认没安装ifconfig命令,可以使用yum install -y net-tools命令来安装。 ifconfig...

李超小牛子
今天
1
0
[机器学习]回归--Decision Tree Regression

CART决策树又称分类回归树,当数据集的因变量为连续性数值时,该树算法就是一个回归树,可以用叶节点观察的均值作为预测值;当数据集的因变量为离散型数值时,该树算法就是一个分类树,可以很...

wangxuwei
昨天
1
0
Redis做分布式无锁CAS的问题

因为Redis本身是单线程的,具备原子性,所以可以用来做分布式无锁的操作,但会有一点小问题。 public interface OrderService { public String getOrderNo();} public class OrderRe...

算法之名
昨天
10
0
143. Reorder List - LeetCode

Question 143. Reorder List Solution 题目大意:给一个链表,将这个列表分成前后两部分,后半部分反转,再将这两分链表的节点交替连接成一个新的链表 思路 :先将链表分成前后两部分,将后部...

yysue
昨天
1
0
数据结构与算法1

第一个代码,描述一个被称为BankAccount的类,该类模拟了银行中的账户操作。程序建立了一个开户金额,显示金额,存款,取款并显示余额。 主要的知识点联系为类的含义,构造函数,公有和私有。...

沉迷于编程的小菜菜
昨天
1
0
从为什么别的队伍总比你的快说起

在机场候检排队的时候,大多数情况下,别的队伍都要比自己所在的队伍快,并常常懊悔当初怎么没去那个队。 其实,最快的队伍只能有一个,而排队之前并不知道那个队快。所以,如果有六个队伍你...

我是菜鸟我骄傲
昨天
1
0
分布式事务常见的解决方案

随着互联网的发展,越来越多的多服务相互之间的调用,这时候就产生了一个问题,在单项目情况下很容易实现的事务控制(通过数据库的acid控制),变得不那么容易。 这时候就产生了多种方案: ...

小海bug
昨天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部