如果说,C 语言比较有特色的东西是什么。我觉得就是,讲指针,数组,地址算数结合在了一起。
当然,这也引起了一些问题,使得,C语言的程序非常的灵魂,有些时候,一些写法对初学者还比较的
晦涩难懂。比如复制字符串,可以有下面的几种写法。
反正个人感觉,要能很轻松看别人写的C代码,还是要花点功夫的。
要真正理解这些东西,就必须对基本概念有所把握。
1. 地址:每个变量,都在内存中有个地址,这个地址就是调用这个变量的ID。如果学过汇编,就知道,
寻址是一个比较烦的问题,当然高级语言中,就没有这样麻烦了。地址的占用的字节和平台相关,在我的win32下面是,3个字节。
2. 指针: 指针是一种变量,这种变量保存了 “变量的地址”。所以,它不能指向一个表达式,register 类型的变量也不行(只能指向内存中的变量)。
3. 数组:数组和指针的关系相当紧密。首先,声明一个数组,系统就为某一个类型的变量连续分配了一个内存区块,然后,把起始的地址赋值给数组名。
数组名可以理解为一种受限制的指针,它是readonly的。
数组声明时,就分配了内存,所以 a[0] a[1] 的你就可以取了。
指针声明时,只是声明了一个地址变量, *(p+1), 这样搞就出问题了。
一个特例:
char *s = "hello world.";
char s[] = "hello world.";
你会发现很奇怪,为什么 指针 和 数组 能赋值相同的东西呢?
实际上是一个在这里,编译器做了处理。
第一个:"hello world."是一个字符串常量。可以认为是一个指针。然后,*s 指向了这个常量。
而第二个 "hello world." 编译器做了处理 ,实际上等价于下面的形式 {'h','e',...,'\0'}
指针算数:
指针的运算,统一了指针和数组,使得数组能做的事情,指针都能做,当然,数组从写法上要简洁一些。
指针运算可以分为以下几类:
1. 赋值: 相同的类型是指针可以进行赋值。
2.加法: 指针可以和数字进行加法运算。
3. 减法: 指针可以和数字进行减法运算,但是不要乱访问。如果两个指针指向了同一个数组,那么也可以进行减法的运行。
4. 比较: 如果指针指向了同一个数组,还可以进行比较的运算。
不考虑底层的内存分配问题,数组名可以认为是一种受限制的指针。这个不是很准确的理解,可以让你知道,实际上问题也不是很复杂:
编程序就是一个分配内存,操作内存的过程。把数据在内存,操作来,操作去,就变成程序了。具体怎么操作合理,如何构建非常复杂的操作
就构成了复杂的计算机科学。
当然,这也引起了一些问题,使得,C语言的程序非常的灵魂,有些时候,一些写法对初学者还比较的
晦涩难懂。比如复制字符串,可以有下面的几种写法。
void strcpy (char *s, char *t)
{
int i;
i = 0;
while ((s[i] = t[i]) != '\0')
i++;
}
void strcpy (char *s, char *t)
{
while ((*s = *t) != '\0') {
s++;
t++;
}
}
void strcpy (char *s, char *t)
{
while (*s++ = *t++);
}
{
int i;
i = 0;
while ((s[i] = t[i]) != '\0')
i++;
}
void strcpy (char *s, char *t)
{
while ((*s = *t) != '\0') {
s++;
t++;
}
}
void strcpy (char *s, char *t)
{
while (*s++ = *t++);
}
反正个人感觉,要能很轻松看别人写的C代码,还是要花点功夫的。
要真正理解这些东西,就必须对基本概念有所把握。
1. 地址:每个变量,都在内存中有个地址,这个地址就是调用这个变量的ID。如果学过汇编,就知道,
寻址是一个比较烦的问题,当然高级语言中,就没有这样麻烦了。地址的占用的字节和平台相关,在我的win32下面是,3个字节。
2. 指针: 指针是一种变量,这种变量保存了 “变量的地址”。所以,它不能指向一个表达式,register 类型的变量也不行(只能指向内存中的变量)。
3. 数组:数组和指针的关系相当紧密。首先,声明一个数组,系统就为某一个类型的变量连续分配了一个内存区块,然后,把起始的地址赋值给数组名。
数组名可以理解为一种受限制的指针,它是readonly的。
数组声明时,就分配了内存,所以 a[0] a[1] 的你就可以取了。
指针声明时,只是声明了一个地址变量, *(p+1), 这样搞就出问题了。
一个特例:
char *s = "hello world.";
char s[] = "hello world.";
你会发现很奇怪,为什么 指针 和 数组 能赋值相同的东西呢?
实际上是一个在这里,编译器做了处理。
第一个:"hello world."是一个字符串常量。可以认为是一个指针。然后,*s 指向了这个常量。
而第二个 "hello world." 编译器做了处理 ,实际上等价于下面的形式 {'h','e',...,'\0'}
指针算数:
指针的运算,统一了指针和数组,使得数组能做的事情,指针都能做,当然,数组从写法上要简洁一些。
指针运算可以分为以下几类:
1. 赋值: 相同的类型是指针可以进行赋值。
2.加法: 指针可以和数字进行加法运算。
3. 减法: 指针可以和数字进行减法运算,但是不要乱访问。如果两个指针指向了同一个数组,那么也可以进行减法的运行。
4. 比较: 如果指针指向了同一个数组,还可以进行比较的运算。
不考虑底层的内存分配问题,数组名可以认为是一种受限制的指针。这个不是很准确的理解,可以让你知道,实际上问题也不是很复杂:
编程序就是一个分配内存,操作内存的过程。把数据在内存,操作来,操作去,就变成程序了。具体怎么操作合理,如何构建非常复杂的操作
就构成了复杂的计算机科学。