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

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

文章目录

9.11 结构体元素偏移

//int 占 2 个字节,char 占 1 个字节,float 占 4 个字节struct stu{
union{
char bj[5]; int bn[2]; }class;//5 char xm[8];//8 float cj;//4}xc;

问题:求sizeof(xc)?

我的答案:32

正确答案:20

分析:

无论结构体还是联合体,都讲究一个字节对齐,按照其内部最大元素内存大小对齐!!!

所以union中最大元素类型是int,这里是2字节,所以union按照2字节对齐,char bj[5]占了5字节,按照2字节对齐的时候再补一个字节,所以union的大小是6Byte;在struct中,class已经占了前6字节,char xm[8]中每一个char占1字节,所以char数组可以紧接着存放8个字节,现在内存大小为6+8=14字节,由于float需要4字节对齐,所以float从第16字节开始存储,占用4字节。至此struct内存大小占用20字节!

注意:结构体涉及数组的时候,我觉得可以把数组拆分开看作一个个元素,就好多了,只出现数组是不可以按照数组整体来内存对齐的.

结构体定义如下:

//int 占 2 个字节,char 占 1 个字节,float 占 4 个字节struct stu{
union{
char bj[5]; int bn[2]; }class;//5 char xm[8];//8 float cj;//4}xc;

问题:若xc地址为0X1000,求&xm[0]的值?

我的答案:0X1006

根据上面的内容,union大小为6Byte,所以相对于结构体的偏移地址是6,则紧挨着的xm[0]的地址就是0X1000+6=0X1006

为了提高 CPU 的存储速度,编译器会对一些变量的起始地址做了“对齐”处理。

对齐方式(变量存放的起始地址相对于结构的起始地址的偏移量)
char 偏移量必须为 sizeof(char) 即 1 的倍数
int 偏移量必须为 sizeof(int) 即 4 的倍数 (跟编译器有关,有可能是 2)
float 偏移量必须为 sizeof(float) 即 4 的倍数
double 偏移量必须为 sizeof(double) 即 8 的倍数
short 偏移量必须为 sizeof(short) 即 2 的倍数

9.12 指针、数组的声明

题目:

用变量a给出下面的定义

1、一个整型数(An integer)

2、一个指向整型数的指针( A pointer to an integer)

3、一个指向指针的的指针,它指向的指针是指向一个整数( A pointer to a pointer to an intege)

4、一个有10个整型数的数组( An array of 10 integers)

5、一个有10个指针的数组,该指针是指向一个整型数的。(An array of 10 pointers to integers)

6、 一个指向有10个整型数数组的指针( A pointer to an array of 10 integers)

7、 一个指向函数的指针,该函数有一个整型参数并返回一个整型数(A pointer to a function that takes an integer as an argument and returns an integer)

8、一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数( An array of ten pointers to functions that take an integer argument and return an integer

答案:

1:int a

2:int *a

3:int **a

4:int a[10]

5:int* a[10]

6:int (*a)[10]

7:int (*a)(int)

8:int (*a[10])(int)

[]的优先级比*要高,所以可以根据题中的要求来判断[]*的先后执行顺序。

比如5题:一个10个指针的数组,指针指向整型数;首先是一个10个元素的数组,所以首先a[10],然后指定数组元素是指针指向整型,所以声明元素为int *

再比如6题:一个指针,指向有10个整型数的数组;首先是一个指针,所以先声明指针,即*a,然后指针的指向是一个10个元素的整型数组,所以就成了int (*a)[10]

当涉及到函数的时候,分为三部分:函数返回值类型、指向函数的类型、函数的参数类型。指向函数的格式就是加上一个括号,代表函数体。

所以7题分析为:返回值和参数都是整型数,所以int () (int)确定了两部分,然后是指向函数的指针,所以就有了int (*a)(int)

同理8题:返回值和参数都是整型,指向函数的是一个10个元素数组,数组的元素指向函数,所以就有int (*a[10])(int)

9.13 负数的求余运算

运行下列语句,求出x的值:

int x=10;x += 3+x%(-3);//x=x+3+x%(-3)=13+

答案:14

分析:

x += 3+x%(-3)中,+=运算比较好判断,主要是x%(-3)的判断不知道是1还是-1,在求余运算中,余数的符号与被除数的符号相同,所以在这里x=10,则得数就是1,即x += 3+1易得x的值为14.

9.14 阅读代码

阅读下列代码,分析该代码的功能:

char *func(char *dest, const char *src, int count)    {
char *tmp = dest; while (count) {
if ((*tmp = *src) != 0) src++; tmp++; count--; } return dest; }

分析:

先看参数和返回值,参数中第二个参数是const修饰的(指向的地址不可改变),所以第二个参数位置的字符串肯定是不能改变的,然后返回值也是一个char类型的指针,初步推断可能是一个字符串操作类的函数。

然后往函数内部分析,先创建了一个字符指针,指向传进来的dest

在while中根据count的大小进行遍历

if ((*tmp = *src) != 0)中,先是将*tep = *src*然后判断*tmp是否为空,相当于字符拷贝,然后自增、coun自减

可以看出此函数就是拷贝字符串的函数。

实际上strncpy的源码如下:

/*    * strncpy - Copy a length-limited, %NUL-terminated string    * @dest: Where to copy the string to    * @src: Where to copy the string from    * @count: The maximum number of bytes to copy    *    * The result is not %NUL-terminated if the source exceeds    * @count bytes.    *    * In the case where the length of @src is less than that of    * count, the remainder of @dest will be padded with %NUL.    */   char *strncpy(char *dest, const char *src, size_t count)    //从 src 复制count个字符 到 dest {
char *tmp = dest; while (count) {
if ((*tmp = *src) != 0) //把 src 的值 复制到 dest ,如果 src 的值 非空,那么指针自加。 //否则 指针不加,src 后续都是指向 0 ,即字符串结束,后续的 dest值都为 0 src++; tmp++; // dest 的指针 自加 count--; //最大计数值 减 1 } return dest; c}

9.15 逗号表达式细节

求如下程序的输出:

int a[3][2] = {
(0,1),(2,3),(4,5)};int *p = a[0];printf("%d",p[0]);

答案:1

分析:

这里分析一下程序,p指针指向a[0],也就是指向二维数组的首地址,所以p[0]的值就是二维数组的第一个值。

再看一下二维数组的定义:int a[3][2]={(0,1),(2,3),(4,5)},这里要注意,这里的初始化不是分段赋值,正常的分段赋值应该是这样:int a[3][2]={

{0,1},{2,3},{4,5}},这里是逗号分隔的,所以是逗号表达式,实际的是连续赋值:int a[3][2]={1,3,5},所以p[0]=1.

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

你可能感兴趣的文章
通过限制循环次数来避免死循环
查看>>
ADO连接字符串
查看>>
字符数组的位置决定程序能否成功执行--不明白
查看>>
拷贝代码时没有仔细检查,导致误修改了函数参数
查看>>
MySQL批量导入数据SQL语句(CSV数据文件格式)
查看>>
ADO连接Oracle
查看>>
遍历Windows系统中所有进程的名字(*.exe)
查看>>
进程看门狗
查看>>
线程看门狗
查看>>
调试代码的宏定义
查看>>
创建、重命名文件
查看>>
文件大小保护
查看>>
删除指定目录下所有文件及目录
查看>>
XDR-从文件空间解码整数
查看>>
XDR-.x文件的简单使用
查看>>
XDR-枚举的试用
查看>>
使用CppSQLite3访问SQLite数据库
查看>>
第一个boost程序---timer的使用
查看>>
使用boost asio库实现字节数可控的CS通信
查看>>
linux下串口编程
查看>>