设为首页 加入收藏

TOP

快速学习C语言一: Hello World(一)
2015-01-22 21:13:15 来源: 作者: 【 】 浏览:31
Tags:快速 学习 语言 Hello World
估计不会写C语言的同学也都听过C语言,从头开始快速学一下吧,以后肯定能用的上。 如果使用过其它类C的语言,如JAVA,C#等,学C的语法应该挺快的。
?
先快速学习并练习一些基本的语言要素,基本类型,表达式,函数,循环结构, 基本字符串操作, 基本指针操作,动态分配内存,使用结构表示复杂数据, 使用函数指针实现灵活逻辑。
?
虽然C是一个规模很小的语言,但也得自己多设计一些练习练手才能学会。
?
基本类型
我就记得char, int, 别的都不常用吧应该,用的时候再搜索。
?
表达式
和JAVA, C#差不多吧,不用学基本,各种算数运算符,关系运算符,逻辑运算符,逗号, 括号等的意思应该也差不多,表达式最终的结果也有类型和值。
?
函数
函数是最基本的抽象,基本没有什么语言没有函数的概念,它封装一系列操作, 最简单的Hello world,如下。
?
?
static void hello_world(){
? ? printf("hello, world\n");
}
?
?
我们的练习都是随手写的函数,不需要被外部调用,所以前面加个static,表示只在 本文件内可见。
?
printf输出一行的话,最后要加\n, 常见个格式化参数有%d,%c,%s,%p等,分别表示 输出int, char, 字符串, 指针。
?
分支,循环结构
和别的语言差不多,不过i的声明要放在函数开头,c89就是这样。
?
static void n_hello_world(int n){
? ? int i = 0;
? ? for (i = 0; i < n; i++) {
? ? ? ? printf("hello, world\n");
? ? }
}
?
?
字符串练习,获取一个字符串的长度
库函数strlen就是干这个的,不过我们自己可以写一个练手,c没有字符串类型, 用'\0'结尾的字符数组表示字符串,所以for循环从头滚到'\0'位置就好了。
?
复制代码
// 字符串练习, 计算字符串长度
static int w_strlen(const char* str){
? ? int i;
? ? // 向后滚动指针,同时递增i,直到找到字符串结尾
? ? for (i = 0; *str != '\0'; str++, i++) {
? ? ? ? ;
? ? }
? ? return i;
}
复制代码
?
?
const 修饰符表示这个参数不能在函数里进行更改,防止意外改动。char *就是传说中 字符串了。 写C程序得用好for语句,有各种惯用法,用好了可以写出很紧凑的程序,比如上面for语句 的第2个分号后的逗号表达式可以递增两个变量。
?
理解字符串的存储
第一种方式是在编译时分配的内存,是字符串常量,指针s1指向的内存不能更改。 第二种方式应该是在栈上分配的内存(不确定),可以通过指针修改其中的字符。
?
复制代码
static void change_str_test(){
? ? // 常量不能修改
? ? // char* s1 = "hello"; // will core dump
? ? char s1[10] = "hello";
? ? *s1 = 'p';
? ? printf("%s\n", s1);
}
复制代码
?
?
指针练习
指针可以进行加减的操作,每加一次就滚动过它指向的类型长度, 比如char指针就是 滚动1个字节。
?
复制代码
// 指针练习, 反转字符串
static char* reverse(char* str){
? ? char* ret = str;
? ? // 滚到字符数组末尾的\0之前
? ? char* p = str + w_strlen(str) - 1;
? ? char c;
?
? ? // 两个指针,一个从前往后滚,一个从后往前滚,直到就要交错之前
? ? // 滚动的过程中交换两个指针指向的字符
? ? for ( ; p > str; --p, ++str) {?
? ? ? ? printf("debug[reverse]: %p %p %c %c\n", p, str, *p, *str);
? ? ? ? c = *p;
? ? ? ? *p = *str;
? ? ? ? *str = c;
? ? }
?
? ? return ret;
}
复制代码
?
?
c = *p表示取出指针p指向的字符,赋值给变量c,*表示取值。
?
*p = *str相当于p[i] = str[i],右边的取出来的是值,左边的取出来的也是值, 值赋值给值,看起来有些诡异,但就是这样写的。反正p = *str肯定不对,因为p是 指针类型,*str是计算结果是字符类型。
?
动态分配内存
我记得TCPL前几章都没讲malloc,free等内存分配的函数,好多任务只需要在编译阶段 分配内存就够了,但比较大型复杂的程序应该都需要动态管理一些内存的。
?
C语言没有GC,要手工释放动态分配的内存,否则就会造成内存泄漏,所以一定要配平 资源,有malloc的地方,一定要想好它应该在哪里free。
?
目前我了解到的原则就有两种:
?
谁分配,谁释放
谁使用,谁释放
对了, malloc出来的内存要强转成你需要的指针类型,然后free时指针要滚到你动态 分配内存的起始点。
?
复制代码
// 内存申请相关,连接两个字符串
static void concat_test(){
? ? char* a = "hello";
? ? char* b = "world";
? ? //结果字符串长度为两个字符窜长度加\0的位置
? ? int len = w_strlen(a) + w_strlen(b) + 1;
? ? // 动态分配内存
? ? char* p = (char *)malloc(sizeof(char) * len);
? ? char* result;?
?
? ? // 必须判断是否分配到内存
? ? if (p != NULL){
? ? ? ? // 保存动态分配内存的开始指针,free时必须从这里free
? ? ? ? result = p;
?
? ? ? ? //滚动p和a,直到a的末尾
? ? ? ? while (*a != '\0') {
? ? ? ? ? ? printf("debug[concat_test]:while a %p %c\n", a, *a);
? ? ? ? ? ? *p++ = *a++;
? ? ? ? }
?
? ? ? ? //滚动p和b,直到b的末尾
? ? ? ? while (*b != '\0') {
? ? ? ? ? ? printf("debug[concat_test]:while b %p %c\n", a, *a);
? ? ? ? ? ? *p++ = *b++;
? ? ? ? }
?
? ? ? ? // 末尾整个0
? ? ? ? *p= '\0';
? ? ? ? printf("concat_test: %s\n", result);
?
? ? ? ? //释放动态分配的内存
? ? ? ? free(result);
? ? }else{
? ? ? ? printf("malloc error");
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇C和指针 (pointers on C)――第.. 下一篇Objective-C 布尔类型 和 cl..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: