当前位置: 首页 > news >正文

抓取网站源码怎么做镜像开网上授课的网站应该怎么做

抓取网站源码怎么做镜像,开网上授课的网站应该怎么做,自己建设的网站打开慢,diy定制软件文章目录 第12章 指针和数组12.1 指针的算术运算12.1.1 指针加上整数12.1.2 指针减去整数12.1.3 两个指针相减12.1.4 指针比较12.1.5 指向复合字面量的指针(C99) 12.2 指针用于数组处理12.2.1 *运算符和运算符的组合 12.3 用数组名作为指针12.3.1 数组型实际参数(改进版)12.3.2… 文章目录 第12章 指针和数组12.1 指针的算术运算12.1.1 指针加上整数12.1.2 指针减去整数12.1.3 两个指针相减12.1.4 指针比较12.1.5 指向复合字面量的指针(C99) 12.2 指针用于数组处理12.2.1 *运算符和运算符的组合 12.3 用数组名作为指针12.3.1 数组型实际参数(改进版)12.3.2 用指针作为数组名 12.4 指针和多维数组12.4.1 处理多维数组的元素12.4.2 处理多维数组的行12.4.3 处理多维数组的列12.4.4 用多维数组名作为指针 12.5 C99中的指针和变长数组问与答写在最后 第12章 指针和数组 第11章介绍了指针并且说明了如何把指针用作函数的实际参数和函数的返回值。本章介绍指针的另一种应用。当指针指向数组元素时C语言允许对指针进行算术运算加法和减法通过这种运算我们可以用指针代替数组下标对数组进行处理。 正如本章将介绍的那样C语言中指针和数组的关系是非常紧密的。后面的第13章字符串和第17章指针的高级应用将利用这种关系。理解指针和数组之间的关系对于熟练掌握C语言非常关键它能使我们深入了解C语言的设计过程并且能够帮助我们理解现有的程序。然而需要知道的是用指针处理数组的主要原因是效率但是这里的效率提升已经不再像当初那么重要了这主要归功于编译器的改进。 12.1节讨论指针的算术运算并且说明如何使用关系运算符和判等运算符进行指针的比较12.2节示范如何用指针处理数组元素12.3节揭示了一个关于数组的重要事实即可以用数组的名字作为指向数组中第一个元素的指针并且利用这个事实说明了数组型实际参数的真实工作机制12.4节讲解前3节的主题对于多维数组的应用最后的12.5节介绍指针和变长数组之间的关系C99的特性。 12.1 指针的算术运算 由11.5节可知指针可以指向数组元素。例如假设已经声明a和p如下 int a[10], *p;通过下列写法可以使p指向a[0]: p a[0];现在可以通过p访问a[0]。例如可以通过下列写法把值5存入a[0]中 *p 5;把指针p指向数组a的元素不是特别令人激动。但是通过在p上执行指针算术运算或者地址算术运算可以访问数组a的其他所有元素。C语言支持3种而且只有3种格式的指针算术运算 指针加上整数指针减去整数两个指针相减。 接下来仔细研究一下每种运算。下面的所有例子都假设有如下声明 int a[10], *p, *q, i;12.1.1 指针加上整数 指针p加上整数j产生指向特定元素的指针这个特定元素是p原先指向的元素后的j个位置。更确切地说如果p指向数组元素a[i]那么p j指向a[i j]当然前提是a[i j]必须存在。 下面的示例说明指针的加法运算: p a[2]; //p指向a数组的第3个元素q p 3; //q指向a数组的第6个元素p 6; //p指向a数组的第9个元素12.1.2 指针减去整数 如果p指向数组元素a[i]那么p - j指向a[i - j]。例如 p a[8]; //p指向a数组第9个元素q p - 3; //q指向a数组第6个元素p - 6; //p指向a数组第3个元素12.1.3 两个指针相减 当两个指针相减时结果为指针之间的距离用数组元素的个数来度量。因此如果p指向a[i]且q指向a[j]那么p - q就等于i - j。例如 p a[5]; q a[1];i p - q; /* i is 4 */ i q - p; /* i is -4 */ 请注意在一个不指向任何数组元素的指针上执行算术运算会导致未定义的行为。此外只有在两个指针指向同一个数组时把它们相减才有意义。 12.1.4 指针比较 可以用关系运算符、、和和判等运算符和!进行指针比较。只有在两个指针指向同一数组时用关系运算符进行的指针比较才有意义。比较的结果依赖于数组中两个元素的相对位置。例如在下面的赋值后p q的值是0而p q的值是1。 p a[5]; q a[1];12.1.5 指向复合字面量的指针(C99) 指针指向由复合字面量9.3节创建的数组中的某个元素是合法的。回顾一下复合字面量是C99的一个特性可以用于创建没有名称的数组。考虑下面的例子 int *p (int []){3, 0, 3, 4, 1}; p指向一个5元素数组的第一个元素这个数组包括5个整数3、0、3、4和1。使用复合字面量可以减少一些麻烦我们不再需要先声明一个数组变量然后用指针p指向数组的第一个元素 int a[] {3, 0, 3, 4, 1}; int *p a[0]; 12.2 指针用于数组处理 指针的算术运算允许通过对指针变量进行重复自增来访问数组的元素。下面这个对数组a中元素求和的程序片段说明了这种方法。在这个示例中指针变量p初始指向a[0]每次执行循环时对p进行自增。因此p先指向a[1]然后指向a[2]以此类推。在p指向数组a的最后一个元素后循环终止。 #define N 10 ... int a[N], sum, *p; ... sum 0; for (p a[0]; p a[N]; p) sum *p; for语句中的条件p a[N]值得特别说明一下。尽管元素a[N]不存在数组a的下标为0~N-1但是对它使用取地址运算符是合法的。因为循环不会尝试检查a[N]的值所以在上述方式下使用a[N]是非常安全的。执行循环体时p依次等于a[0], a[1], …, a[N-1]但是当p等于a[N]时循环终止。 当然改用下标可以很容易地写出不使用指针的循环。支持采用指针算术运算的最常见论调是这样做可以节省执行时间。但是这依赖于具体的实现——对有些编译器来说实际上依靠下标的循环会产生更好的代码。 12.2.1 *运算符和运算符的组合 C程序员经常在处理数组元素的语句中组合*间接寻址运算符和运算符。思考一个简单的例子把值存入一个数组元素中然后前进到下一个元素。利用数组下标可以这样写 a[i] j; 如果p指向数组元素那么相应的语句将是: *p j;因为后缀的优先级高于*所以编译器把上述语句看作: *(p) j;p的值是p。因为使用后缀所以p只有在表达式计算出来后才可以自增。因此*(p)的值将是*p即p当前指向的对象。 当然*p不是唯一合法的*和的组合。例如可以编写(*p)这个表达式返回p指向的对象然后对该对象进行自增p本身是不变化的。如果觉得困惑请看下面列举的表达式 表达式含义*p或*(p)自增前表达式的值是*p以后再自增p(*p)自增前表达式的值是*p以后再自增*p*p或*(p)先自增p自增后表达式的值是*p*p或(*p)先自增*p自增后表达式的值是*p 这4种组合都可以出现在程序中但有些组合比其他组合要常见得多。最频繁见到的就是*p或者*(p)它在循环中是很方便的。对数组a的元素求和时可以这样做 for (p a[0]; p a[N]; p) sum *p;//改写成p a[0]; while (p a[N]) sum *p;*运算符和--运算符的组合方法类似于*和的组合。 为了应用*和--的组合一起回到10.2节的栈的例子。原始版本的栈依靠名为top的整型变量来记录contents数组中“栈顶”的位置。现在用一个指针变量来替换top这个指针变量初始指向contents数组的第0个元素。 int *top_ptr contents[0];//下面是新的push函数和pop函数把更新其他栈函数留作练习void push(int i) { if (is_full()) stack_overflow(); else *top_ptr i; } int pop(void) { if (is_empty()) stack_underflow(); elsereturn *--top_ptr; }注意!!因为希望pop函数在取回top_ptr指向的值之前对top_ptr进行自减所以要写成*--top_ptr而不是*top_ptr--。 12.3 用数组名作为指针 指针的算术运算是数组和指针之间相互关联的一种方法但这不是两者之间唯一的联系。下面是另一种关键的关系可以用数组的名字作为指向数组第一个元素的指针。这种关系简化了指针的算术运算而且使数组和指针更加通用。 例如假设用如下形式声明a int a[10];用a作为指向数组第一个元素的指针可以修改a[0] *a 7; /* stores 7 in a[0] */ 可以通过指针a 1来修改a[1] *(a1) 12; /* store 12 in a[1] */通常情况下a i等同于a[i]两者都表示指向数组a中元素i的指针并且*(ai)等价于a[i]两者都表示元素i本身。换句话说可以把数组的取下标操作看作指针算术运算的一种形式。 数组名可以用作指针这一事实使得编写遍历数组的循环更加容易。思考下面这个来自12.2节的循环 for (p a[0]; p a[N]; p) sum *p;为了简化这个循环可以用a替换a[0]同时用a N替换a[N] for (p a; p a N; p) sum *p; 请注意虽然可以把数组名用作指针但是不能给数组名赋新的值。试图使数组名指向其他地方是错误的 while (*a ! 0) a; /* wrong */这一限制不会对我们造成什么损失。我们可以把a复制给一个指针变量然后改变该指针变量 p a; while (*p ! 0) p;8.1节的程序reverse.c读入10个数然后逆序输出这些数。程序读取数时会把这些数存入数组。一旦所有的数都读入了程序就会反向遍历数组并打印出这些数。 原来的程序利用下标来访问数组中的元素。下面是改进后的程序我们用指针的算术运算取代了数组的取下标操作。 /* reverse3.c --Reverses a series of numbers (pointer version) */ #include stdio.h #define N 10 int main(void) { int a[N], *p; printf(Enter %d numbers: , N); for (p a; p a N; p) scanf(%d, p); printf(In reverse order:); for (p a N - 1; p a; p--) printf( %d, *p); printf(\n); return 0; } 在原先的程序中整型变量i用来记录数组内的当前位置。新版程序用指针变量p替换了i。读入的数仍然存储在数组中只是换了一种方法来记录数组中的位置。 注意scanf函数的第二个实际参数是p不是p。因为p指向数组的元素所以它是满足scanf函数要求的参数而p则是指向“指向数组元素的指针”的指针。 12.3.1 数组型实际参数(改进版) 数组名在传递给函数时总是被视为指针。思考下面的函数这个函数会返回整型数组中最大的元素 int find_largest(int a[], int n) { int i, max; max a[0]; for (i 1; i n; i) if (a[i] max) max a[i]; return max; } 假设调用find_largest函数如下 largest find_largest(b, N); 这个调用会把指向数组b第一个元素的指针赋值给a数组本身并没有被复制。 把数组型形式参数看作指针会产生许多重要的结果。 在给函数传递普通变量时变量的值会被复制。任何对相应的形式参数的改变都不会影响到变量。反之因为没有对数组本身进行复制所以作为实际参数的数组是可能被改变的。例如下列函数9.3节见过可以通过在数组的每个元素中存储零来修改数组 void store_zeros(int a[], int n) { int i; for (i 0; i n; i) a[i] 0; } 为了指明数组型形式参数不会被改变可以在其声明中包含单词const int find_largest(const int a[], int n) { ... } 如果参数中有const编译器会核实find_largest函数体中确实没有对a中元素的赋值。 给函数传递数组所需的时间与数组的大小无关。因为没有对数组进行复制所以传递大数组不会产生不利的结果。 如果需要可以把数组型形式参数声明为指针。例如可以按如下形式定义find_largest函数 int find_largest(int *a, int n) { ... } 声明a是指针就相当于声明它是数组。编译器把这两类声明看作完全一样的。 请注意!!对于形式参数而言声明为数组跟声明为指针是一样的但是对变量而言声明为数组跟声明为指针是不同的。声明 int a[10];会导致编译器预留10个整数的空间但声明 int *a;只会导致编译器为一个指针变量分配空间。在后一种情况下a不是数组试图把它当作数组来使用可能会导致极糟的后果。例如赋值 *a 0; /* wrong */将在a指向的地方存储0。因为我们不知道a指向哪里所以对程序的影响是无法预料的。 可以给形式参数为数组的函数传递数组的“片段”所谓片段是指连续的数组元素组成的序列。假设希望用find_largest函数来定位数组b中某一部分的最大元素比如元素b[5],…,b[14]。调用find_largest函数时将传递b[5]的地址和数10表明希望find_largest函数从b[5]开始检查10个数组元素largest find_largest(b[5], 10); 12.3.2 用指针作为数组名 既然可以用数组名作为指针C语言是否允许把指针看作数组名进行取下标操作呢现在你可能猜出答案是肯定的你是对的。下面是一个例子 #define N 10 ... int a[N], i, sum 0, *p a; ... for (i 0; i N; i) sum p[i];编译器把p[i]看作*(pi)这是指针算术运算非常正规的用法。目前我们对能够对指针取下标还仅限于好奇但17.3节会看到它实际上非常有用。 12.4 指针和多维数组 就像指针可以指向一维数组的元素一样指针还可以指向多维数组的元素。本节将探讨用指针处理多维数组元素的常用方法。简单起见这里只讨论二维数组但所有内容都可以应用于更高维的数组。 12.4.1 处理多维数组的元素 从8.2节可知C语言按行主序存储二维数组换句话说先是第0行的元素接着是第1行的依此类推。 使用指针时可以利用这一布局特点。如果使指针p指向二维数组中的第一个元素即第0行第0列的元素就可以通过重复自增p的方法访问数组中的每一个元素。 作为示例一起来看看把二维数组的所有元素初始化为0的问题。假设数组的声明如下 int a[NUM_ROWS][NUM_COLS];显而易见的方法是用嵌套的for循环 int row, col; ... for (row 0; row NUM_ROWS; row) for (col 0; col NUM_COLS; col) a[row][col] 0;但是如果把a看作一维的整型数组那么就可以把上述两个循环改成一个循环了 int *p; ... for (p a[0][0]; p a[NUM_ROWS-1][NUM_COLS-1]; p) *p 0;循环开始时p指向a[0][0]。对p连续自增可以使指针p指向a[0][1]、a[0][2]、a[0][3]等。当p到达a[0][NUM_COLS-1]即第0行的最后一个元素时再次对p自增将使它指向a[1][0]也就是第1行的第一个元素。这一过程持续进行直到p越过a[NUM_ROWS-1][NUM_COLS-1]数组中的最后一个元素为止。 虽然把二维数组当成一维数组来处理看上去像在搞欺骗但是对大多数C语言编译器而言这样做是合法的。这样做是否是个好主意则要另当别论。这类方法明显破坏了程序的可读性但是至少对一些老的编译器来说这种方法在效率方面进行了补偿。不过对许多现代的编译器来说这样所获得的速度优势往往极少甚至完全没有。 12.4.2 处理多维数组的行 处理二维数组的一行中的元素该怎么办呢再次选择使用指针变量p。为了访问到第i行的元素需要初始化p使其指向数组a中第i行的元素0 p a[i][0]; 对于任意的二维数组a来说由于表达式a[i]是指向第i行中第一个元素元素0的指针上面的语句可以简写为: p a[i];为了了解原理回顾一下把数组取下标和指针算术运算关联起来的那个神奇公式对于任意数组a来说表达式a[i]等价于*(a i)。因此a[i][0]等同于(*(a[i] 0))而后者等价于*a[i]又因为和*运算符可以抵消所以也就等同于a[i]。下面的循环对数组a的第i行清零其中用到了这一简化 int a[NUM_ROWS][NUM_COLS], *p, i; ... for (p a[i]; p a[i] NUM_COLS; p) *p 0; 因为a[i]是指向数组a的第i行的指针所以可以把a[i]传递给需要用一维数组作为实际参数的函数。换句话说使用一维数组的函数也可以使用二维数组中的一行。因此诸如find_largest和store_zeros这类函数比我们预期的更加通用。思考最初设计用来找到一维数组中最大元素的find_largest函数现在同样可以用它来确定二维数组a中第i行的最大元素 largest find_largest(a[i], NUM_COLS); 12.4.3 处理多维数组的列 处理二维数组的一列中的元素就没那么容易了因为数组是按行而不是按列存储的。下面的循环对数组a的第i列清零 int a[NUM_ROWS][NUM_COLS], (*p)[NUM_COLS], i; ... for (p a[0]; p a[NUM_ROWS]; p) (*p)[i] 0; 这里把p声明为指向长度为NUM_COLS的整型数组的指针。在(*p)[NUM_COLS]中*p是需要使用括号的如果没有括号编译器将认为p是指针数组而不是指向数组的指针。表达式p把p移到下一行的开始位置。在表达式(*p)[i]中*p代表a的一整行因此(*p)[i]选中了该行第i列的那个元素。(*p)[i]中的括号是必要的因为编译器会将*p[i]解释为*(p[i])。 12.4.4 用多维数组名作为指针 就像一维数组的名字可以用作指针一样无论数组的维数是多少都可以采用任意数组的名字作为指针。但是需要特别小心。思考下列数组 int a[NUM_ROWS][NUM_COLS]; a不是指向a[0][0]的指针而是指向a[0]的指针。从C语言的角度来看这样做是有意义的。C语言认为a不是二维数组而是一维数组并且这个一维数组的每个元素又是一维数组。用作指针时a的类型是int (*)[NUM_COLS]指向长度为NUM_COLS的整型数组的指针。 了解a指向的是a[0]有助于简化处理二维数组元素的循环。例如为了把数组a的第i列清零可以用 for (p a[0]; p a [NUM_ROWS]; p) (*p)[i] 0;取代 for (p a; p a NUM_ROWS; p) (*p)[i] 0;另一种应用是巧妙地让函数把多维数组看作一维数组。例如思考如何使用find_largest函数找到二维数组a中的最大元素。我们把a数组的地址作为find_largest函数的第一个实际参数NUM_ROWS * NUM_COLS数组a中的元素总数量作为第二个实际参数 largest find_largest(a, NUM_ROWS * NUM_COLS); /* WRONG */ 这条语句不能通过编译因为a的类型为int (*)[NUM_COLS]但find_largest函数期望的实际参数类型是int *。正确的调用是 largest find_largest(a[0], NUM_ROWS * NUM_COLS); //a[0]指向第0行的元素0类型为int *编译器转换以后所以这一次调用将正确地执行。 12.5 C99中的指针和变长数组 指针可以指向变长数组8.3节中的元素变长数组是C99的一个特性。普通的指针变量可以用于指向一维变长数组的元素 void f(int n) { int a[n], *p; p a; ... }如果变长数组是多维的指针的类型取决于除第一维外每一维的长度。下面是二维的情况 void f(int m, int n) { int a[m][n], (*p)[n]; p a; ... }因为p的类型依赖于n而n不是常量所以说p具有变量修改类型。需要注意的是编译器并非总能确定p a这样的赋值语句的合法性。例如下面的代码可以通过编译但只有当m n时才是正确的: int a[m][n], (*p)[m]; p a; 如果m≠n后续对p的使用都将导致未定义的行为。 与变长数组一样变量修改类型也具有特定的限制其中最重要的限制是变量修改类型的声明必须出现在函数体内部或者在函数原型中。 变长数组中的指针算术运算和一般数组中的指针算术运算一样。回到12.4节中那个对二维数组a的一列进行清零操作的例子这次将二维数组a声明为变长数组 int a[m][n];指向数组a中某行的指针可以声明为 int (*p)[n];把第i列清零的循环几乎跟12.4节中的完全一样 for (p a; p a m; p) (*p)[i] 0; 问与答 问1我不理解指针的算术运算。如果指针是地址那么这是否意味着p j这样的表达式是把j加到存储在p中的地址上呢 答不是的。用于指针算术运算的整数需要根据指针的类型进行缩放。例如如果p的类型是int *那么p j通常给p加上4 × j假定int类型的值要用4字节存储。但是如果p的类型为double *那么p j可能给p加上8 × j因为double类型的值通常是8字节长。 问2编写处理数组的循环时数组取下标和指针算术运算哪种更好一些呢 答这个问题不容易回答因为答案与所使用的机器和编译器有关。对于早期PDP-11机器上的C语言指针算术运算能生成更快的程序。如果在现在的机器上采用现在的编译器数组取下标方法常常跟指针算术运算差不多而且有时甚至会更好。底线是学习这两种方法然后采用对你正在编写的程序更自然的方法。 问3我在某些地方看到i[a]和a[i]是一样的这是真的吗? 答是的这是真的确实很奇怪。对于编译器而言i[a]等同于*(i a)也就是*(a i)像普通加法一样指针加法也是可交换的。而*(a i)也就是a[i]。但是请不要在程序中使用i[a]除非你正计划参加下一届C语言混乱代码大赛。 问4为什么在形式参数的声明中*a和a[]是一样的 答上述这两种形式都说明我们期望实际参数是指针。在这两种情况下对a可进行的运算是相同的特别是指针算术运算和数组取下标运算。而且在这两种情况下可以在函数内给a本身赋予新的值。C语言要求数组变量的名字只能用作“常量指针”但对于数组型形式参数的名字没有这一限制。 问5把数组型形式参数声明为*a和a[]哪种风格更好呢 答这个问题很棘手。一种观点认为因为*a是不明确的函数到底需要多对象的数组还是指向单个对象的指针所以a[]更好是显而易见的。但是许多程序员认为把形式参数声明为*a更准确因为它会提醒我们传递的仅仅是指针而不是数组的副本。有些人则根据具体情况在两种风格之间切换切换的依据是函数是使用指针算术运算还是使用取下标运算来访问数组的元素的。本书也采用这种方法。在实践中*a比a[]更常用所以最好习惯于前者。不知道是真是假听说现在Dennis Ritchie把a[]标记称为“活化石”因为它“在使学习者困惑方面起的作用与在提醒程序阅读者方面所起的作用是相同的”。 问6我们已经看到C语言中数组和指针之间的紧密联系。称它们是可互换的是否准确 答不准确。数组型形式参数和指针形式参数是可以互换的但是数组型变量不同于指针变量。从技术上说数组的名字不是指针C语言编译器会在需要时把数组的名字转换为指针。为了更清楚地看出两者的区别思考对数组a使用sizeof运算符时会发生什么。sizeof(a)的值是数组中字节的总数即每个元素的大小乘以元素的数量。但是如果p是指针变量那么sizeof(p)的值则是用来存储指针值所需的字节数量。 问7书上说把二维数组视为一维数组对“大多数”编译器而言是合法的。难道不是对所有编译器都合法吗 答不能说对所有编译器都合法。一些现代的“越界检查”编译器不仅记录指针的类型还会在指针指向数组时记录数组的长度。例如假设给p赋一个指向a[0][0]的指针。从技术上讲p指向的是一维数组a[0]的第一个元素。如果在遍历a的所有元素的过程中反复对p进行自增操作当p越过a[0]的最后一个元素时我们就越界了。执行越界检查的编译器会插入代码验证p只能用于访问a[0]指向的数组中的元素。一旦越过这个数组的边界再对p进行自增就会导致编译器报错。 问8如果a是二维数组为什么可以给find_largest函数传递a[0]而不是数组a本身呢a和a[0]不是都指向同一位置数组开始的位置吗 答它们确实指向同一位置两者都指向元素a[0][0]。问题是a的类型不对。用作实际参数时a是一个指向数组的指针但find_largest函数需要指向整数的指针作为参数。a[0]的类型为int *因此它可以作为find_largest函数的实际参数。关于类型的这种考虑实际上是很好的如果C语言没这么挑剔我们可能会犯各种各样编译器注意不到的指针错误。 写在最后 本文是博主阅读《C语言程序设计现代方法第2版·修订版》时所作笔记日后会持续更新后续章节笔记。欢迎各位大佬阅读学习如有疑问请及时联系指正希望对各位有所帮助Thank you very much
http://www.yutouwan.com/news/400924/

相关文章:

  • 临沂网站建设找谁合肥seo按天扣费
  • 石家庄招投标公共服务平台官网seo优化软件下载
  • 合肥大型网站北京网站制作公司兴田德润实力强
  • 驻马店 网站制作短视频代运营费用明细
  • 网站关键词筛选域名注册网站哪个好
  • 帮做钓鱼网站会怎样成都游戏网站建设
  • 柳州房地产网站建设一般企业邮箱是哪里注册
  • 做网站 怎么推广dw wordpress
  • 深圳宝安区哪里好玩班级优化大师下载
  • 社区网站 备案做项目的网站
  • 培训通网站建设宁波北京网站建设
  • 携程网建设网站的理由交互设计产品有哪些
  • 网站怎么更改后台登陆密码网站设计中的事件是什么
  • 用ip地址做网站网站建设 台州
  • 分享网站模板信和财富网站开发
  • 网站开发合同 doc怎么自己做视频网站
  • 网站开发就业培训班免费红色ppt模板下载
  • 品牌网站建设的意义网站建设常规尺寸
  • 老徐蜂了网站策划书北京网络优化公司
  • 建站哪家好 discuz郑州那家做网站便宜
  • 网站关键字 怎么设置网站建设研究方法
  • 莆田建设局网站wordpress新建字段
  • 课程微网站开发技术wordpress4.4.1
  • 简述织梦网站上传步骤有什么做公众号封面图的网站
  • 做毕业设计哪个网站好应用软件开发包括什么
  • 松江外贸网站建设WordPress恶意扫描
  • 正在建设中的网站可算违规阿里云域名
  • 网站开发需要的软件德尔普网络做网站怎么样
  • 宿迁市建设局网站360建筑网怎么找回密码
  • 个人网站建设的流程怎么用dw做可上传文件的网站