You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
#define N 16
typedef int fix_matrix[N][N]
int fix_prod_ele(fix_matrix A, fix_matrix B, long i, long k) {
long j;
int result = 0;
for (j = 0; j< N; j++) {
result += A[i][j] * B[j][k];
}
return result;
}
int fix_prod_ele_opt(fix_matrix A, fix_matrix B, long i, long k ) {
int *Aptr = &A[i][0];
int *Bptr = &B[0][k];
int *Bend = &B[N][k];
int result = 0;
do {
result += *Aptr * *Bptr;
Aptr ++;
Bptr += N;
} while (Bptr != Bend);
return result;
}ypedef int fix_matrix[N][N]
int var_ele(long n, int A[n][n], long i, long j) {
return A[i][j];
}
var_ele:
imulq %rdx , %rdi
leaq (%rsi, %rdi, 4), %rax
movl (%rax, %rcx, 4), %eax
ret
数组分配与访问
C语言的素组是一个将标量数据聚集成更大数据类型的方式,C语言实现数组的方式非常简单.因此
很容易翻译为机器代码,C语言的一个不同寻常的特点是可以产生指向数组中元素的指针,并对
这些指针进行运算,在机器代码中,这些指针会被翻译成地址来计算.优化编译器非常善于简化
数组索引所使用的地址计算,不过这是C代码和它到机器代码的翻译之间的对应关系有些难以理解
C语言指针不表达长度....首元素的地址就是数组.
基本原则
对于数据类型T和整形常熟N,声明如下:
T A[N];
指针运算
嵌套的数组
定长数组
C语言编译器能够定长多维数组上的操作代码,这里我们展示优化等级设置为-01时GCC采用的一些优化。假设
我们用如下方式将数据类型fix_matrix声明位16*16的整型数组:
变长数组
历史上如果要申请边长数组,必须使用malloc或者calloc这样的函数为这些数组分配存储空间。而且不得不显示的编码。不过现在可以在分配时候
才计算出数组长度,比如
异质的数据结构
C语言提供了两种不同类型的对象组合到一起创建数据类型的机制:
结构
C语言的struct声明创建了一个数据类型,将可能不同类型的对象聚合到一个对象中。用名字来引用结构的各个组成部分。类似于数组的实现。结构的所有组成部分都存放在内存的一段连续的区域。而指向结构的指针就是结构第一个字节的地址。编译器维护关于每个结构类型的信息。指示每个字段的字节编译。它以这些偏移作为内存引用指令的位移。从而才生对结构元素的引用
联合
联合提供了一种方式,能够规避C语言的类型系统,允许多种类型来用一个对象。联合声明的语法和结构的语法是一样的,只不过语义相差比较大,它们用不同的字段来引用相同的内存块
联合用于表示互斥的结构,联合内存的大小是联合内最大的大小。用来表示一些
明显互斥的机构。
集合控制与数据
指针
指针是C语言的一个核心特色,它们以一种同意方式,对不同数据结构中的元素产生了引用。指针有一些
基本概念其实非常简单。再次,我们重点介绍一些指针和它们映射到机器代码的关键原则
变量IP[是一个指向int类型的指针,而CPP指针是指向指针指向的对象本身就是一个指向char类型的指针。通常,
如果对象类型为T,那么指针的类型为T*, 特殊的void *类型表示通用指针,比如说malloc函数返回一个通用指针,
然后通过强制类型转换或者赋值操作那样隐式强制类型转换。指针类型不是机器代码中的一部分,它们是一个C怨言
提供的一种抽象,帮助程序是避免寻址错误
的表达式,这样的例子包括变量一级结构,联合和数组的元素。我们已经看到因为leaq指令是设计用来计算内存引用
的地址,&运算符的机器代码实现常用的这条指令计算表达式的值
是存储到一个指定的地址,要么是从指定的地址读取。
数组引用和指针运算都需要用对象大小对偏移量进行伸缩。当我们写表达式p + i.这里的指针P的值是p.得到的地址计算为P + l * I
例如,如果P是要给char *类型的指针。它的值为P。
用下面的原型定义
然后我们可以声明要给指针fp, 将它赋值为这个函数,代码如下
然后用这个指针来调用这函数;
The text was updated successfully, but these errors were encountered: