2014年11月24日
source Insight 字体选择 Courier New 11 更好看 Auto Indent 选择smart , Indent close Brace
2014年11月21日
const char*, char const*, char*const的区别问题几乎是C++面试中每次都会有的题目。
事实上这个概念谁都有,只是三种声明方式非常相似很容易记混。
Bjarne在他的The C++ Programming Language里面给出过一个助记的方法: 把一个声明从右向左读。
char * const cp;
( * 读成 pointer to ) cp is a const pointer to char
const char * p;
p is a pointer to const char; char const * p;
同上因为C++里面没有const*的运算符,所以const只能修饰属于前面的类型char,因此char const * p等价于const char *p。
C++标准规定,const关键字放在类型或变量名之前等价的。
(1)char *p:p是一个工作指针,可以用来对任意位置 (非系统敏感区域)进 行读操作和写操作 ,一次读写一个字节(char占一个字节)。
(2)const char*p或者char const *p(因为没有const*p运算,因此const修饰的还是前面的char):可以对任意位置(非系统敏感区域)进行“只读” 操作。(“只读”是相对于char *p来说所限定的内容)
(3)char *const p(const 修饰的是p):只能对“某个固定的位置” 进 行读写操作,并且在定义p时就必须初始化(因为在后面不能执行“p=..”的操作,因此就不能在后面初始化,因此只能在定义时初始化)。(“某个固定的位 置”是相对于char *p来说所限定的内容)
可以总结以上3点为:char *p中的指针p通常是”万能”的工作指针 ,而(2)和(3)只是在(1)的基础上加了些特定的限制 ,这些限制在程序中并不是必须的,只是为了防止程序员的粗心大意而产生事与愿违的错 误。
另外,要明白“每块内存空间都可有名字;每块内存空间内容皆可变(除非有所限) ” 。比如函数里定义的char s[]="hello";事实上在进程的栈内存里开辟了6个变量共6个字节的空间,其中6个字符变量的名字分别为:s1[0]、s1[1]、 s1[2]、s1[3]、s1[4]、s1[5](内容是'\0')
{
待验证 : 还有一个4字节的指针变量s 。不过s是“有所限制”的,属于char *const类型,也就是前面说的 (3)这种情况,s一直指向s[0], 即(*s==s[0]=='h'),可以通过*s='k'来改变s所指向的 s[0]的值,但不能执行(char *h=“aaa”;s=h;)来对s另外赋值。
}
(4)上面的(2)和(3)只是对p进行限定,没有也不能对p所指向的空间进行限定,对于"char s[]="hello";const char*p=s;" 虽然不能通过*(p+i)='x'或者p[i]='x'来修改数组元素s[0]~s[4]的值,但可以通过*(s+i)='x'或者s[i]='x'来修改原数组元素的值--RAM里内存单元的可读可写属性不因对工作指针的限定而改变,而只会因对其本身的限定而改变。如const char c=‘A’,c是RAM里一个内存单元(8字节)的名字,该内存单元的内容只可读,不可写。
(5)const char **p或者char const**p :涉及两个指针p和 *p。由于const修饰char ,对指针p没有任何限定,对指针*p进行了上面情况(2)的限定。
(6)char *const *p:涉及两个指针p和 *p。由于const修饰前面的char*,也就是对p所指向的内容*p进行了限定(也属于前面的情况(2))。而对*p来说,由于不能通过"*p=..."来进行另外赋值,因此属于前面的情况(3)的限定。
(7)char **const p : 涉及两个指针p和 *p,const修饰p,对p进行上面情况(3)的限定,而对*p,没有任何限定。
//检出http://pan.baidu.com/share/link?shareid=3844355476&uk=3036849974 //剑指offer下载
2014年12月10日
关于函数指针传递方法:
1、在调用函数的形参列表中直接定义函数指针,比如void (func*)(void)
2、形参列表中定义一个空指针比如(void *func),在使用函数指针时将空指针强制转换成函数指针(void(*)(char))func 对应的函数void (*func)(char);函数声明.
指向指针的指针: int **p;
**p表示int型元素的实际值。
*p 指向int型元素,*p保存的是int型元素的地址
p 保存*p指针的实际地址
应用,p++可以的切换到下一个指针,如果指针指向的是结构体,p++就保存下一个结构体指针的地址。
**p与*p用法区分:
1、如果p指向内容申请了内存需要在函数执行之后继续有效的话,使用**p。
2、指向指针或者指针数组时用**p。
2014年12月11日
volatile 修饰变量表示变量随时可能会被改变,不希望被GCC有优化而作修改。
volatile 修饰函数表示该函数不会在返回到调用者代码中,可以让gcc产生更好一些的代码。
2014年12月12日
关于inline函数
1、非静态inline函数:总会被编译器编译出自己的汇编代码来。
2、静态inline函数: static inline 内联函数调用会集成到到调用者代码中,
如果内联函数中有使用该内联函数的地址,递归,或者内联函数中存在不能被替换集成的调用,该内联函数还是会被编译成汇编代码。
3、extern inline函数:(几乎类同于一个宏定义)这种情况下内联函数仅用于内联集成,并在任何情况下也不会单独产生该函数自身的汇编代码。
即使明确是用了该函数的地址也不会产生。这样的一个地址会变成一个外部引用,就好像你仅仅声明了一个函数而没有定义函数一样。
在代码中使用##可以讲字符连接起来(在宏定义中)例如
#define fork
#define __NR_fork 5
#define system_call(x) _NR_##x
int main()
{
printf("%d\n",system_call(fork));
return 0;
}
输出的结果是5
http://www.jobui.com/mianshiti/it/qianrushi/
http://wenku.baidu.com/link?url=1D9eG3wEPMWaiQek4tXtkwr7Jb5FdJPcVyLPIoNDmZg2CQ_vrxZBKmXf2GJXQJiiBz63eBARk6DYMulSBVXmId_H9gEj2rHfhUjtA3nn0wO
http://wenku.baidu.com/link?url=TMfwa7WwfsnAKd850qh2IM245LNg7DJSHTNOleTadequjNc1Lu24Tyu64zsGG4Sksto4__Apt2k9-emFg61Y3y_OHPSZKj5TcCXOj9l1msO
779

被折叠的 条评论
为什么被折叠?



