1.int a[3][4] = { {1,2},{0},{4,6,8,10}};
a[1,2]=?
a[2,1]=?
答案: (数组自动补 0 )
a[1][2]=0;
a[2][1]=6;
代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int a[3][4] = { {1,2},{0},{4,6,8,10}};
cout<<"a[1][2] = "<<a[1][2]<<endl;
cout<<"a[2][1] = "<<a[2][1]<<endl;
}
2. int k=2;
int m=4;
int n=6;
int *pk=&k;
int *pm=&m;
int *p;
*(p=&n) = *pk*(*pm);
n=?
答案:
n=8;
代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int k=2;
int m=4;
int n=6;
int *pk=&k;
int *pm=&m;
int *p;
//*p = pk * pm = 2* 4 =8
*(p=&n) = *pk * (*pm);
//*(p= &n) 等于 *p = &n;
// *pk * (*pm) 等于 m * n
//注意之间的间隔少, 不要看错了!
cout<<"n= "<<n<<endl;
}
3.int *var;
int b;
var=&b;
b=100;
b=*var+10;
*var= ?
答案:
* var=110
代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int *var;
int b;
var=&b;
b=100;
b=*var+10;//指针应用
cout<<"*var = "<<*var<<endl;
}
4.int a[5] ,*p=a 正确使用
选项:
1. *(p+5 ) //错的 数组超标
2. * (a+2) //对的
3. *&a[5 ] // 数组超标
5. int a[5] , *p =5 , 对指针的 正确引用
1. &a+1 // 错的 &(a +1)
2. &a[0] // 对的
3. p+5 //错的 数组超标
4. *a+1 // 指针的引用 这是 *a =1 *a+1=2
6.int a[4][[6] --->4行 6列 正确的表示 a[i][j] 的地址表达
1. & a[0][0] + 4* i + j ; // 错的 这个是把二维数组看成一维数组, 4*i + j 这个是 x 行 4 列的 应用
2. & a[0][0] + 6* j + i ; //错的 这个是 j, i 的位置错误, 主要是因为 不能看成数组
3. & a[0][0] + 6*i + j; // 对的
4. & a[0][0] + 4*j + i; // 错的 不能形成 数组
7.int i=-2 以十六进制数的形式结构 表达 i 在 内存的存储形式
原码: i= 1 0010
反码: i= 1 1101
补码: i= 1 1110
知识自己查询!!!
8.volatile 与 static 的区别 c与 c++ 的区别
c:
volatile int i=10; int a = i; ... //其他代码,并未明确告诉编译器,对i进行过操作 int b = i;
volatile 指出 i是随时可能发生变化的,每次使用它的时候必须从i的地址中读取,因而编译器生成的汇编代码会重新从i的地址读取数据放在b中。而优化做法是,由于编译器发现两次从i读数据的代码之间的代码没有对i进行过操作,它会自动把上次读的数据放在b中。而不是重新从i里面读。这样以来,如果i是一个寄存器变量或者表示一个端口数据就容易出错,所以说volatile可以保证对特殊地址的稳定访问。
static:
1. 局部变量
普通局部变量是再熟悉不过的变量了,在任何一个函数内部定义的变量(不加static修饰符)都属于这个范畴。编译器一般不对普通局部变量进行初始化,也就是说它的值在初始时是不确定的,除非对其显式赋值。
普通局部变量存储于进程栈空间,使用完毕会立即释放。
静态局部变量使用static修饰符定义,即使在声明时未赋初值,编译器也会把它初始化为0。且静态局部变量存储于进程的全局数据区,即使函数返回,它的值也会保持不变。
变量在全局数据区分配内存空间;编译器自动对其初始化
其作用域为局部作用域,当定义它的函数结束时,其作用域随之结束
全局变量
全局变量定义在函数体外部,在全局数据区分配存储空间,且编译器会自动对其初始化。
普通全局变量对整个工程可见,其他文件可以使用extern外部声明后直接使用。也就是说其他文件不能再定义一个与其相同名字的变量了(否则编译器会认为它们是同一个变量)。
静态全局变量仅对当前文件可见,其他文件不可访问,其他文件可以定义与其同名的变量,两者互不影响。
在定义不需要与其他文件共享的全局变量时,加上static关键字能够有效地降低程序模块之间的耦合,避免不同文件同名变量的冲突,且不会误使用。
函数
函数的使用方式与全局变量类似,在函数的返回类型前加上static,就是静态函数。其特性如下:
静态函数只能在声明它的文件中可见,其他文件不能引用该函数
不同的文件可以使用相同名字的静态函数,互不影响
c++:
volatile.,声明这个字段易变(可能被多个线程使用),Java内存模型负责各个线程的工作区与主存区的该字段的值保持同步,即一致性。
static,声明这个字段是静态的(可能被多个实例共享),在主存区上该类的所有实例的该字段为同一个变量,即唯一性。
volatile,声明变量值的—致性;
static,声明变量的唯—性。
此外,volatile同步机制不同于synchronized,前者是内存同步,后者不仅包含内存同步(一致性),且保证线程互斥(互斥性)。
staic只是声明变量在主存上的唯一性,不能保证工作区与主存区变量值的一致性;除非变量的值是不可变的,即再加上final的修饰符,否则static声明的变量,不是线程安全的。
9.
struct INFO
{
int a;
char c[6];
float f;
double d;
} ;
一个INFO 的变量的 内存大小
内存大小: 24
代码:
#include<bits/stdc++.h>
using namespace std;
struct INFO
{
int a;
char c[6];
float f;
double d;
};
int main()
{
INFO a;
cout<<"内存大小: "<<sizeof(a)<<endl;
}
我的理解
首先 定义一个结构体 : 他在数据区的内存分配 的图形是一个 矩形 ,
struct INFO
{
int a;
char c[6]; //这里可以 看成 6 个 char
float f;
double d;
};
就这个结构体来说 :
1.开始的地方 : sizeof(int ) = 4 ;
2.数据开辟 一个 一行 4 列 的数据区域 存储 int a
3.第二个来了一个 sizeof( char c[6] ) = 6 ;
4.这个时候 数据开辟 了 一个 1 行 6列 的数据区域 ,但是 因为结构的数据区域要在一起, 那么,就要合并, 1 行4 列 和1行 6 列 合并 , 变成啥, 2行 6 列 因为数据区域 要是 矩形,
5.第三个数据来了 sizeof( float ) = 4;
6. 这时候系统 发现之前的 数据区域,有空余的空间 (等于 2 ) , 看是否能挤一挤 ,发现区域小了,挤不进去,只好 再开辟一个 1行 6 列的空间 与 之前的 2 行 6 列的空间 合并成为 3行 6列。
7.第四个数据来了 sizeof( double ) =8
8.系统看他比之前的数据 都大 直接开辟 一个 1行8列的数据空间存储它,, 之后与之前的是数据区域合并, 1行 8列, 与 3行 6 列 , 变成一个矩形 ,, --》 4行8列。
9.这时候,系统又看 内存空得太多了,可以挤一挤吗 ?
一下 int 4 与 float 4 挤到一行去了 。变成了 3行 8 列
内存大小 = 3 *8 =24;
其他的案列:
自己补充知识点
10.ARM 程序编译后的 可执行代码 分为哪几个阶段 ,作用
答:
text段是代码段。它用来放程序代码(code)。它通常是只读的。
.data段是数据段。它用来存放初始化了的(initailized)全局变量(global)和初始化了的静态变量(static)。它是可读可写的。
.bss段是全局变量数据段。它用来存放未初始化的(uninitailized)全局变量(global)和未初始化的静态变量(static)。它也是可读可写的。bss是英文Block Started by Symbol的缩写。之所以把bss跟data分开来,是因为系统会为这些bss段的变量的初值清零。
.rodata段是常量数据段。它用来存放常量(const)。它也是只读的。
在ARM的集成开发环境中,
1、只读的代码段称为Code段,即上述的.text段。
2、只读的常量数据段,被称作RO Data段,即上述的.constdata段。
以上两个段统称为RO段(Read Only),放在ROM或FLASH等非易失性器件中。
3、可读可写的初始化了的全局变量和静态变量段,被称作RW Data段(ReadWrite),即上述的.data段。
4、可读可写的未初始化的全局变量和静态变量段,被称作ZI Data段(Zero Init),即上述的.bss段。因为这个段里的变量要被初始化为零,所以叫ZI段。
三个段
1.RO
2.RW
3.ZI
11.已知函数模型 int fun(int a,float b)
声明一个函数指针
int (*p)(int a, float b);
12..使用宏定义 写一个 返回最大的函数 ,
#define max_1(a,b) (((a)>(b))?(a):(b))
代码:
#include<bits/stdc++.h>
using namespace std;
#define max_1(a,b) (((a)>(b))?(a):(b))
int main()
{
int a=max_1(1,2);
cout<<a<<endl;
}
程序题目:
1. 1.完成下面函数,对一个传入数组进行由小到大排序,传入参数为数组首地址和数组长度
void Sort(int*pArray, int nLen);
#include<bits/stdc++.h>
using namespace std;
void Sort(int* pArray, int nLen)//pArray 是数组, nlen是数组长度
{
for(int i=0;i<nLen;i++)
{
for(int j=i+1;j<nLen;j++)
{
if(pArray[i]>pArray[j])
{
int a=pArray[i];
pArray[i]=pArray[j];
pArray[j]=a;
}
}
}
}
int main()
{
int num[]={2,1,5,6,4,8,9};
Sort(num,7);
for(int i=0;i<7;i++)
{
cout<<num[i]<<" ";
}
}
2.一个结构体 两个小题
某数据管理软件中采用链表来维护员工的信息,链表节点结构体类型声明如下所示,假定该链表已经存在,且已经按照员工工号从小到大排列各节点,其中链表首节点并不存储任何信息,只是用于占位以简化链表操作。要求实现下两个链表操作函数(C或C++):
typedef struct _WorkerInfo
char Name[20];/*员工姓名*/
unsigned int ID;/*员工工号,在整个链表中工号不会重复*/struct _Workerlnfo*pNext;
}WorkerInfo;
2.1 1)编写一个函数添加新的员工信息,即通过传入链表首节点地址、新员工的姓名和F
工号信息,动态生成一个节点插入到当前链表合适位置,成功返回0,出错返回-1,
函数原型声明如下:
int InsertNewNode(WorkerInfo *pListHead, const char*Name, unsigned int lD);
2.22)编写一个函数删除某员工信息,即通过入链表首节点地址和传入该员
工的工号,在链表中搜索相应节点,并予以删除,成功返回o,出错返回-1,函数原型声明如下
int DeleteNode(WorkerInfo *pListHead, unsigned int lD);
提示:可以用malloc和free函数进行动态内存分配和回收,亦可使用new和delete
代码:
#include<bits/stdc++.h>
using namespace std;
struct WorkerInfo
{
char Name[20];/*员工姓名*/
unsigned int ID;/*员工工号,在整个链表中工号不会重复*/
struct WorkerInfo *pNext;//指针
};
//函数功能: 添加工人到链表合适的位置 ID 不会重复 所以按照 ID 排序
int InsertNewNode(WorkerInfo *pListHead, const char*Name, unsigned int ID)//pListHead 头节点 name 工人的名字 ID 工人的ID
{
if(pListHead==NULL)
{
return 0;
}
WorkerInfo * pp =pListHead;
WorkerInfo * kk= (WorkerInfo*)malloc(sizeof(WorkerInfo));
strcpy(kk->Name,Name);
kk->ID=ID;
while(pp!=NULL)
{
if(pp->pNext!=NULL)
{
if(pp->pNext->ID > ID)
{
kk->pNext=pp->pNext;
pp->pNext=kk;
return 1;
}
}
pp=pp->pNext;
}
pp=pListHead;//
while(pp->pNext!=NULL) ///找到最后一个单位
{
pp=pp->pNext;
}
kk->pNext=pp->pNext;
pp->pNext=kk;
return 1;
}
//程序功能: 删除工人的信息
int DeleteNode(WorkerInfo *pListHead, unsigned int ID)//pListHead 头节点 ID 工人的ID
{
WorkerInfo * kk =pListHead; //方便删除
WorkerInfo * pp =pListHead;
while(pp!=NULL)
{
if(pp->ID==ID)
{
kk->pNext=pp->pNext;
delete pp;
return 1;
}
else
{
kk=pp;
pp=pp->pNext;
}
}
return 0;//没有这个人
}
//程序功能 打印链表信息
void print(WorkerInfo *pListHead)
{
WorkerInfo *pp=pListHead;
while(pp!=NULL)
{
cout<<pp->Name<<" "<<pp->ID<<endl;
pp=pp->pNext;
}
}
int main()
{
WorkerInfo * head=(WorkerInfo* )malloc(sizeof(WorkerInfo));
head->pNext=NULL;
head->ID=0;
strcpy(head->Name,"0000");
cout<<"第1次打印链表 : "<<endl;
print(head);
InsertNewNode(head,"11111",1);
cout<<"第2次打印链表 : "<<endl;
print(head);
InsertNewNode(head,"3333",3);
InsertNewNode(head,"2222",2);
DeleteNode(head,2);
cout<<"第3次打印链表 : "<<endl;
print(head);
}