Summer 9

1.下面程序的输出结果为多少(32为机器上)

void Func(char str_arg[2])
{
	int m = sizeof(str_arg);
	int n = strlen(str_arg);
	printf("%d\n", m);//4
	printf("%d\n", n);//5
}

int main(void)
{
	char str[] = "Hello";
	Func(str);
	system("pause");
	return 0;
}

sizeof和strlen()都可以用来统计字符串所占用的大小,二者的区别为:

  1. sizeof是运算符,而strlen是函数;
  2. strlen必须以char *作为参数,且必须以'\0'结尾;而sizeof()可以用于其他类型;
  3. strlen统计字符串中字符的长度,不包括结尾的'\0';
  4. 数组做sizeof的参数不退化,而传递给strlen就变为指针

sizeof(str):占用的字节为5 + 1 = 6,其中1为末尾的'\0';

strlen(str):5

当数组作为函数的参数时,其自动转换为指向函数的指针,sizeof(str_arg)表示的是指针的长度,在32为计算机上为4位。

Func(str):传递的是指针,大小为4

2. 1<<3+2 的值是  32

+的优先级高于<< 

所以是1<<5    左移位5位,00001------>10000,也就是2^5=32,左移在不溢出的情况下相当于乘以2

优先级记忆方法如下:    
    记住一个最高的:构造类型的元素或成员以及小括号。    
    记住一个最低的:逗号运算符。    
    剩余的是一、二、三、赋值。    
    意思是单目、双目、三目和赋值运算符。    
    在诸多运算符中,又分为:    
    算术、关系、逻辑。    
    两种位操作运算符中,移位运算符在算术运算符后边,逻辑位运算符在逻辑运算符的前面。再细分如下:    
    算术运算符分     *,/,%高于+,-。    
    关系运算符中,〉,〉=,<,<=高于==,!=。    
    逻辑运算符中,除了逻辑求反(!)是单目外,逻辑与(&&)高于逻辑或(||)。    
    逻辑位运算符中,除了逻辑按位求反(~)外,按位与(&)高于按位半加(^),高于按位或(|)。    
    这样就将15种优先级都记住了,再将记忆方法总结如下:    
    去掉一个最高的,去掉一个最低的,剩下的是一、二、三、赋值。双目运算符中,顺序为算术、关系和逻辑,移位和逻辑位插入其中。

3. 在小端序的机器中,如果

union X
{
	int x;
	char y[4];
}a;

int main()
{
	a.x = 0X11223344;
	printf("%x\n", a.y[0]);//44
	printf("%x\n", a.y[1]);//33
	printf("%x\n", a.y[2]);//22
	printf("%x\n", a.y[3]);//11
	system("pause");
	return 0;
}

大端模式(Big_endian):字数据的高字节存储在低地址中,而字数据的低字节则存放在高地址中。

小端模式(Little_endian):字数据的高字节存储在高地址中,而字数据的低字节则存放在低地址中。

一个很好的记忆方法 大序端按照顺序写 小序端倒序写

union 型数据所占的空间等于其最大的成员所占的空间。对union型的成员的存取都是相对于该联合体基地址的偏移量为0 处开始,也就是联合体的访问不论对哪个变量的存取都是从union 的首地址位置开始。
union 维护足够的空间来置放多个数据成员中的“一种”,而不是为每一个数据成员配置空间,在union 中所有的数据成员共用一个空间,同一时间只能储存其中一个数据成员,所有的数据成员具有相同的起始地址。例子如下:
union StateMachine
{
   char character;
   int number;
   char *str;
   double exp;
};
一个union 只配置一个足够大的空间以来容纳最大长度的数据成员,以上例而言,最大长度是double 型态,所以StateMachine 的空间大小就是double 数据类型的大小。

4.阅读如下代码,请问:p和“hello ,world”存储在内存 栈,只读存储区

const char *p="hello,world";

局部变量存放在栈中,堆中存放的是new和malloc开辟出的,而程序中定义的常量存放在只读存储区

局部变量:栈

全局变量,static变量:全局静态区域

动态变量:堆

局栈动堆

5. 空指针是指 所指向的空间位置就是地址0的指针

我们判断空指针用 if(ptr==NULL) 来判断 ,  而NULL在宏定义中定义为0  ,所以判断空指针就是判断地址是否为0

空指针:在VS里是为NULL的指针,在C/C++中,NULL=0

A.未存放任何数据的指针,说法没有所指向的空间位置就是地址0的指针完善,事实上,指向的地方可以是一个地址,只是那个地址不一定有数据

B.所指向的空间位置存放着数据0的指针肯定错,int a = 0, int *b = &a

C.所指向的空间位置可用于存放任何类型数据的指针 void *也是指针,且可以强制类型转换,指针的大小与机器字长有关.

6.如下代码结果是 a=2,x=1

int main()
{
	int a, x;
	for (a = 0, x = 0; a <= 1 && !x++; a++)
	{
		a++;
	}
	printf("%d %d", a, x);// 2 1
	system("pause");
	return 0;
}

此题关键在于第二个判断条件: !x++。!与后置++同时出现时,后置++优先级高于!,所以!x++相当于!(x++),但是后置自增运算符是等语句执行完成之后再自增。

7.写一个宏,输入两个参数,返回较小的一个:#define Min(X,Y) ((X)>=(Y)?(Y):(X))//结尾没有';'

8. 下面程序输出结果为 5 ,2000000,3

int main()
{
	int a[5] = { 1, 2, 3, 4, 5 };
	int *p1 = (int*)(&a + 1);//&(a+1)指的是下一个数组的首地址,也就是下一行首地址
	int *p2 = (int*)((int)a + 1);
	int *p3 = (int*)(a + 1);
	printf("%d ,%x,%d\n", p1[-1], p2[0], p3[1]);//5 ,2000000,3
	system("pause");
	return 0;
}

&a + 1: 取数组a 的首地址,该地址的值加上sizeof(a) 的值,即&a + 5*sizeof(int),也就是下一个数组的首地址,显然当前指针已经越过了数组的界限。
(int *)(&a+1): 则是把上一步计算出来的地址,强制转换为int * 类型。
*(a+1): a,&a 的值是一样的,但意思不一样,a 是数组首元素的首地址,也就是a[0]的首地址,a+1 是数组下一元素的首地址,即a[1]的首地址。&a 是数组的首地址,,&a+1 是下一个数组的首地址。

a+1 就是指针向后偏移一个元素,指向2,p3[1]~*(p3+1),即就是3.

(int)a,已经把a的地址强转成int型数字(32bit),所以“((int)a+1); ”实际指向了整个数组内存块的第二个地址。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值