第六周:数据类型

编程类型解析

//给定不超过6的正整数A,考虑从A开始的连续4个数字。请输出所有由它们组成的无重复数字的3位数
//输出格式:满足条件的3位数,要求从大到小,每行6个整数,整数间以空格分隔,但行末不能有多余空格
int main()
{
    int a;
    scanf("%d",&a);
    int i,j,k;
    int cnt = 0;
    
    i = a;
    while( i<=a+3){
        j = a;
        while( j<=a+3){
            k = a;
            while( k<=a+3){
                if( i!=j ){
                    if( i!=k ){
                        if( j!=k){
                            cnt++;
                            printf("%d%d%d",i,j,k);
                            if( cnt == 6){
                                printf("\n");
                                cnt = 0;
                            }else{
                                printf(" ");
                            }
                        }
                    }
                }
                k++;
            }
            j++;
        }
        i++;
    }
    return 0;    
}
#include<stdio.h>
int main() {
	int n;
	//scanf("%d", &n);
	n=3;
	int first = 1;
	int i = 1;
	while(i < n){
		first *= 10;
		i++;
	}
	//printf("first=%d\n", first);
	//遍历100-999
	i = first;
	while(i < first*10){
		//需要一个临时的变量去记录 i 
		int t = i;
		//需要一个"和"去记录每一位数的 n次幂 
		int sum = 0;
		do {
			int d = t % 10;
			t /= 10;
			//d^2 = d*d;  d^3 = d*d*d;
			/*
			int p = 1;
			int j = 0;
			while(j < n){
				p *= d;
				j++;
			}
			//或者*/ 
			int p = d;
			int j = 1;
			while(j < n){
				p *= d;
				j++;
			}
			sum += p;
		} while(t > 0);
		if (sum == i) {
			printf("%d\n", i);
		}
		i++;
	} 
	return 0;
} 
#include<stdio.h>
int main() {
	int n;
	//scanf("%d", &n);
	n = 9;
	int i,j;
	i = 1;
	while( i <= n) {
		j = 1;
		while(j <= i){
			printf("%d*%d=%d", j,i,i*j);
			//i,j会输出9*1= 9*2= 
			//我们想要输出1*9= 2*9= 
			//如果i*j小于10,比如1*1=1 小于 10 
			if( i*j < 10){
				//输出三个空格 
				printf("   ");
			} else {
				//输出两个空格 
				printf("  ");
			} 
			j++;
		}
		//还需要在每一个行加个回车
		printf("\n"); 
		i++;
	}
	
	return 0;
} 
#include<stdio.h>
int main() {
	int m,n;
	int i;
	//个数 
	int cnt = 0;
	int sum = 0;
	
	scanf("%d %d", &m, &n); 
	//如果m是 1,单独做一个特殊的判断 
	if(m == 1)
		m=2;
		
	for(i=m; i<=n; i++){
		int isPrime = 1;
		int k;
		//需要有另外一个循环去证明 i是不是isPrime
		for(k=2; k<i-1; k++){
			if(i%k == 0){
				isPrime = 0;
				break;
			}
		}
		// 判断 i 是否素数
		if(isPrime) {
			cnt++;
			sum+=i;
		} 
	}
	printf("%d %d\n", cnt, sum);
	
	return 0;
} 
#include <stdio.h>
int main(){
	//随机数,猜测的最大次数 
    int number,n;
	//用户每次猜测的数字 
	int inp;
	//  finished为 1 则表示猜中,0 没猜中 
    int finished = 0;
    // 记录猜测次数
    int cnt = 0;
    scanf("%d %d",&number,&n);
    while(scanf("%d",&inp)){
        cnt++;
        //如果这个数小于0 或 猜测次数大于最大猜测次数 ,则输入不合法
        if(inp < 0 || cnt > n){
            printf("Game Over\n");
            break;
        }
        // 输入猜测数太大
        if(inp > number){
            printf("Too big\n");
        // 输入猜测数太小
        }else if(inp < number){
            printf("Too small\n");
        // 输入猜测数与随机数相等
        }else{
            // 1次成功
            if(cnt == 1){
				printf("Bingo!\n");
             // 3次以内成功
			}else if(cnt <= 3){
				printf("Lucky You!\n");
            // 3次以上成功
			}else{
				printf("Good Guess!\n");
			}
            finished = 1;
            if(finished == 1) break;
        }
    }
    return 0;
}
#include<stdio.h>
int main() {
	int n;
    //分子,分母 
	double dividend,divisor;
	double sum = 0.0;
	int i;
	double t;
	
	scanf("%d", &n);
	// n = 2000;
	dividend = 2;
	divisor = 1;
	for(i = 1; i <= n; i++){
		sum += dividend/divisor;
		t = dividend;
		dividend = dividend + divisor;
		divisor = t;
	}
	printf("%.2f\n", sum);
	
	return 0;
} 
#include<stdio.h>
int main() {
	//分子,分母 
	int dividend,divisor;
	scanf("%d/%d", &dividend, &divisor);
	
	int a = dividend;
	int b = divisor;
	int t;
	//辗转相除法算出最大公约数 
	while(b > 0){
		t = a % b;
		a = b;
		b = t;
	}
	printf("%d/%d\n", dividend/a, divisor/a);
	
	return 0;
} 
#include<stdio.h>
int main() { 
	int x;
	scanf("%d", &x);
	
	if(x < 0){
		printf("fu ");
		x = -x;
	}
	int mask = 1;
	int t = x;
	//辗转相除法算出最大公约数 
	while(t > 9){
		t /= 10;
		mask *= 10;
	}

	do{
		int d = x / mask;
		switch(d){
			case 0: printf("ling"); break;
			case 1: printf("yi"); break;
			case 2: printf("er"); break;
			case 3: printf("san"); break;
			case 4: printf("si"); break;
			case 5: printf("wu"); break;
			case 6: printf("liu"); break;
			case 7: printf("qi"); break;
			case 8: printf("ba"); break;
			case 9: printf("jiu"); break;
		}
		// 最后不要有行末的空格 
		if (mask > 9) printf(" ");
		x %= mask; 
		mask /= 10;
	} while(mask > 0);
	printf("\n");
	
	return 0;
} 
#include<stdio.h>
int main() { 
	int a,n;
	scanf("%d %d", &a, &n);
	
	int sum = 0;
	int i;
	//每一轮的数字 
	int t = 0;
	// 0*10+2 2*10+2 (2*10+2)*10+2
	for(i=0; i<n; i++){
		t = t*10+a;
		sum += t;
	}
	printf("%d\n", sum);
	
	return 0;
} 

C语言的类型

整数

  1. char:一字节(8比特)-128至127
  2. short:2字节 -32768至32767
  3. int:取决于编译器(CPU),通常的意义都是"1个字"
  4. long:取决于编译器(CPU),通常的意义是"1个字"(4或8字节)
  5. long long:8字节
*整数的内部表达
  1. 计算机内部一切都是二进制
  2. 18 -> 00010010
  3. 0 -> 00000000
  4. -18 ->?
*如何表示负数
  1. 十进制用"-"来表示负数,在做计算的时候
  2. 加减是做相反的运算
  3. 乘除时当作正数,计算完毕后对结果的符号取反
*二进制负数
  1. 1个字节可以表达的数:0000 0000 - 1111 1111(0-255)

三种方案:

  1. 仿照十进制,有一个特殊的标志表示负数
  2. 取中间的数为0,如100 0000表示0,比它小的是负数,比它大的是正数
  3. 补码(实际上使用的,方案1和2都有缺陷)
*补码

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

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

​ 1111 1111被当作纯二进制看待时,是255,被当作补码看待时是-1

​ 同理,对于-a,其补码就是0-a,实际是2的n次方-a,n是这种类型的位数

数的范围
  1. 对于一个字节(8位),可以表达的是:0000 0000 ->1111 1111
  2. 其中0000 0000->0 、1111 1111至1000 0000 ->-1至-128 、 0000 0001至0111 1111->1至127

浮点数

float、double、long double

逻辑

bool

指针

自定义类型

类型有何不同

  1. 类型名称:int、long、double
  2. 输入输出时的格式化:%d、%ld、%lf
  3. 所表达的数的范围:char<short<int<float<double
  4. 内存中所占据的大小:1个字节到16个字节
  5. 内存中的表达形式:二进制数(补码)、编码
sizeof
  1. 是一个运算符,给出某个类型或者变量在内存中所占据的字节数

例如:sizeof(int)、size(i)

  1. 是静态运算符,它的结果在编译时刻就决定了
  2. 不要在sizeof的括号里做运算,这些运算不会进行的
unsigned
  1. 在整形类型前加上unsigned使得它们变成无符号的整数
  2. 内部的二进制表达没变,变的是如何看待它们。如何输出
  3. 1111 1111对于char来说是-1,对于unsigned char来说是255
  4. 如果一个字面量常数想要表达自己是unsigned,可以在后面加上U或者u,255U
  5. 用L或者l表示long( long)
  6. unsigned初衷并非扩展数能表达的范围,而是为了做纯二进制运算,主要是为了移位
整数越界

整数是以纯二进制方式进行计算的,所以:

  1. 1111 1111+1 -> 1 0000 0000 ->0
  2. 0111 1111+1 -> 1 0000 0000 ->-128
  3. 1000 0000-1 -> 0111 1111 ->127
整数的输入输出

只有两种形式:int或者long long

  1. %d:int
  2. %u:unsigned
  3. %ld:long long
  4. %lu:unsigned long long
8进制和16进制
  1. 一个以0开始的数字字面量是8进制
  2. 一个以0x开始的数字字面量是16进制
  3. %o用于8进制,%x用于16进制
  4. 8进制跟16进制只是如何把数字表达为字符串,与内部如何表达数字无关
  5. 16进制很适合表达二进制数据,因为4位二进制正好是一个16进制位
  6. 8进制的一位数字正好表达3位二进制
  7. 因为早期计算机的字长是12的倍数,而非8
选择整数类型
  1. 为什么整数要有那么多种?为了准确表达内存,做底层程序的需要
  2. 没有特殊需要就选择int
  3. 现在CPU的字长普遍是32位或者64位,一次内存读写就是一个int,一次计算也是一个int,选择更短的类型不会更快,甚至可能更慢
  4. 现代的编译器一般会设计内存对齐,所以更短的类型实际在内存中有可能也占据一个int的大小(虽然sizeof告诉你更小)
  5. unsigned与否只是输出的不同,内部计算是一样的

浮点数

浮点类型
类型字长范围有效数字
float32正负(1.20×100,正负inf,NaN)7
double64正负(2.20×100,正负inf,NaN)15
浮点的输入输出
类型scanfprintf
float%f%f,%e
double%lf%f,%e
科学计数法
  1. 可选的+或者-符号
  2. 可以用e或者E
  3. 整个词不能有空格
  4. 小数点也是可选的
  5. 符号可以是正负也可以省略(表示+)
  6. 例如:-5.67E+16
输出精度

在%和f之间加上.n可以指定输出小数点后几位,这样的输出是做四舍五入的

  1. printf(“%.3f\n”,-0.0049);
  2. printf(“%.30f\n”,-0.0049);
  3. printf(“%.3f\n”,-0.00 49);
超出范围的浮点数
  1. printf输出inf表示超过范围的浮点数:+无穷
  2. printf输出nan表示不存在的浮点数
浮点运算的精度
  1. 带小数点的字面量是double而非float
  2. float需要用f或者F后缀来表明身份
浮点数的内部表达
  1. 浮点数在计算时是由专用的硬件部件实现的
  2. 计算double和float所用的部件是一样的
选择浮点类型
  1. 如果没有特殊需要,只使用double
  2. 现代CPU能直接对double做硬件运算,性能不会比float差,在64位的机器上,数据存储的速度也不比float慢

字符

字符类型

char是一种整数,也是一种特殊的类型:字符。这是因为:

  1. 用单引号表示的字符字面量:‘a’,‘1’
  2. "也是一个字符
  3. printf和scanf里用%c来输入输出字符

字符的输入输出

  1. 如何输入’1’这个字符给char c?

scanf(“%c”,&c);->1

scanf(“%d”,&i);c=i ;->49

  1. ‘1’的ASCII编码是49,所以当c==49时,它代表’1’
  2. 这是一个49的各自表述
混合输入

有何不同

scanf(“%d %c”,&i,&c);

scanf(“%d%c”,&i,&c);

字符计算
  1. 一个字符加一个数字得到ASCII码表中那个数之后的字符
  2. 两个字符的减,得到它们在表中的距离
大小写转化
  1. 字母在ASCII表中是顺序排列的
  2. 大写字母和小写字母是分开排列的,并不在一起
  3. ‘a’-‘A’可以得到两段之间的距离,于是a+‘a’-‘A’可以把一个大写字母变成小写字母,反之把这个运算中的‘a’与‘A’互相调换即可把一个小写字母变成大写字母

逃逸字符

用来表达无法印出来的控制字符或特殊字,在那些具有特殊符号的前面加上\即可将其当作普通字符使用

字符意义
\b回退一格
\t到下一个表格位
\n换行
\r回车
"双引号
单引号
\反斜杠本身
制表位
  1. 每行的固定位置
  2. 一个\t使得输出从下一个制表位开始
  3. 用\t能使上下两行对齐

逻辑类型

bool

  1. 在宏定义中加上#include<stdbool.h>
  2. 之后就可以使用bool和true跟false

bool的运算

  1. bool实际上还是以int的手段实现的,所以可以当作int来计算
  2. 也只能当作int来输入输出

类型转换

自动类型转换
  1. 当运算符的两边出现不一致的类型时,会自动转换成较大的类型
  2. 大的意思是能表达的数的范围更大
  3. char->short->int->long->long long
  4. int->float->double
  5. 对于printf,任何小于int的类型会被转化成int;float会被转换成double
  6. 但是scanf不会,要输入short,需要%hd
强制类型转换
  1. 要把一个量强制转换成另一个类型(通常是较小的类型),需要:(类型)值
  2. 比如(int)10.2 (short)32
  3. 需要注意这个时候的安全性,小的变量不总能表达大的量
  4. 这个只是从那个变量计算出了一个新的类型的值,它并不改变那个变量,无论值还是类型都不改变
  5. 强制类型转换的优先级高于四则运算

有些运算

逻辑运算

  1. 逻辑运算是对逻辑量进行的运算,结果只有0或者1
  2. 逻辑量是关系运算或逻辑运算的结果
运算符描述示例结果
逻辑非!a如果a是true结果就是false如果a是fasle结果就是true
&&逻辑与a&&b如果a和b都是是true结果就是true否则就是false
||逻辑或a||b如果a和b有一个是true结果就是true两个都是false,结果才是false
try(尝试)

如何判断一个字符c是否是大写字母?

c >= ‘A’&&c<=‘Z’

逻辑优先级

!>&&>||

总体优先级排名

优先级运算符结合性
1()从左到右
2!± ++ –从右到左(单目的+和-)
3/ %从左到右
4+ -从左到右
5< <= > >=从左到右
6== !=从左到右
7&&从左到右
8||从左到右
9= += -= *= /= %=从右到左
短路
  1. 逻辑运算是自左向右进行的,如果左边的结果已经能够决定结果了,就不会做右边的计算了
  2. 对于&&,左边是false时就不会做右边的运算了
  3. 对于||,左边是true时就不会做右边的运算了
  4. 不要把赋值,包括复合赋值组合进表达式

条件运算符

  1. count = (count>20)?count-10:count+10;
  2. 当count>20是真的时候执行前者,是假执行后者
  3. 优先级:条件运算符的优先级高于赋值运算符,但是低于其他运算符
  4. 不要嵌套条件表达式(很容易出问题)

逗号运算符

  1. 逗号用来连接两个表达式,并以其右边的表达式的值作为它的结果。逗号的优先级是所有运算符中最低的,所以它两边的表达式会先计算;逗号的组合关系是自左像右,所以左边的表达式会先计算,而右边的表达式的值就留下来作为逗号运算的结果
  2. 比如在for中使用
  3. for(i = 1,j=8;i<j;i++,j–)
  • 24
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值