2. C 与 C++ 的关系
- C++继承了所有C特性
- C++在C的基础上提供了更多的语法支持
- C++的设计目标是运行效率与开发效率的统一
C 到 C++ 的升级
- C++更强调语言的实用性
- 所有的变量都可以在需要使用时再定义
int c = 0;
for (int i = 1; i <= 3; i++)
{
for (int j = 1; j <= 3; j++)
{
c += i * j;
}
}
对比: C语言种的变量都必须在作用域开始的位置定义!!(C99之前的版本)
-
register
关键字请求编译器将局部变量存储于寄存器中- 在C++中依然支持
register
关键字 - C++编译器有自己的优化方式
- C语言中无法获取
register
变量的地址 - C++中可以取得
register
变量的地址
- C语言中无法获取
- 在C++中依然支持
-
C++中的
register
关键字- C++编译器发现程序中需要取
register
变量的地址时,register
对变量的声明变得无效 - 早期C语言编译器不会对代码进行优化,因此
register
变量是一个很好的补充
- C++编译器发现程序中需要取
-
在C语言中,重复定义多个同名的全局变量是合法的
-
在C++中,不允许定义多个同名的全局变量
C语言中多个同名的全局变量最终会被链接到全局数据区的同一个地址空间上;C++ 直接拒绝这种二义性的做法!!!
#include <stdio.h>
int g_v;
int g_v;
int main()
{
printf("Begin...\n");
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);
register int a = 0;
printf("&a = %p\n", &a);
printf("End...\n");
return 0;
}
gun gcc 编译运行
编译:
gcc 2-1.c -o 2-1.out
2-1.c: In function ‘main’:
2-1.c:24:5: error: address of register variable ‘a’ requested
24 | printf("&a = %p\n", &a);
| ^~~~~~
gun g++ 编译运行
编译:
g++ 2-1.c -o 2-1.out
2-1.c:4:5: error: redefinition of ‘int g_v’
4 | int g_v;
| ^~~
2-1.c:3:5: note: ‘int g_v’ previously declared here
3 | int g_v;
| ^~~
2-1.c: In function ‘int main()’:
2-1.c:22:18: warning: ISO C++17 does not allow ‘register’ storage class specifier [-Wregister]
22 | register int a = 0;
| ^
struct
关键字的加强- C语言中的
struct
定义了一组变量的集合 - C语言中
struct
定义的标识符并不是一种新的类型 - C++中的
struct
用于定义一个全新的类型
- C语言中的
C和C++中结构体的等价定义
typedef struct _tag_student Student;
struct _tag_student
{
const char* name;
int age;
};
struct Student
{
const char* name;
int age;
};
- C++中所有的标识符都必须显示的声明类型
- C语言中的默认类型在 C++中是不合法的
思考?
int f()
与int f(void)
有区别吗?如果有区别是什么?
f(i)
{
printf("i = %d\n", i);
}
g()
{
return 5;
}
-
问题:
- 函数
f()
的返回值和参数分别是什么类型? - 函数
g()
可以接受多少个参数?
- 函数
-
在C语言中
int f()
表示返回值为int
,接受任意参数的函数f(void)
表示返回值为int
的无参函数
-
在C++中
int f()
和int f(void)
具有相同的意义,表示返回值为int
的无参函数
#include <stdio.h>
struct Student
{
const char *name;
int age;
};
f(i)
{
printf("i = %d\n", i);
}
g()
{
return 5;
}
int main(int argc, char **argv)
{
Student s1 = {"Fyang", 28};
Student s2 = {"Yang", 26};
f(10);
printf("g() = %d\n", g(1, 2, 3, 4, 5));
return 0;
}
gun gcc 编译运行
编译:
gcc 2-2.c -o 2-2.out
2-2.c:9:1: warning: return type defaults to ‘int’ [-Wimplicit-int]
9 | f(i)
| ^
2-2.c: In function ‘f’:
2-2.c:9:1: warning: type of ‘i’ defaults to ‘int’ [-Wimplicit-int]
2-2.c: At top level:
2-2.c:14:1: warning: return type defaults to ‘int’ [-Wimplicit-int]
14 | g()
| ^
2-2.c: In function ‘main’:
2-2.c:21:5: error: unknown type name ‘Student’; use ‘struct’ keyword to refer to the type
21 | Student s1 = {"Fyang", 28};
| ^~~~~~~
| struct
2-2.c:21:19: warning: initialization of ‘int’ from ‘char *’ makes integer from pointer without a cast [-Wint-conversion]
21 | Student s1 = {"Fyang", 28};
| ^~~~~~~
2-2.c:21:19: note: (near initialization for ‘s1’)
2-2.c:21:28: warning: excess elements in scalar initializer
21 | Student s1 = {"Fyang", 28};
| ^~
2-2.c:21:28: note: (near initialization for ‘s1’)
2-2.c:22:5: error: unknown type name ‘Student’; use ‘struct’ keyword to refer to the type
22 | Student s2 = {"Yang", 26};
| ^~~~~~~
| struct
2-2.c:22:19: warning: initialization of ‘int’ from ‘char *’ makes integer from pointer without a cast [-Wint-conversion]
22 | Student s2 = {"Yang", 26};
| ^~~~~~
2-2.c:22:19: note: (near initialization for ‘s2’)
2-2.c:22:27: warning: excess elements in scalar initializer
22 | Student s2 = {"Yang", 26};
| ^~
2-2.c:22:27: note: (near initialization for ‘s2’)
gun g++ 编译运行
编译:
g++ 2-2.c -o 2-2.out
2-2.c:9:2: error: expected constructor, destructor, or type conversion before ‘(’ token
9 | f(i)
| ^
2-2.c:14:1: error: ISO C++ forbids declaration of ‘g’ with no type [-fpermissive]
14 | g()
| ^
2-2.c: In function ‘int main(int, char**)’:
2-2.c:24:5: error: ‘f’ was not declared in this scope
24 | f(10);
| ^
2-2.c:26:27: error: too many arguments to function ‘int g()’
26 | printf("g() = %d\n", g(1, 2, 3, 4, 5));
| ~^~~~~~~~~~~~~~~
2-2.c:14:1: note: declared here
14 | g()
| ^
#include <stdio.h>
typedef struct _tag_student Student;
struct _tag_student
{
const char* name;
int age;
};
f(i) // int f(int i)
{
printf("i = %d\n", i);
}
g()
{
return 5;
}
int main(int argc, char **argv)
{
Student s1 = {"Fyang", 28};
Student s2 = {"Yang", 26};
f(10);
printf("g() = %d\n", g(1, 2, 3, 4, 5));
return 0;
}
gun gcc 编译运行
编译:
gcc 2-3.c -o 2-3.out
运行:
./2-3.out
i = 10
g() = 5
- Q:
int f()
与int f(void)
有什么区别吗?如果有区别是什么? - A:
- C语言编译器中:
int f()
返回值为int
,参数任意多个;int f(void)
返回值为int
,不接受任何参数
- C++编译器中:
int f()
与int f(void)
没有区别,返回值为int
,不接受任何参数
- C语言编译器中:
小结
- C++更强调实用性,可以在任意的地方声明变量
- C++中的
register
只是一个兼容的作用 - C++编译器能够更好的进行优化
- C++中的任意标识符都必须显示的指明类型