-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathc_c++1.txt
128 lines (79 loc) · 6.18 KB
/
c_c++1.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
1.双感叹号的作用:!!非0值 = 1,而!!0 = 0
2.和管道命令相似的 << 在c++里包含iostream头文件后,常作为输入输出赋值命令,例如cout<<"a"<<a<<endl 输出a,cin>>a 输入的值存入a中
3.void *:/强制转换 ---> (类型名 *)要转换的变量
void作用不在于定义,虽然void *它可以定义任意类型的指针变量,但是它的主要功能在于对函数返回的限定和对函数参数的限定,
void定义的东西通常是没有返回值的,而其参数又可以是任意类型,当void *定义的指针和其他例如float,int *有值的交换时,
void所定义的可以接受任何类型的值,不过其他类型的变量就必须在void类型进行强制转换后再能进行赋值操作了。
1.函数没有返回值
一般来说c/c++里是不允许出现函数类型未定义这种不安全的语法,即使编译器也不会报错甚至没有警告,不过的确是不严谨的。
在c中凡是不加类型限定的函数,默认是返回整型的值,并不是void类型。所以最好不要遗漏未定义类型的函数,若没有返回值的,请声明为void。
2.函数没有参数
若函数无参数,请声明其参数为void类型 例如int r_0(void){return 0;}
无参数的情况,这里可以分成c和c++两种情况,在c++是不允许调用参数为空的函数是向里面传入参数,而在turbo C里却不会报错,依旧会正常输出值。
3.be careful about void-pointer
void *定义的指针(下面统称为void指针)不能进行算法操作,ANSI标准坚持进行算法操作的指针必须要明确其指向数据的数据类型,
但是凡事皆有例外,在GNU类的编译器中并不阻止void指针进行算法操作,即void *定义的例如pvoid,也可以进行诸如 pvoid++;这样的自增操作,操作的实际是pvoid的结果增大了1。
(GUN类编译器里将void指针的算法操作视为和char *一致)不过规范上来说,为了提高程序的移植性,这样写更好:(char *)pvoid++;
int * pint; pint++; 此时的pint自增后,变大的是sizeof(int)的结果而并不是pint的值?
4.如果函数参数可能是任意类型的指针,那么请声明为void *类型。
典型的如内存操作函数:
void * memcpy(void *dest, const void *src, size_t len);
/ int a1[100],a2[100]; memcpy(a1,a2,100*sizeof(int)); a2到a1
void * memset(void * buffer, int c, size_t num);
/ int array[100]; memset(array,0,100*sizeof(int)); array清0
btw:以上两个内存操作函数返回值也是void指针类型,这是为什么?
5.void不能表示一个真实的变量
void是对变量的一个抽象定义,类似于c++里的抽象基类的概念,实际上并不能给一个变量定义为void类型。
例如 void a; func(void b); ---> false
6.summary
int *p含义是定义p为int *类型的指针,而不是用int类型定义*p这个指针!
无论什么类型的指针,初始值都是一样的0xCCCCCCCC(VC6里的,不同编译器会有变化),void *p; cout<<p<<endl; 输出值应该就是之前说的那个初始值
一个指针如果暂时没有合适的初始化值,就可以把它置为NULL。 pNULL;p = 0;p = 0L;p = '\0';p = 3 - 3;p = 0 * 17
(void)argc;
4.#include<memory.h> #include"stdlib.h"
#include <..> 是从标准库里直接提取头文件
#include ".. "是先从源文件当前目录提取头文件(可以是自己写的头文件),再从标准库里提取。
5.双冒号命令 ::
1.域操作符,表示类和成员的关系,类似从属关系的地方 class::member,也常常用于在类变量内部作为当前类实例的元素,
2.用在全局函数前,在函数名前加::
3.引用成员函数及变量,作用域成员与算符,system::math::sqrt(),
4.命名空间作用域符?
6.strlen和sizeof
前者是函数 后者是一种操作字符
对于一个静态数组,strlen是计算字符串实际的长度,sizeof是计算分配的长度,如果字符串未定义分配长度,sizeof计算的时候会在实际字符串长度上加1,那个1是结束的一个默认“\0”
对于静态数组和动态数组识别的不同:
char * ss="blabla", sizeof(ss)=4/一个长整型指针所占的空间, sizeof(*ss)=1/ss数组第一个字符所占的空间, strlen(ss)=6/ss字符串的长度,会识别空格
7.struct结构体
typedef struct xxx(){
;
;
}xxx1;
struct xxx(){
;
;
};
xxx xxx1;
while (*++*argv)
**++argv
++**argv
错在哪?
int *p=1
*p=0
指针不能指向常量,即使定义时可以指向int *p=2,但是后面也不能改变其的指向再指向常量
同理初始为空指针的,也不能在之后再让其指向任何常量
注意:指针是用来指向变量的,指向常量会让它指向的东西变成不稳定的,易变的,这对常量来说是绝对不允许的情况
1.int main(void){
char *s ="hello world";
*s ='H';
}
被装载时,系统把“hello world” 连同其它的字符串和const型数据放入到内存的只读区。执行时,一个变量s被设为指向该字符串的位置,当再试图向该位置写时,就会产生段错误。
2.
int *ptr = NULL;
*ptr =1;
因为该代码只创建了一个空指针,并没有指向一个具体空间,当赋值时,产生段错误。
8.主函数以外的函数,如果在整个文件的位置在主函数的后面,主函数中需要有相应调用函数的声明,否则会有链接的错误.
9."initialization makes pointer from integer without a cast [enabled by default]"
定义指针变量出现的错误,尽量不要出现系统帮你去对变量进行类型转换,自己手动去强制转换或者改变定义类型.
10.‘a’ is used uninitialized in this function [-Wuninitialized]
指针变量a指向一个不确定的且没有被初始化的内存地址.指针变量没有特定赋值,因此没有分配固定的内存空间,会指向一段随机的内存地址,这样是被视为可能会造成系统不稳定的因素.
解决方法就是对其进行赋值,在c中,如果不是后面会对该变量赋值,那么一定一定在最开始定义的时候就进行初始化(一般变量)或赋值(指针操作)否则就会出现这种未初始化的错误.gcc里对一般变量只初始化不赋值默认值是"0".