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

苏宁网站开发人员工资国内做设计的网站有哪些方面

苏宁网站开发人员工资,国内做设计的网站有哪些方面,制作网页的颜色模式为,做外围网站代理违法吗结构体 一、结构体简介 C 语言内置的数据类型#xff0c;除了最基本的几种原始类型#xff0c;只有数组属于复合类型#xff0c;可以同时包含多个值#xff0c;但是只能包含相同类型的数据#xff0c;实际使用中并不够用。 实际使用中#xff0c;主要有下面两种情况除了最基本的几种原始类型只有数组属于复合类型可以同时包含多个值但是只能包含相同类型的数据实际使用中并不够用。 实际使用中主要有下面两种情况需要更灵活强大的复合类型。 复杂的物体需要使用多个变量描述这些变量都是相关的最好有某种机制将它们联系起来。某些函数需要传入多个参数如果一个个按照顺序传入非常麻烦最好能组合成一个复合结构传入。 为了解决这些问题C 语言提供了struct关键字允许自定义复合数据类型将不同类型的值组合在一起。这样不仅为编程提供方便也有利于增强代码的可读性。 C 语言没有其他语言的对象object和类class的概念struct 结构很大程度上提供了对象和类的功能。 struct fraction {int numerator;int denominator; }; /*定义了新的数据类型以后就可以声明该类型的变量这与声明其他类型变量的写法是一样的。 *//* 声明自定义类型的变量时类型名前面不要忘记加上struct关键字。也就是说必须使用struct fraction f1声明变量不能写成fraction f1。 */ struct fraction f1;f1.numerator 22; f1.denominator 7; /* 逐一对属性赋值。上面示例中先声明了一个struct fraction类型的变量f1这时编译器就会为f1分配内存接着就可以通过.运算符为f1的不同属性赋值。 */struct car {char* name;float price;int speed; };struct car saturn {Saturn SL/2, 16000.99, 175}; /* 可以使用大括号一次性对 struct 结构的所有属性赋值。 *//* 变量saturn是struct car类型大括号里面同时对它的三个属性赋值。如果大括号里面的值的数量少于属性的数量那么缺失的属性自动初始化为0。大括号里面的值的顺序必须与 struct 类型声明时属性的顺序一致。否则必须为每个值指定属性名。 struct car saturn {.speed172, .nameSaturn SL/2}; */struct car saturn {.speed172, .nameSaturn SL/2}; saturn.speed 168; /* 声明变量以后可以修改某个属性的值。 */struct book {char title[500];char author[100];float value; } b1 {title, Author, 56.7}; /* struct 的数据类型声明语句与变量的声明语句可以合并为一个语句。 */ struct {char title[500];char author[100];float value; } b1; /* 该语句同时声明了数据类型book和该类型的变量b1。如果类型标识符book只用在这一个地方后面不再用到这里可以将类型名省略。什么是只用在一个地方 */ struct {char title[500];char author[100];float value; } b1 {Harry Potter, J. K. Rowling, 10.0},b2 {Cancer Ward, Aleksandr Solzhenitsyn, 7.85}; /* struct声明了一个匿名数据类型然后又声明了这个类型的变量b1。与其他变量声明语句一样可以在声明变量的同时对变量赋值。 */// 指针变量也可以指向struct结构。 struct book {char title[500];char author[100];float value; }* b1;// 或者写成两个语句 struct book {char title[500];char author[100];float value; }; struct book* b1; /* 变量b1是一个指针指向的数据是struct book类型的实例。 */// struct 结构也可以作为数组成员。 struct title numbers[1000];numbers[0].numerator 22; numbers[0].denominator 7; 二、结构体内存对齐 struct 结构占用的存储空间不是各个属性存储空间的总和而是最大内存占用属性的存储空间的倍数其他属性会添加空位与之对齐。 为什么浪费这么多空间进行内存对齐呢这是为了加快读写速度把内存占用划分成等长的区块就可以快速在 struct 结构体中定位到每个属性的起始地址。 由于这个特性在有必要的情况下定义 struct 结构体时可以采用存储大小递增或递减的顺序定义每个属性这样就能节省一些空间。 struct foo {int a; // 4 - 8 空4个char* b; // 8char c; // 1 - 8 空7个 }; printf(%d\n, sizeof(struct foo)); // 24 struct foo {char c; // 1 - 4 空三个int a; // 4char* b; // 8 }; printf(%d\\n, sizeof(struct foo)); // 16 上面示例中占用空间最小的char c排在第一位其次是int a占用空间最大的char* b排在最后。整个strct foo的内存占用就从24字节下降到16字节。 三、struct 的赋值 第一种方法struct 变量也类似于其他变量可以使用赋值运算符赋值给另一个变量。 struct cat { char name[30]; short age; } a, b;strcpy(a.name, Hello); a.age 3;b a; // struct赋值 b.name[0] M;printf(%s\n, a.name); // Hello printf(%s\n, b.name); // Mello注意 赋值要求两个变量是同一个类型不同类型的 struct 变量无法互相赋值。C 语言没有提供比较两个自定义数据结构是否相等的方法无法用比较运算符比如和!比较两个数据结构是否相等或不等 第二种方法可以使用函数memcpy来为结构体赋值将一个结构体的指定长度的内存区域复制到另一个结构体的指定位置 // 定义两个学生结构体 Student student1 { 1001, Alice, 90.5 }; Student student2;// 为 student2 赋值 memcpy(student2, student1, sizeof(Student));四、struct 指针 struct类型的指针和其他数据类型的指针是相似的完全可以按照其他指针的理解方式来学习struct指针。 传入struct变量函数内部得到的是一个原始值的副本。 #include stdio.hstruct turtle {char* name;char* species;int age; };void fun(struct turtle t) {t.age t.age 1; }int main() {struct turtle myTurtle {Turtle, sea turtle, 18};fun(myTurtle);printf(Age is %i\\n, myTurtle.age); // 输出 18return 0; } 上面示例中函数happy()传入的是一个 struct 变量myTurtle函数内部有一个自增操作。但是执行完happy()以后函数外部的age属性值根本没变。原因就是函数内部得到的是 struct 变量的副本改变副本影响不到函数外部的原始数据。 通常情况下开发者希望传入函数的是同一份数据函数内部修改数据以后会反映在函数外部。而且传入的是同一份数据也有利于提高程序性能。这时就需要将 struct 变量的指针传入函数通过指针来修改 struct 属性就可以影响到函数外部。 传入struct指针那么通过指针修改数据就会改变之前保存的数据不再是副本 void happy(struct turtle* t) {...} happy(myTurtle);上面代码中t是 struct 结构的指针调用函数时传入的是指针。struct 类型跟数组不一样类型标识符本身并不是指针所以传入时指针必须写成myTurtle。 函数内部也必须使用(*t).age或t-age的写法从指针拿到 struct 结构本身。 void happy(struct turtle* t) {(*t).age (*t).age 1;// t-age t-age 1// 大大增强了代码的可读性 }上面示例中(*t).age不能写成*t.age因为点运算符.的优先级高于*。*t.age这种写法会将t.age看成一个指针然后取它对应的值会出现无法预料的结果。 现在重新编译执行上面的整个示例happy()内部对 struct 结构的操作就会反映到函数外部。 这里提及一个在链表中容易犯错的知识 move l1; 和 move-next l1; 是不完全等价的。 move l1; 是将指针 move 直接指向 l1 所指向的节点。这意味着 move 和 l1 同时指向同一个节点它们指向的是同一块内存地址。move-next l1; 是将 move 指针所指向节点的 next 指针指向 l1 所指向的节点。这意味着将 l1 插入到 move 所指向节点的后面。 如果只执行 move l1;则 l1 并没有插入到新链表中而是直接将 move 指向了 l1 所指向的节点。 如果只执行 move-next l1;则相当于将 l1 插入到了 move 所指向的节点的后面但没有将 move 指针移动到新的节点。 五、struct 的嵌套 struct 结构的成员可以是另一个 struct 结构。 struct species {char* name;int kinds; };struct fish {char* name;int age;struct species breed; };// fish的属性breed是另一个struct结构species。赋值的时候有多种写法。 // 写法一 struct fish shark {shark, 9, {Selachimorpha, 500}};// 写法二 struct species myBreed {Selachimorpha, 500}; struct fish shark {shark, 9, myBreed};// 写法三 struct fish shark {.nameshark,.age9,.breed{Selachimorpha, 500} };// 写法四 struct fish shark {.nameshark,.age9,.breed.nameSelachimorpha,.breed.kinds500// 引用breed属性的内部属性要使用两次点运算符 };printf(Sharks species is %s, shark.breed.name); struct name {char first[50];char last[50]; };struct student {struct name name;short age;char sex; } student1;/* 对字符数组属性赋值要使用strcpy()函数不能直接赋值因为直接改掉字符数组名的地址会报错。 */ strcpy(student1.name.first, Harry); strcpy(student1.name.last, Potter);// or struct name myname {Harry, Potter}; student1.name myname; struct 结构内部不仅可以引用其他结构还可以自我引用即结构内部引用当前结构。比如链表结构的节点就可以写成下面这样。 struct node {int data;struct node* next; }; struct node {int data;struct node* next; };struct node* head;// 生成一个三个节点的列表 (11)-(22)-(33) head malloc(sizeof(struct node));head-data 11; head-next malloc(sizeof(struct node));head-next-data 22; head-next-next malloc(sizeof(struct node));head-next-next-data 33; head-next-next-next NULL;// 遍历这个列表 for (struct node *cur head; cur ! NULL; cur cur-next) {printf(%d\\n, cur-data); } 六、typedef关键字 起别名 typedef type name; 为某个类型起别名 type代表类型名name代表别名。 typedef unsigned char BYTE; BYTE c z;typedef 可以一次指定多个别名。 ~~typedef int antelope, bagel, mushroom;~~ typedef 可以为指针起别名。 typedef int* intptr; int a 10; intptr x a;/* 使用的时候要小心这样不容易看出来变量x是一个指针类型。 */ typedef 也可以用来为数组类型起别名。 typedef int five_ints[5]; five_ints x {11, 22, 33, 44, 55};typedef 为函数起别名的写法如下。 typedef signed char (*fp)(void); /* 类型别名fp是一个指针代表函数signed char (*)(void)。 */typedef为结构体起别名 typedef struct cell_phone {int cell_no;float minutes_of_charge; } phone; // 或者把typedef带下来typedef struct cell_phone phone // 还可以省略结构体的名字 phone p {5551234, 5}; /* typedef命令可以为 struct 结构指定一个别名 这样使用起来更简洁。phone是别名而不是结构体变量 */起别名的好处 1更好的代码可读性。 2为 struct、union、enum 等命令定义的复杂数据结构创建别名从而便于引用。 3typedef 方便以后为变量改类型。 typedef float app_float; app_float f1, f2, f3; /* 变量f1、f2、f3的类型都是float。如果以后需要为它们改类型只需要修改typedef语句即可。 */4可移植性 某一个值在不同计算机上的类型可能是不一样的。 int i 100000;上面代码在32位整数的计算机没有问题但是在16位整数的计算机就会出错。 C 语言的解决办法就是提供了类型别名在不同计算机上会解释成不同类型比如int32_t。 int32_t i 100000; 上面示例将变量i声明成int32_t类型保证它在不同计算机上都是32位宽度移植代码时就不会出错。 这一类的类型别名都是用 typedef 定义的。下面是类似的例子。 typedef long int ptrdiff_t; typedef unsigned long int size_t; typedef int wchar_t; 这些整数类型别名都放在头文件stdint.h不同架构的计算机只需修改这个头文件即可而无需修改代码。 因此typedef有助于提高代码的可移植性使其能适配不同架构的计算机。 5简化类型声明 C 语言有些类型声明相当复杂比如下面这个。 char (*(*x(void))[5])(void); typedef 可以简化复杂的类型声明使其更容易理解。首先最外面一层起一个类型别名。 typedef char (*Func)(void); Func (*x(void))[5]; 这个看起来还是有点复杂就为里面一层也定义一个别名。 typedef char (*Func)(void); typedef Func Arr[5]; Arr* x(void); 上面代码就比较容易解读了。 x是一个函数返回一个指向 Arr 类型的指针。Arr是一个数组有5个成员每个成员是Func类型。Func是一个函数指针指向一个无参数、返回字符值的函数。 内存操作函数 一、内存简介 C 语言的内存管理分成两部分。 一部分是系统管理的 系统管理的内存主要是函数内部的变量局部变量。这部分变量在函数运行时进入内存函数运行结束后自动从内存卸载。这些变量存放的区域称为”栈“stack”栈“所在的内存是系统自动管理的。 另一部分是用户手动管理的 用户手动管理的内存主要是程序运行的整个过程中都存在的变量全局变量这些变量需要用户手动从内存释放。如果使用后忘记释放它就一直占用内存直到程序退出这种情况称为**”内存泄漏“memory leak。**这些变量所在的内存称为”堆“heap”堆“所在的内存是用户手动管理的。 二、malloc() 功能手动分配内存系统就会在“堆”中分配一段连续的内存动态数组 函数原型void *malloc(size_t size) 参数size是指分配的字节数 返回值是一个指向分配内存首地址的指针若分配失败则返回NULL 注意 malloc分配内存并不会进行初始化所以内存中还保留着之前的值 有时候为了增加代码的可读性可以对malloc()返回的指针进行一次强制类型转换。 一定要注意检查malloc是否分配失败 /* malloc()最常用的场合就是为数组和自定义数据结构分配内存。 */ int *p (int *) malloc(sizeof(int) * 10);for (int i 0; i 10; i)p[i] i * 5;/* malloc()用来创建数组有一个好处就是它可以创建动态数组即根据成员数量的不同而创建长度不同的数组。 */ int *p (int *) malloc(n * sizeof(int));/*注意malloc()不会对所分配的内存进行初始化里面还保存着原来的值。如果没有初始化就使用这段内存可能从里面读到以前的值。程序员要自己负责初始化比如字符串初始化可以使用strcpy()函数。 */char *p malloc(sizeof(char) * 4); strcpy(p, abc);// or p abc;三、 calloc() 功能手动分配内存空间并将内存存放的值初始化为0 函数原型void* calloc(size_t n, size_t size); 返回值一个指向分配内存首地址的指针分配失败时返回 NULL 参数第一个参数是某种数据类型的值的数量第二个是该数据类型的字节长度。分配内存的大小是由这两者的乘积决定。 注意 malloc() 不会对内存进行初始化如果想要初始化为0还要额外调用memset()函数。 int* p calloc(10, sizeof(int));// 等同于 int* p malloc(sizeof(int) * 10); memset(p, 0, sizeof(int) * 10);四、realloc() 功能realloc()函数用于修改已经分配的内存块的大小可以放大也可以缩小 函数原型void* realloc(void* block, size_t size) 返回值返回一个指向新的内存块的指针。如果分配不成功返回 NULL。 参数 block已经分配好的内存块指针由malloc()或calloc()或realloc()产生。size该内存块的新大小单位为字节。 注意 realloc()可能返回一个全新的地址数据也会自动复制过去也可能返回跟原来一样的地址。 realloc()优先在原有内存块上进行缩减尽量不移动数据所以通常是返回原先的地址。如果新内存块小于原来的大小则丢弃超出的部分如果大于原来的大小则不对新增的部分进行初始化程序员可以自动调用memset()。 realloc()的第一个参数可以是 NULL这时就相当于新建一个指针。 char* p realloc(NULL, 3490); // 等同于 char* p malloc(3490); 如果realloc()的第二个参数是0就会释放掉内存块。 由于有分配失败的可能所以调用realloc()以后最好检查一下它的返回值是否为 NULL。分配失败时原有内存块中的数据不会发生改变。 float* new_p realloc(p, sizeof(*p * 40));if (new_p NULL) {printf(Error reallocing\\n);return 1; } realloc()不会对内存块进行初始化。 五、free() 功能释放手动分配的内存 函数原型void free(void *block) 参数指向开辟内存的指针block 返回值无返回值 注意 若手动分配的内存不释放掉那这个内存块会一直占用到程序运行结束。 // free()的参数是malloc()返回的内存地址 // 分配内存后若不再使用一定要及时释放否则容易造成内存泄露 int* p (int*) malloc(sizeof(int));*p 12; free(p);分配的内存块一旦释放就不应该再次操作已经释放的地址也不应该再次使用free()对该地址释放第二次。 六、restrict 说明符 声明指针变量时可以使用restrict说明符告诉编译器该块内存区域只有当前指针一种访问方式其他指针不能读写该块内存。这种指针称为“受限指针”restrict pointer。 int *restrict p; p malloc(sizeof(int)); 上面示例中声明指针变量p时加入了restrict说明符使得p变成了受限指针。后面当p指向malloc()函数返回的一块内存区域就味着该区域只有通过p来访问不存在其他访问方式。 int* restrict p; p malloc(sizeof(int));int* q p; *q 0; // 未定义行为 上面示例中另一个指针q与受限指针p指向同一块内存现在该内存有p和q两种访问方式。这就违反了对编译器的承诺后面通过*q对该内存区域赋值会导致未定义行为。 七、memcpy() 功能memcpy()用于将一块源地址内存拷贝到另一块目标地址内存中**不能有重叠内存区域。**该函数的原型定义在头文件string.h。 函数原型void *memcpy(void *restrict dest, void *restrict source, size_t n); 参数dest是目标地址source是源地址第三个参数n是要拷贝的字节数n 返回值memcpy()的返回值是第一个参数即目标地址的指针。 注意 **dest和source都是 void 指针表示可以移动任何类型的内存数据**如果要拷贝10个 double 类型的数组成员n就等于10 * sizeof(double)而不是10。该函数会将从source开始的n个字节拷贝到dest。**dest和source都是 void 指针表示这里不限制指针类型各种类型的内存数据都可以拷贝**两者都有 restrict 关键字表示dest指针所指的区域不能让别的指针来修改包括source同样source指针所指的区域也不能让别的指针修改也包括dest即这两个内存块不应该有互相重叠的区域。因为memcpy()只是将一段内存的值复制到另一段内存所以不需要知道内存里面的数据是什么类型。 复制字符串 /* memcpy()可以取代strcpy()进行字符串拷贝而且是更好的方法不仅更安全速度也更快它不检查字符串尾部的\0字符。 */#include stdio.h #include string.hint main(void) {char s[] Goats!;char t[100];memcpy(t, s, sizeof(s)); // 拷贝7个字节包括终止符printf(%s\n, t); // Goats!return 0; }my_memcpy.c void* my_memcpy(void* dest, void* src, int byte_count) {char* s src;char* d dest;while (byte_count--) {*d *s;}return dest; } /*不管传入的dest和src是什么类型的指针将它们重新定义成一字节的 char 指针这样就可以逐字节进行复制。*d *s语句相当于先执行*d *s源字节的值复制给目标字节然后各自移动到下一个字节。最后返回复制后的dest指针便于后续使用。 */八、memmove() 功能memmove()函数用于将一段源地址内存数据复制到另一段目标地址内存中。允许dest和source所指向的内存区域有重叠。该函数的原型定义在头文件string.h。 函数原型void *memmove(void *dest, void *source, size_t n); 参数dest是目标地址source是源地址n是要移动的字节数。 返回值memmove()返回值是第一个参数即目标地址的指针。 注意 如果dest和source所指向的内存区域发生重叠源区域的内容会被更改如果没有重叠它与memcpy()行为相同。 char x[] Hello world!;// 输出 world!world! printf(%s\n, (char *) memmove(x, x[6], 6));上面示例中从字符串x的6号位置开始6个字节就是“world!”memmove()将其前移到0号位置所以x就变成了“world!world!”。 九、memcmp() 功能memcmp()函数用来比较两个内存区域。它的原型定义在string.h。 函数原型int memcmp(const void *s1, const void *s2, size_t n); 参数前两个参数是用来比较的指针第三个参数指定比较的字节数。 返回值两块内存区域的每个字节以字符形式解读按照字典顺序进行比较从左到右比较ASCII码值如果两者相同返回0如果s1大于s2返回大于0的整数如果s1小于s2返回小于0的整数。 注意 与strncmp()不同memcmp()可以比较内部带有字符串终止符\0的内存区域。 char s1[] {b, i, g, \0, c, a, r}; char s2[] {b, i, g, \0, c, a, t};if (memcmp(s1, s2, 3) 0) // true if (memcmp(s1, s2, 4) 0) // true if (memcmp(s1, s2, 7) 0) // false if (strncmp(s1, s2, 3) 0) // true if (strncmp(s1, s2, 7) 0) // true 注意strncmp不会比较\0之后的内容十、memchr() 功能在内存区域中查找指定字符。 函数原型void *memchr(const void *s, int c, size_t n); 参数第一个参数是一个指针指向内存区域的开始位置第二个参数是所要查找的字符第三个参数是待查找内存区域的字节长度。 返回值一旦找到它就会停止查找并返回指向该位置的指针。如果直到检查完指定的字节数依然没有发现指定字符则返回 NULL。 十一、memset() 功能将一段内存全部设置为指定值。 函数原型void *memset(void *s, int c, size_t n); 参数第一个参数是一个指针指向内存区域的开始位置第二个参数是待写入的字符值第三个参数是一个整数表示需要待格式化的字节数。 返回值返回第一个参数指针。 简单例子 char str[] BBBBBBBBBBBB;// 输出 bbbbbbbBBBBB printf(%s\n, (char*) memset(str, b, 7)); 注意 malloc开辟内存后没有初始化memset()可以将开辟内存区域全部初始化为0。 int *arr (int *)malloc(100 * sizeof(int)); memset(arr, 0, 100 * sizeof(int)); // 第三个参数不是sizeof(arr)// ... free(arr);
http://www.pierceye.com/news/180688/

相关文章:

  • 揭阳新闻最新消息常用的seo工具推荐
  • 网站方案策划中国最大的博客网站
  • 网站建设加空间食品包装设计ppt
  • 搭建一个网站 优帮云张家口远大建设集团网站
  • wordpress本地视频播放器苏州谷歌seo
  • 银川网站建设有哪些16岁做分期网站
  • 制作网站对话框火车票网站建设多少
  • 怎么问客户做不做网站设计一个简单的广告
  • 佛山 网站关键词优化trel域名
  • 哪家网站建设好大连房产网
  • 企业做推广哪些网站比较好兰州有做百度网站的吗
  • 网站建设和管理规则自己建网站的流程
  • 网站的前期推广广州网站建设加盟
  • 网站灰色 代码深圳的深圳的网站建设公司
  • 做电影采集网站需要多大vps安徽建设新工程信息网站
  • 中小企业网站制作化工厂网站建设
  • 电子政务网站建设出版社百度网页提交入口
  • 专业柳州网站建设哪家便宜淄博桓台网站建设定制
  • 网站建设投标标书企业网站建设销售前景
  • wordpress建站教程凌风wordpress 仪表盘 慢
  • 怎样给网站或者商品做推广关于建网站新闻
  • 上海 微信网站 建站一对一直播app
  • ppt模板免费下载网站哪个好克拉玛依市住房和建设局网站
  • 制作网站得多少钱交互设计留学
  • 理财网站免费建设经典重庆新闻论坛
  • 南京专业网站制作哪家好企业所得税交多少
  • 广西网站建设哪家好常熟做网站的
  • 礼品网站制作辽宁省建设部网站
  • 网站群的建设目标澧县网页设计
  • 邯郸网站建设在哪里网站建设yingkagou