1 C 到 C++ 的升级
1 变量定义
-
C++ 中所有的变量都可以在需要使用时再定义
-
C语言中的变量都必须在作用域开始的位置定义
-
示例
-
Demo1:test.c
#include <stdio.h> int main() { int c = 0; for(int i = 1; i <= 3; ++i) { for(int j = 1; j <= 3; ++j) { c += i * j; } } printf("c = %d\n", c); return 0; }
-
编译
test.c: In function ‘main’: test.c:7: error: ‘for’ loop initial declarations are only allowed in C99 mode test.c:7: note: use option -std=c99 or -std=gnu99 to compile your code test.c:8: error: ‘for’ loop initial declarations are only allowed in C99 mode
-
Demo2:test.cpp
#include <stdio.h> int main() { int c = 0; for(int i = 1; i <= 3; ++i) { for(int j = 1; j <= 3; ++j) { c += i * j; } } printf("c = %d\n", c); return 0; }
-
编译并运行
c = 36
-
2 register
-
register
关键字请求编译器将局部变量存储于寄存器中- 在 C++ 中依然支持
register
关键字 - C++ 编译器有自己的优化方式
- C语言中无法获得
register
变量的地址;C++ 中可以取得register
变量的地址
- 在 C++ 中依然支持
-
示例
-
Demo:test.c
#include <stdio.h> int main(int argc, char *argv[]) { register int a = 0; printf("&a = %p\n", &a); return 0; }
-
编译
test.c: In function ‘main’: test.c:7: error: address of register variable ‘a’ requested
-
Demo:test.cpp
#include <stdio.h> int main(int argc, char *argv[]) { register int a = 0; printf("&a = %p\n", &a); return 0; }
-
编译并运行
&a = 0xbfb553c0
-
3 多个同名全局变量
-
在C语言中,重复定义多个同名的全局变量是合法的
-
在 C++ 中,不允许定义多个同名的全局变量
-
C语言中多个同名的全局变量最终会被链接到全局数据区的同一个地址空间上,C++ 直接拒绝这种做法
-
C 到 C++ 的升级1
-
Demo1:test.c
#include <stdio.h> int g_v; int g_v; int main(int argc, char *argv[]) { printf("Begin...\n"); printf("End...\n"); return 0; }
-
运行
Begin ... End ...
-
Demo2:test.cpp
#include <stdio.h> int g_v; int g_v; int main(int argc, char *argv[]) { printf("Begin...\n"); printf("End...\n"); return 0; }
-
编译
test.cpp:4: error: redefinition of ‘int g_v’ test.cpp:3: error: ‘int g_v’ previously declared here
-
4 struct
-
struct
关键字的加强-
C语言中的
struct
定义了一组变量的集合 -
C语言中
struct
定义的标识符并不是一种新的类型 -
C++ 中的
struct
用于定义一个全新的类型 -
C 和 C++ 中结构体的等价定义
typedef struct _tag_student Student; struct _atg_student { const char* name; int age; }; struct Student { conts char* name; int age; };
-
5 返回类型与参数
-
问题:
int f()
与int f(void)
有区别么?- 看是C语言编译器还是C++编译器
-
C++ 中所有的标识符都必须显式的声明类型
-
C语言中的默认类型在C++中是不合法的
f(i) { printf("i = %d\n",i); } g() { return 5; }
- 问题1:函数
f
的返回值和参数分别是什么类型? - 问题2:函数
g
可以接受多少个参数?
- 问题1:函数
-
在C语言中
int f()
表示返回值为int
,接收任意参数的函数int f(void)
表示返回值为int
的无参函数
-
在 C++ 中
-
int f()
和int f(void)
具有相同的意义:表示返回值为int
的无参函数 -
C 到 C++ 的升级2
-
Demo:test.cpp
#include <stdio.h> //定义一个新的类型 struct Student { const char* name; int age; }; //报错:C++不接受默认类型 f(i) { printf("i = %d\n", i); } //报错:C++不接受默认类型 g() { return 5; } int main(int argc, char *argv[]) { //可以直接使用Student类型定义一个局部变量 Student s1 = {"ABCD", 30}; Student s2 = {"EFGH", 30}; f(10); printf("g() = %d\n", g(1,2,3,4,5)); return 0; }
-
编译:
g++ test.cpp
test.cpp:9:2: error: expected constructor, destructor, or type conversion before ‘(’ token f(i) ^ test.cpp:14:3: error: ISO C++ forbids declaration of ‘g’ with no type [-fpermissive] g() ^ test.cpp: In function ‘int main()’: test.cpp:28:9: error: ‘f’ was not declared in this scope f(10); ^ test.cpp:30:36: error: too many arguments to function ‘int g()’ printf("g() = %d\n",g(1,2,3,4,5)); ^ test.cpp:14:1: note: declared here g() ^
-
编译:
gcc test.c
1.c:8:1: warning: return type defaults to ‘int’ [-Wimplicit-int] f(i) { ^ 1.c: In function ‘f’: 1.c:8:1: warning: type of ‘i’ defaults to ‘int’ [-Wimplicit-int] 1.c: At top level: 1.c:12:1: warning: return type defaults to ‘int’ [-Wimplicit-int] g() { ^ 1.c: In function ‘main’: 1.c:19:5: error: unknown type name ‘Student’ Student s1 = {"ABCD", 30}; ^ 1.c:19:19: warning: initialization makes integer from pointer without a cast [-Wint-conversion] Student s1 = {"ABCD", 30}; ^ 1.c:19:19: note: (near initialization for ‘s1’) 1.c:19:27: warning: excess elements in scalar initializer Student s1 = {"ABCD", 30}; ^ 1.c:19:27: note: (near initialization for ‘s1’) 1.c:20:5: error: unknown type name ‘Student’ Student s2 = {"EFGH", 30}; ^ 1.c:20:19: warning: initialization makes integer from pointer without a cast [-Wint-conversion] Student s2 = {"EFGH", 30}; ^ 1.c:20:19: note: (near initialization for ‘s2’) 1.c:20:27: warning: excess elements in scalar initializer Student s2 = {"EFGH", 30}; ^ 1.c:20:27: note: (near initialization for ‘s2’)
-