c/cpp学习笔记
从大学刚学习c/cpp以来,几年过去了,但是由于大学没有好好深入学习研究c/cpp以及算法,挺后悔的。所以奉劝计算机专业的学生,大学不应该过早步入各种开发的步调,而忽略c/cpp、算法、基础专业知识的学习。其实一开始,最重要的就是把基础打扎实了,编程的思维方式和动手能力很重要,如何将现实问题,通过算法建模转化为代码才是至关重要的,可以视为灵魂。
所以我把自己学习的过程做记录,没事的时候仔细体会,别有一番风味,每次也会有不一样的体会。
指针
先以一段代码开始
12345678910111213141516171819202122232425262728293031323334353637383940414243 int main(int argc, char *argv[]){// create two arrays we care aboutint ages[] = {23, 43, 12, 89, 2};char *names[] = {"Alan", "Frank","Mary", "John", "Lisa"};// safely get the size of agesint count = sizeof(ages) / sizeof(int);int i = 0;// first way using indexingfor(i = 0; i < count; i++) {printf("%s has %d years alive.\n",names[i], ages[i]);}printf("---\n");// setup the pointers to the start of the arraysint *cur_age = ages;char **cur_name = names;// second way using pointersfor(i = 0; i < count; i++) {printf("%s is %d years old.\n",*(cur_name+i), *(cur_age+i));}printf("---\n");// third way, pointers are just arraysfor(i = 0; i < count; i++) {printf("%s is %d years old again.\n",cur_name[i], cur_age[i]);}printf("---\n");// fourth way with pointers in a stupid complex wayfor(cur_name = names, cur_age = ages;(cur_age - ages) < count;cur_name++, cur_age++){printf("%s lived %d years so far.\n",*cur_name, *cur_age);}return 0;}上面的代码很好的诠释了指正的工作原理,首先
- 在你的计算机中开辟一块内存。
- 将ages这个名字“指向”它的起始位置。
- 通过选取ages作为基址,并且获取位置为i的元素,来对内存块进行索引。
- 将ages+i处的元素转换成大小正确的有效的int,这样就返回了你想要的结果:下标i处的int。
指针仅仅是指向计算机中的某个地址,并带有类型限定符,所以你可以通过它得到正确大小的数据,指针的用途就是让你手动对内存块进行索引,一些情况下数组并不能做到。绝大多数情况中,你可能打算使用数组,但是一些处理原始内存块的情况,是指针的用武之地。指针向你提供了原始的、直接的内存块访问途径,让你能够处理它们。
指针有四个最基本的操作:
- 向OS申请一块内存,并且用指针处理它。这包括字符串,和一些你从来没见过的东西,比如结构体。
- 通过指针向函数传递大块的内存(比如很大的结构体),这样不必把全部数据都传递进去。
- 获取函数的地址用于动态调用。
- 对一块内存做复杂的搜索,比如,转换网络套接字中的字节,或者解析文
其实当我们在阅读别人的代码或者自己运用指正,只要把下面这几点牢记于心,就应该没问题,一步一步去拆解理解:- type *ptr:type类型的指针,名为ptr
- *ptr:ptr所指向位置的值
- *(ptr + i):ptr所指向位置加上i)的值
- &thing:thing的地址
- type *ptr = &thing:名为ptr,type类型的指针,值设置为thing的地址
- ptr++:自增ptr指向的位置*
结构体
从一段代码搞起:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172 struct Person {char *name;int age;int height;int weight;};struct Person *Person_create(char *name, int age, int height, int weight){struct Person *who = malloc(sizeof(struct Person));assert(who != NULL);//使用strdup来复制字符串name,是为了确保结构体真正拥有它。strdup的行为实际上类似malloc但是它同时会将原来的字符串复制到新创建的内存。who->name = strdup(name);who->age = age;who->height = height;who->weight = weight;return who;}void Person_destroy(struct Person *who){assert(who != NULL);free(who->name);free(who);}void Person_print(struct Person *who){printf("Name: %s\n", who->name);printf("\tAge: %d\n", who->age);printf("\tHeight: %d\n", who->height);printf("\tWeight: %d\n", who->weight);}int main(int argc, char *argv[]){// make two people structuresstruct Person *joe = Person_create("Joe Alex", 32, 64, 140);struct Person *frank = Person_create("Frank Blank", 20, 72, 180);// print them out and where they are in memoryprintf("Joe is at memory location %p:\n", joe);Person_print(joe);printf("Frank is at memory location %p:\n", frank);Person_print(frank);// make everyone age 20 years and print them againjoe->age += 20;joe->height -= 2;joe->weight += 40;Person_print(joe);frank->age += 20;frank->weight += 20;Person_print(frank);// destroy them both so we clean upPerson_destroy(joe);Person_destroy(frank);return 0;}
其实结构体就相当于数据库中的一行或者OOP语言中的类一样*
##