前言
本文为业余学习《明解C语言入门篇》的记录,包含代码清单和练习题。
开始学习时间:2022年8月21日
+++++++++++++++++++++++++++++++
第1章 初识C语言
第2章 运算和数据类型
第3章 分支结构程序
第4章 程序的循环控制
第5章 数组
第6章 函数
第7章 基本数据类型
第8章 动手编写各种程序吧
第9章 字符串的基本知识
第10章 指针
第11章 字符串和指针
第12章 结构体
第13章 文件处理
+++++++++++++++++++++++++++++++
第7章、基本数据类型
7-1 基本数据类型和数
7-2 整型和字符型
代码清单 7-1
//显示字符型和整型数据类型的表示范围
#include <stdio.h>
#include <limits.h>
int main()
{
puts("该环境下各字符型、整型数值的范围");
printf("char : %d~%d\n" , CHAR_MIN , CHAR_MAX );
printf("signed char : %d~%d\n" , SCHAR_MIN , SCHAR_MAX);
printf("unsigned char : %d~%d\n" , 0 , UCHAR_MAX);
printf("short : %d~%d\n" , SHRT_MIN , SHRT_MAX);
printf("int : %d~%d\n" , INT_MIN , INT_MAX);
printf("long : %ld~%ld\n" , LONG_MIN , LONG_MAX);
printf("unsigned short : %u~%u\n" , 0 , USHRT_MAX);
printf("unsigned : %u~%u\n" , 0 , UINT_MAX);
printf("unsigned long : %lu~%lu\n" , 0 , ULONG_MAX);
return 0;
}
代码清单 7-2
//判断char型有无符号
#include <stdio.h>
#include <limits.h>
int main()
{
printf("这个编译器中的char型是");
CHAR_MIN?puts("有符号的。"):puts("无符号的。");
return 0;
}
代码清单 7-3
//显示字符型和整形的长度
#include <stdio.h>
int main()
{
printf("sizeof(char) =%u\n",(unsigned) sizeof(char));
printf("sizeof(short) =%u\n",(unsigned) sizeof(short));
printf("sizeof(int) =%u\n",(unsigned) sizeof(int));
printf("sizeof(long) =%u\n",(unsigned) sizeof(long));
return 0;
}
代码清单 7-4
//显示数据类型和变量的长度
#include <stdio.h>
int main()
{
int na=0,nb=0;
double dx=0,dy=0;
printf("sizeof(int) =%u\n", (unsigned) sizeof(int));
printf("sizeof(double) =%u\n", (unsigned) sizeof(double));
printf("sizeof(na) =%u\n", (unsigned) sizeof(na));
printf("sizeof(dx) =%u\n", (unsigned) sizeof(dx));
printf("sizeof(na+nb) =%u\n", (unsigned) sizeof(na+nb));
printf("sizeof(na+dy) =%u\n", (unsigned) sizeof(na+dy));
printf("sizeof(dx+dy) =%u\n", (unsigned) sizeof(dx+dy));
return 0;
}
代码清单 7-5
//求数组的元素个数
#include <stdio.h>
int main()
{
int vi[10]={0};
double vd[25]={0};
printf("数组vi的元素个数=%u\n",(unsigned)(sizeof(vi)/sizeof(vi[0])));
printf("数组vd的元素个数=%u\n",(unsigned)(sizeof(vd)/sizeof(vd[0])));
return 0;
}
练习 7-1
//创建一个程序,显示各表达式的值,并加以说明
#include <stdio.h>
int main()
{
int n=0;
printf("sizeof 1 = %u\n",(unsigned) sizeof 1); //常量1为int型,长度为4
printf("sizeof +1 = %u\n",(unsigned) sizeof +1); //常量+1为有符号整型,长度为4
printf("sizeof -1 = %u\n",(unsigned) sizeof -1); //常量-1为有符号整型,长度为4
printf("sizeof(unsigned)-1 = %u\n",(unsigned) sizeof(unsigned)-1); //sizeof(unsigned)=4,4-1=3,结果为3
printf("sizeof(double)-1 = %u\n",(unsigned) sizeof(double)-1); //sizeof(double)=8,8-1=7,结果为7
printf("sizeof((double)-1) = %u\n",(unsigned) sizeof((double)-1)); //double为浮点型,浮点型-整型=浮点型,结果为8
printf("sizeof n+2 = %u\n",(unsigned) sizeof n+2); //整型+2,结果为6
printf("sizeof(n+2) = %u\n",(unsigned) sizeof(n+2)); //(n+2)=整型,结果为4
printf("sizeof(n+2.0) = %u\n",(unsigned) sizeof(n+2.0)); //整型+浮点型=浮点型,结果为8
return 0;
}
代码清单 7-6
//按位运算
#include <stdio.h>
int count_bits(unsigned x)
{
int bits=0;
while(x)
{
if(x & 1U)
{
bits++;
}
x>>= 1;
}
return bits;
}
int int_bits()
{
return count_bits(~0u);
}
void print_bits(unsigned x)
{
int i;
for(i=int_bits() -1;i>=0;i--)
{
putchar(((x>>i) & 1U) ? '1' : '0');
}
}
int main()
{
unsigned a,b;
printf("请输入两个非负整数。\n");
printf("a:"); scanf("%u",&a);
printf("b:"); scanf("%u",&b);
printf("\na = "); print_bits(a);
printf("\nb = "); print_bits(b);
printf("\na & b = "); print_bits(a & b);
printf("\na | b = "); print_bits(a | b);
printf("\na ^ b = "); print_bits(a ^ b);
printf("\n~a = "); print_bits(~a);
printf("\n~b = "); print_bits(~b);
putchar('\n');
return 0;
}
代码清单 7-7
//显示对unsigned型的值进行左移和右移后的值
#include <stdio.h>
int count_bits(unsigned x)
{
int bits=0;
while(x)
{
if(x & 1U)
{
bits++;
}
x>>= 1;
}
return bits;
}
int int_bits()
{
return count_bits(~0u);
}
void print_bits(unsigned x)
{
int i;
for(i=int_bits() -1;i>=0;i--)
{
putchar(((x>>i) & 1U) ? '1' : '0');
}
}
int main()
{
unsigned x,n;
printf("非负整数:"); scanf("%u",&x);
printf("位移位数:"); scanf("%u",&n);
printf("\n整数 = "); print_bits(x);
printf("\n左移后的值 = "); print_bits(x<<n);
printf("\n右移后的值 = "); print_bits(x>>n);
putchar('\n');
return 0;
}
练习 7-2
/*
编写一个程序,确认只要没有发生高位溢出,则
无符号整数位左移后的值等于其乘以2的指数幂后的值
无符号整数位右移后的值等于其除以2的指数幂后的值
*/
#include <stdio.h>
int power(unsigned x)
{
int i;
unsigned product=1;
if(x)
{
for(i=1;i<=x;i++)
{
product*=2;
}
}
return product;
}
int main()
{
int nx,ny;
printf("非负整数:"); scanf("%u",&nx);
printf("位移位数:"); scanf("%u",&ny);
printf("nx = %u\n",nx);
printf("左移后的值 = %u\n",nx<<ny);
printf("n乘以2的指数幂的值 = %u\n",nx*power(ny));
printf("右移后的值 = %u\n",nx>>ny);
printf("除以2的指数幂的值 = %u\n",nx/power(ny));
return 0;
}
练习 7-3
/*
编写rrotate函数,返回无符号整数x右移n位后的值。
unsigned rrotate(unsigned x,int n) {…}
编写lrotate函数,返回无符号整数x左移n位后的值。
unsigned lrotate(unsigned x,int n) {…}
*/
#include <stdio.h>
unsigned rrotate(unsigned x,int n)
{
return x>>n;
}
unsigned lrotate(unsigned x,int n)
{
return x<<n;
}
int main()
{
unsigned nx;
int n_bits;
printf("非负整数:"); scanf("%u",&nx);
printf("位移位数:"); scanf("%d",&n_bits);
printf("%u右移%d位后的值为%u。\n",nx,n_bits,rrotate(nx,n_bits));
printf("%u左移%d位后的值为%u。\n",nx,n_bits,lrotate(nx,n_bits));
return 0;
}
练习 7-4
/*
编写set函数,返回将无符号整数x的第pos位设为1后的值。
unsigned set(unsigned x,int pos) {…}
编写reset函数,返回将无符号整数x的第pos位设为0后的值。
unsigned reset(unsigned x,int pos) {…}
编写inverse函数,返回将无符号整数x的第pos位取反后的值。
unsigned set(unsigned x,int pos) {…}
*/
#include <stdio.h>
int count_bits(void);
unsigned set(unsigned x,int pos);
unsigned reset(unsigned x,int pos);
unsigned inverse(unsigned x,int pos);
int main()
{
unsigned u_x;
int i_pos;
printf("非负整数:"); scanf("%u",&u_x);
printf("第pos位:"); scanf("%d",&i_pos);
printf("%u第%d位设为1后的值为%u。\n",u_x,i_pos,set(u_x,i_pos));
printf("%u第%d位设为0后的值为%u。\n",u_x,i_pos,reset(u_x,i_pos));
printf("%u第%d位取反后的值为%u。\n",u_x,i_pos,inverse(u_x,i_pos));
return 0;
}
int count_bits(void)
{
unsigned x=~0U;
int bits=0;
while(x)
{
if(x&1U)
{
bits++;
}
x>>=1;
}
return bits;
}
unsigned set(unsigned x,int pos)
{
return x|1U<<count_bits()-pos;
}
unsigned reset(unsigned x,int pos)
{
return x&~(1U<<count_bits()-pos);
}
unsigned inverse(unsigned x,int pos)
{
return x<<pos-1>>count_bits()-1&1U?reset(x,pos):set(x,pos);
}
练习 7-5
/*
编写程序,显示无符号整数x从第pos位后的n位设为1后的值。
unsigned set_n(unsigned x,int pos,int n) {…}
编写程序,显示无符号整数x从第pos位后的n位设为0后的值。
unsigned reset_n(unsigned x,int pos,int n) {…}
编写程序,显示无符号整数x从第pos位后的n位取反后的值。
unsigned inverse_n(unsigned x,int pos,int n) {…}
*/
#include <stdio.h>
unsigned set_n(unsigned x,int pos,int n);
unsigned reset_n(unsigned x,int pos,int n);
unsigned inverse_n(unsigned x,int pos,int n);
int count_bits(void);
int main()
{
unsigned x;
int pos,n;
printf("请输入一个非负整数:"); scanf("%u",&x);
printf("从第几位开始修改:"); scanf("%d",&pos);
printf("要修改多少位:"); scanf("%d",&n);
printf("%u从%d位开始将%d位设为1后的值为%u。\n",x,pos,n,set_n(x,pos,n));
printf("%u从%d位开始将%d位设为0后的值为%u。\n",x,pos,n,reset_n(x,pos,n));
printf("%u从%d位开始将%d位取反后的值为%u。\n",x,pos,n,inverse_n(x,pos,n));
return 0;
}
unsigned set_n(unsigned x,int pos,int n)
{
int i;
int bit=count_bits()-pos;
for(i=bit;i>bit-n;i--)
{
x=x|1U<<i;
}
return x;
}
unsigned reset_n(unsigned x,int pos,int n)
{
int i;
int bit=count_bits()-pos;
for(i=bit;i>bit-n;i--)
{
x=x&~(1U<<i);
}
return x;
}
unsigned inverse_n(unsigned x,int pos,int n)
{
int i;
int bit=count_bits()-pos;
for(i=bit;i>bit-n;i--)
{
x=x&1U<<i?x&~(1U<<i):x|1U<<i;
}
return x;
}
int count_bits(void)
{
unsigned x=~0U;
int bits=0;
while(x)
{
if(x&1U)
{
bits++;
}
x>>=1;
}
return bits;
}
代码清单 7-8
//以十进制、二进制、八进制和十六进制的形式显示0~65535
#include <stdio.h>
int count_bits(unsigned x);
int int_bits(void);
void print_nbits(unsigned x,unsigned n);
int main()
{
unsigned i;
for(i=0;i<=65535U;i++)
{
printf("%5u ",i);
print_nbits(i,16);
printf(" %06o %04X\n",i,i);
}
return 0;
}
int count_bits(unsigned x)
{
int bits=0;
while(x)
{
if(x&1U)
{
bits++;
}
x>>=1;
}
return bits;
}
int int_bits(void)
{
return count_bits(~0U);
}
void print_nbits(unsigned x,unsigned n)
{
int i=int_bits();
i=(n<i)?n-1:i-1;
for(;i>=0;i--)
{
putchar(((x>>i)&1u)?'1':'0');
}
return 0;
}
练习 7-6
//编写程序确认对无符号整数执行算术运算不会发生数据溢出
#include <stdio.h>
#include <limits.h>
int main()
{
unsigned x,y;
x=50000;
y=UINT_MAX-x+100;
printf("UINT_MAX = %u\n",UINT_MAX);
printf("x = %u\n",x);
printf("y = %u\n",y);
printf("x+y = %u\n",x+y); //结果为99
return 0;
}
7-3 浮点型
代码清单 7-9
//表示浮点型变量的值
#include <stdio.h>
int main()
{
float a=123456789012345678901234567890.0;
double b=123456789012345678901234567890.0;
long double c=123456789012345678901234567890.0;
printf("a = %f\n",a);
printf("b = %f\n",b);
printf("c = %lf\n",c);
return 0;
}
练习 7-7
//输入并显示float型、double型和long double型变量
#include <stdio.h>
int main()
{
float a;
double b;
long double c;
int retry;
do
{
printf("请输入实数a:"); scanf("%f",&a);
printf("请输入实数b:"); scanf("%lf",&b);
printf("请输入实数c:"); scanf("%lf",&c);
printf("a = %f\n",a);
printf("b = %.15f\n",b);
printf("c = %.20lf\n",c);
printf("是否继续?是…[999],否…[888]:");
scanf("%d",&retry);
}while(retry==999);
return 0;
}
代码清单 7-10
//求出两点间的距离
#include <stdio.h>
#include <math.h>
double dist(double x1,double y1,double x2,double y2)
{
return sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
}
int main()
{
double x1,y1;
double x2,y2;
printf("求两点间的距离。\n");
printf("点1…X坐标:"); scanf("%lf",&x1);
printf(" Y坐标:"); scanf("%lf",&y1);
printf("点2…X坐标:"); scanf("%lf",&x2);
printf(" Y坐标:"); scanf("%lf",&y2);
printf("两点之间的距离为%f。\n",dist(x1,y1,x2,y2));
return 0;
}
练习 7-8
//使用sizeof运算符显示3种浮点型的长度
#include <stdio.h>
int main()
{
printf("float = %d\n",sizeof(float));
printf("double = %d\n",sizeof(double));
printf("long double = %d\n",sizeof(long double));
return 0;
}
练习 7-9
//输入一个实数作为面积,求正方形的边长
#include <stdio.h>
#include <math.h>
int main()
{
double side;
double area;
printf("请输入正方形的面积:");
scanf("%lf",&area);
printf("此正方形的边长为%.3f。\n",sqrt(area));
return 0;
}
代码清单 7-11
//以0.01为单位从0.0递增至1.0的循环
#include <stdio.h>
int main()
{
float X;
for(X=0.0;X<=1.0;X+=0.01)
{
printf("X = %f\n",X);
}
return 0;
}
代码清单 7-12
//以0.01为单位从0.0递增至1.0的循环(用整数控制)
#include <stdio.h>
int main()
{
int i;
double x;
for(i=1;i<=100;i++)
{
x=i/100.0;
printf("x = %f\n",x);
}
return 0;
}
练习 7-10
//横向显示代码清单7-11和7-12所得值的过程
#include <stdio.h>
int main()
{
int i;
float x = 0.0;
for (i = 0;i<=100;i++)
{
printf("%03d:",i+1);
printf("x = %f ",x);
x+=0.01;
printf("x = %f\n",i/100.0);
}
return 0;
}
练习 7-11
//改写代码清单7-11和7-12,求递增后的所有值的累计
#include <stdio.h>
int main()
{
int i;
float x = 0.0;
float sum1 = 0.0;
float sum2 = 0.0;
for (i = 0;i<=100;++i)
{
printf("%03d:",i);
printf("x = %f ",x);
printf("x = %f\n",i/100.0);
x+=0.01;
sum1+=x;
sum2+=i/100.0;
}
puts("--------------------------------");
printf("累计: %f %f\n",sum1,sum2);
return 0;
}
7-4 运算和运算符
总结
summary
//对浮点数进行多次加法运算
#include <stdio.h>
int main()
{
int i;
int no;
float value;
float sum=0.0;
printf("对浮点数进行多次加法运算。\n");
printf("值:"); scanf("%f",&value);
printf("次数:"); scanf("%d",&no);
for(i=0;i<no;i++)
{
sum+=value;
}
printf("加法运算的结果是%f。\n",sum);
return 0;
}