博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
每日一题(九)
阅读量:3950 次
发布时间:2019-05-24

本文共 1970 字,大约阅读时间需要 6 分钟。

文章目录

10.6 判断程序输出

判断如下程序输出:

int sum(int a){
auto int c = 0; static int b = 3; c += 1; b += 2; return (a + b + c);}int main(){
int i; int a = 2; for (i = 0; i < 5; i++) {
printf("%d\n", sum(a)); }}

程序会调用五次sum函数,每次传入的参数都是a=2

对于函数宿命来说,返回a+b+c,其中a来自参数(不变);c来自函数内的局部变量,每次进入函数的时候重新申请,所以也是不变;b是static修饰的,相当于全局变量,所以sum的返回值是:2+1+(b+2)其中b的值每次改变都保留

所以经过五次循环sum,得到结果为:

8

10

12

14

16

10.7 指针移动

判断如下伪代码输出:

int a[3] = {
0, 1, 2};int *p, *q;p = a;q = &a[2];printf("%d\n", a[q - p]);

答案:2

也就是a[q - p] = a[2]

a是一个int型数组,p、q是int型指针,p指向数组的首地址,q指向数组第三个元素的地址。

如果按照字节大小计算的话,p、q指针相差2*4个字节,如果这样的话,q-p的值就为8

但是指针直接的计算以指针所指的数据类型来衡量,即q - p的值为2,所以a[q - p] = a[2]

10.8 带符号的位域

写出下列代码的输出:

typedef struct{
int a : 2;int b : 2;int c : 1;}test;test t;t.a = 1;t.b = 3;t.c = 1;printf("%d", t.a);printf("%d", t.b);printf("%d", t.c);

输出为:1 -1 -1

虽然位域的大小只有一两个位,但是数据类型是int型,必须考虑符号位的存在,所以也将符号位计算在内。

计算机中以补码的方式存储数据

10.9 涉及strcpy的程序分析

分析如下代码,找出不妥的地方:

void test(void){
char string[10], str[10]; int i; for (i = 0; i < 10; i++) {
str[i] = 'a'; } strcpy(string, str);}

首先,str数组内所有的成员都是‘a’,结尾没有结束符‘\0’,所以str当作字符串的时候不能够结束,当str数组作为strcpy的参数的时候,是不确定复制到string的元素个数的,也就是说从str复制到string的字节数具有不确定性。要知道strcpy的工作原理就是遇到字符串结束符‘\0’作为标志,这里的str没有结束符,那到时候复制到string中的后续内容就不确定了。

正确的程序应该修改为如下:

void test(void){
char string[10], str[10]; int i; for (i = 0; i < 9; i++) {
str[i] = 'a'; } str[9] = '\0'; //加上结束符!!! strcpy(string, str); }

10.10 运算符优先级问题(一)

分析如下程序输出:

int arr[] = {
6, 7, 8, 9, 10};int *ptr = arr;*(ptr++) += 123;printf(" %d %d ", *ptr, *(++ptr));

程序的重点在于第三行和第四行代码:

第三行代码:*(ptr++) += 123要明白运算符的优先级,这里涉及到的运算符有:()、*、++、+= 。

他们的优先级为:() > ++ > * > += 。所以先执行()里面的++运算,即ptr++,意为当前指令执行完毕之后ptr指向下一个地址;然后是取值符号*,取当前ptr指向的值—arr[0],即6;然后是+=运算,相当于arr[0] += 123,这个运算使得arr[0] = 129;最后ptr指向arr[1],即 *ptr = 7

第四行代码:考察的是printf函数的入栈顺序,一般是从右向左,所以先执行* (++ptr),再执行*ptr,所以右边的相当于arr[2],左边的相当于arr[2]。

即输出: 8 8

转载地址:http://utwzi.baihongyu.com/

你可能感兴趣的文章
Android开发——ListView局部刷新的实现
查看>>
Java技术——Java中的参数传值方式
查看>>
Android开发——本地验证码的简易实现
查看>>
Java技术——CopyOnWriteArrayList源码解析
查看>>
Java技术——ReentrantLock的Condition的作用以及使用
查看>>
数据结构——搜索树树、B-树、B+树
查看>>
Android开发——带你彻底理解 Window 和 WindowManager
查看>>
设计模式——责任链模式详解
查看>>
设计模式——适配器模式详解
查看>>
设计模式——装饰模式详解
查看>>
Android开发——关于RxJava的知识总结
查看>>
Android开发——View的生命周期总结
查看>>
Android开发——Protocol Buffer的使用(比XML、Json快很多)
查看>>
Android开发——Android系统启动以及App启动过程
查看>>
Android开发——简述RxJava框架的实现原理
查看>>
Android开发——今日头条APK瘦身之路
查看>>
Android开发——使用ActivityLifecycleCallbacks监控App是否处于后台
查看>>
Android开发——Protocol Buffer效率之高的原理介绍
查看>>
Android开发——贝塞尔曲线解析
查看>>
Android开发——微信Android架构历史
查看>>