C/ C++基础(一)

(1)& 和 &&区别

&是按位与是转换成二进制数后每位分别进行与计算

&& 是与运算,与运算是值如果x为真,y为真,则(x&&y)为真,返回一个布尔值1.

          | 和 ||区别
|是 按位或 是转换成二进制数后每位分别进行或运算
|| 是或运算,或运算是指如果x和y中有一个为真,则(x||y)为真,返回一个布尔值1.

(2)计算x转化为二进制后包含1的数量。
#include <iostream>
using namespace std;
int func(int x)
{
   int count =0;
   while(x)
   {
    count++;
        x = x&(x-1);
   }
   return count;
}

int main()
{
 cout<<func(9999)<<endl;
 return 0;
}

本题func函数返回值是形参x转化为二进制后包含1的数量。 9999转化为二进制是10011100001111.  答案为8.

(3)C中printf计算参数时是从右到左压栈的。
#include <stdio.h>
main()
{
 int b = 3;
 int arr[]={6,7,8,9,10};
 sint *ptr = arr;
 *(ptr++)+=123;
 printf("%d,%d\n",*ptr,*(++ptr));
}
C中printf计算参数时是从右到左压栈的。
几个输出结果分别如下:
printf("%d\n",*ptr);此时ptr应该指向第一个元素6.
*(ptr++)+=123应为*ptr=*ptr+123;ptr++,此时ptr应指向第二个元素7。
printf("%d\n",*(ptr-1));此时输出第一个元素129,注意此时是经过计算的。
printf("%d\n",*ptr);此时输出第二个元素7,此时ptr还是指向第二个元素7。
printf("%d,%d\n",*ptr,*(++ptr));从右到左运算,第一个是(++ptr),也就是ptr++,
*ptr=8,此时ptr指向第三个元素8,所以全为8.

(4)类型转换
#include <iostream> //gcc没有iostream
#include <stdio.h>
#include <string.h>
//#include <conio.h> //g++没有conio.h
using namespace std;
int main()
{
  float a = 1.0f;
  cout<<(int)a<<endl;
  cout<<&a<<endl;
  cout<<(int&)a<<endl;
  cout<<boolalpha<<((int)a == (int&)a)<<endl;
 
  float b = 0.0f;
  cout<<(int)b<<endl;
  cout<<&b<<endl;
  cout<<(int&)b<<endl;
  cout<<boolalpha<<((int)b == (int&)b)<<endl;
  return 0;
}

/*jj@ubuntu:~/JJ$ ./typeconvert
1
0xbfd2c278
1065353216
false
0
0xbfd2c27c
0

true

因为1.0(float)和1(int)在内存中的表示不一样
后半截会输出true,因为0.0的浮点表示和0的整形表示在内存中是一样的
int&是引用类型,(int &)a的意思是将a存储单元开始的内容解释为一个int引用.
前面输出的是1065353216,而不是1。这是因为浮点数在内存里和整数里的存储方式不同,(int&)a相当于将该浮点数地址开始的sizeof(int)个字节当成int型的结果输出,因此这取决于float型数据在内存中的存储方式,而不是经过(int&)a显示转换的结果。因为float a = 1.0f 在内存中的表示都是3f800000,而浮点数和一般整数不一样,所以当(int&)a强制转换时,会把内存值3f8000000当作int型输出,所以结果自然变成了1065353216(0x3f800000的十进制表示)。

*/


#include <stdio.h>
int main()
{
   unsigned int a = 0xFFFFFFF7;
   unsigned char i = (unsigned char)a;
   char* b = (char*)&a;
   printf("%08x,%08x\n",i,*b);
}

/*
在Win32下 char, int, float, double各占多少位?
(1) Char   占用8位
(2) Int     占用32位
(3) Float   占用32位
(4) Double 占用64位
unsigned int 变量赋值给 unsigned char变量时会发生字节截断(3位和高于3位的将被程序自动丢弃)。
那么第二个数,也就是char* b = (char*)&a 本身为一个unsigned int的值,把它的地址赋给一个执行char类型数据的指针。char类型的长度只有一个字节,打印char类型的指针指向的值会是多少?
&a 的结果是一个指针,它的类型取决于a的类型,此处&a的类型应该是: int *;
char *b = (char *)&a;
上面等价与:
unsigned int *p = &a;//p中的内容是a的地址,即p指向a
char *b = (char *)p; //此处的强制转换只是使b也指向a而已
上面的步骤就是将一个 unsigned int 型的指针强制转换成一个char型的指针。
所以请注意:这里是char类型的指针转换,而不是char类型的转换。
这样转换后,假设a的地址是x:
p+1 = x+1*sizeof(int) = x+1*4 = x+4;
b+1 = x+1*sizeof(char) = x+1*1 = x+1;
影响的是指针的寻址。 00000f7,ffffff7。
*/

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值