0
点赞
收藏
分享

微信扫一扫

关于数组的编程题(13)

1.逆序输出数组中元素

逆序思想:对于一组数[1 2 3 4 5 6 7 8],先交换1和8,再交换2和6,... ,最后交换4和5。具体由如下函数实现。

//逆序处理
Reserve(int arr[],int sz){
int left=0;
int right=sz-1;
while(left<right){
int tmp=arr[left];
arr[left]=arr[right];
arr[right]=tmp;
left++;
right--;
}
}

代码:

#include<stdio.h>
#include<string.h>

//打印数组元素
Print(int arr[],int sz){
int i;
for(i=0;i<sz;i++){
printf("%d ",arr[i]);
}
printf("\n");
}

//逆序处理
Reserve(int arr[],int sz){
int left=0;
int right=sz-1;
while(left<right){
int tmp=arr[left];
arr[left]=arr[right];
arr[right]=tmp;
left++;
right--;
}
}

//主函数
int main(){
int arr[]={1,2,3,4,5,6,7,8,9};
int sz=sizeof(arr)/sizeof(arr[0]);
Print(arr,sz);
Reserve( arr,sz);
Print(arr,sz);
return 0;
}

运行结果

1 2 3 4 5 6 7 8 9
9 8 7 6 5 4 3 2 1

--------------------------------
Process exited with return value 0
Press any key to continue . . .

2. 交换两个数组中元素

#include<stdio.h>
#include<string.h>

//打印数组元素
Print(int arr[],int sz){
int i;
for(i=0;i<sz;i++){
printf("%d ",arr[i]);
}
printf("\n");
}

//主函数
int main(){
int arr1[]={1,2,3,4,5};
int arr2[]={5,6,7,8,9};
int sz=sizeof(arr1)/sizeof(arr1[0]);
//交换前
printf("交换前:\n");
Print(arr1,sz);
Print(arr2,sz);

int i;
for(i=0;i<sz;i++){
int tmp=arr1[i];
arr1[i]=arr2[i];
arr2[i]=tmp;
}
//交换后
printf("交换后:\n");
Print(arr1,sz);
Print(arr2,sz);
return 0;
}

运行结果

交换前:
1 2 3 4 5
5 6 7 8 9
交换后:
5 6 7 8 9
1 2 3 4 5

--------------------------------
Process exited with return value 0
Press any key to continue . . .

3.小知识

1)在32位系统中,int类型占4个字节,指针占4个字节,操作系统可以使用的最大内存空间是2^32;

2)在64位系统中,int类型占4个字节,指针占8个字节,操作系统可以使用的最大内存空间是2^64。

3)1字节(byte)=8位(bit)

4.强制类型转换的应用以及数据类型所占内存空间的理解

#include<stdio.h>

int main(){
int arr[]={1,2,3,4,5};
short *p=(short*)arr;//short占两个字节__;int占4个字节____
int i;
for(i=0;i<4;i++){
*(p+i)=0;
}
for(i=0;i<5;i++){
printf("%d ",arr[i]);
}
return 0;
}

运行结果

0 0 3 4 5
--------------------------------
Process exited with return value 0
Press any key to continue . . .

5.强制类型转换的应用以及数据类型所占内存空间的理解

#include<stdio.h>

int main(){
int a = 0x11223344;
char *pc=(char*)&a;//short占两个字节__;int占4个字节____
*pc=0;
printf("%x ",a);

return 0;
}

注释:32位机器:对于16进制地址,0x111 22 33 44中,两位十六进制数占1byte。

运行结果

11223300
--------------------------------
Process exited with return value 0
Press any key to continue . . .

6.整数和无符号数进行比较时,先把整型数转换成无符号数,再进行比较>

#include<stdio.h>

int i;//全局变量,不初始化时默认为0
int main(){
i--;
if(i>sizeof(i)){ //sizeof()用来计算变量/类型所占内存的大小---值是无符号数
printf(">\n");
}
else{
printf("<\n");
}

return 0;
}

运行结果

>

--------------------------------
Process exited with return value 0
Press any key to continue . . .

分析:关于-1;

原码:10000000 00000000 00000001

反码:111111111 11111111 11111110

补码:111111111 11111111 11111111

无符号数:111111111 11111111 11111111

整数和无符号数进行比较时,先把整型数转换成无符号数,再进行比较。

7.逗号表达式

#include<stdio.h>
int main(){
int a,b,c;
a = 5;
c = ++a;
b = ++c, c++, ++a, a++;
b += a++ + c;
printf("a=%d b=%d c=%d\n",a,b,c);

return 0;
}

运行结果:

a=9 b=23 c=8

--------------------------------
Process exited with return value 0
Press any key to continue . . .

分析:逗号表达式:从左往右以此计算,且运算符++  +   =    +=  ,优先级依次降低

a = 5;

 c = ++a; //先++a得a=6,然后c=6

 b = ++c, c++, ++a, a++;  //先算b = ++c得c=7且b=7, 再c++得c=8,再++a得a=7,最后a++得a=8

 b += a++ + c;  //由于a++是先赋值后加加,所以先计算b += a+c得b=23,再a+1得 a=9

注释:c++先赋值后加加。

8.统计二进制(补码)数中1 的个数。

类比法:类比十进制数如何计数。比如1231----2个1(采用% /)

定义count=0;num=1231;

while(num)

1231%10=1,若1=1,则执行count++得count=1,1231/10=123;

123%10=3,若3!=1,则不执行count++,123/10=12;

12%10=2,若2!=1,则不执行count++,12/10=1;

1%10=1,若1=1,则执行count++得count=2,1/10=0;

num=0结束循环,计数结束。

基于上述思想,来统计二进制数中1 的个数。

#include<stdio.h>
#include<stdlib.h>

//函数count_bit_one( )
int count_bit_one(int n){
int count=0;
while(n){
if(n%2==1){
count++;
}
n/=2;
}
return count;
}

int main(){
int num=0;
scanf("%d",&num);//13D=1101B
//写一个函数求num的二进制(补码)表示中有几个1
int count = count_bit_one(num);
printf("%d\n",count);

return 0;
}

运行结果:

输入13;
13
3

--------------------------------
Process exited with return value 0
Press any key to continue . . .

输入-1
-1
0

--------------------------------
Process exited with return value 0
Press any key to continue . . .

分析:当输入-1时,出现错误(应当输出32)。

弊端:对于负数会出错。

对于-1:

原码:10000 0000 0000 0000 0000 0000 0001

反码:1111 1111 1111 1111 1111 1111  1110

补码(反码加一):1111 1111 1111 1111 1111 1111  1111;//1是符号位

改进:将1111 1111 1111 1111 1111 1111  1111中的符号位1改成无符号数1111 1111 1111 1111 1111 1111  1111,如下代码实现。

#include<stdio.h>
#include<stdlib.h>

//函数count_bit_one( )
int count_bit_one(unsigned int n){
int count=0;
while(n){
if(n%2==1){
count++;
}
n/=2;
}
return count;
}

int main(){
int num=0;
scanf("%d",&num);//-1
//写一个函数求num的二进制(补码)表示中有几个1
int count = count_bit_one(num);
printf("%d\n",count);

return 0;
}

运行结果:

输入-1
-1
32

--------------------------------
Process exited with return value 0
Press any key to continue . . .

输入13;
13
3

--------------------------------
Process exited with return value 0
Press any key to continue . . .

补充对于正数而言,原码,反码,补码都是一样的;

但对于负数而言,原码,反码,补码(即反码+1)表示各有不同。

1.原码就是符号位加上真值的绝对值,即用第一位表示符号位,其余位表示值。

比如:如果是8位二进制:

[+1]原= 0000 0001

[-1]原 = 1000 0001

第一位是符号位,因为第一位是符号位,所以8位二进制数的取值范围就是:(即第一位不表示值,只表示正负。)

[1111 1111 , 0111 1111]即[-127 , 127]。

2.反码的表示方法是:

正数的反码是其本身;

负数的反码是在其原码的基础上,符号位不变,其余各个位取反。

[+1] = [0000 0001]原= [0000 0001]反

[-1] = [1000 0001]原= [1111 1110]反

可见如果一个反码表示的是负数,人脑无法直观的看出来它的数值。通常要将其转换成原码再计算。

3. 补码的表示方法是:

正数的补码就是其本身;

负数的补码是在其原码的基础上,符号位不变,其余各位取反,最后+1。(也即在反码的基础上+1)

[+1] = [0000 0001]原= [0000 0001]反= [0000 0001]补

[-1] = [1000 0001]原= [1111 1110]反= [1111 1111]补

对于负数,补码表示方式也是人脑无法直观看出其数值的。通常也需要转换成原码再计算其数值。

----------END----------



举报

相关推荐

0 条评论