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----------