c&cpp常见问题

静态与常量

 

static函数与普通函数有什么区别?

如果一个函数只能被本文件中其他函数所调用,它称为内部函数。内部函数又称为静态函数。对于可在当前源文件以外使用的函数,应该在一个头文件中说明,要使用这些函数的源文件要包含这个头文件。

//////////////////////////////////////////////////////////////////////

 

static全局变量与普通的全局变量有什么区别?

   全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。 

    这两者在存储方式上并无不同。这两者的区别虽在于非静态全局变量的作用域是整个源程序, 当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用, 因此可以避免在其它源文件中引起错误。从以上分析可以看出, 把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域,限制了它的使用范围

//////////////////////////////////////////////////////////////////////

 

C++ 程序中调用被 C编译器编译后的函数,为什么要加 extern “C”

 

    C++语言支持函数重载,C语言不支持函数重载。函数被C++编译后在库中的名字与C语言的不同。

假设某个函数的原型为: void foo(int x, int y);

该函数被C编译器编译后在库中的名字为_fooC++编译器则会产生像_foo_int_int之类的名字。

C++提供了C连接交换指定符号externC”来解决名字匹配问题。

     程序员用链接指示符linkage directive 告诉编译器该函数是用其他的程序设计语言
编写的链接指示符有两种形式既可以是单一语句single statement 形式也可以是复
合语句compound statement 形式

// 单一语句形式的链接指示符
extern "C" void exit(int);
// 复合语句形式的链接指示符
extern "C" {
int printf( const char* ... );
int scanf( const char* ... );
}
// 复合语句形式的链接指示符
extern "C" {
#include <cmath>
}

     语言提供的链接指示extern "C" extern "C"是惟一被
保证由所有C++实现都支持的每个编译器实现都可以为其环境下常用的语言提供其他链接
指示例如extern "Ada"可以用来声明是用Ada 语言写的函数extern "FORTRAN"用来
声明是用FORTRAN 语言写的函数等等因为其他的链接指示随着具体实现的不同而不同

 

 

//////////////////////////////////////////////////////////////////////

@font-face{ font-family:"Times New Roman"; } @font-face{ font-family:"宋体"; } @font-face{ font-family:"Symbol"; } @font-face{ font-family:"Arial"; } @font-face{ font-family:"黑体"; } @font-face{ font-family:"Courier New"; } @font-face{ font-family:"Wingdings"; } @font-face{ font-family:"新宋体"; } @font-face{ font-family:"Courier New CYR"; } p.0{ margin:0pt; margin-bottom:0.0001pt; layout-grid-mode:char; text-align:justify; font-size:10.5000pt; font-family:'Times New Roman'; } div.Section0{ margin-top:72.0000pt; margin-bottom:72.0000pt; margin-left:90.0000pt; margin-right:90.0000pt; size:612.0000pt 792.0000pt; }

要使引用pr代表变量“char *p”,则pr的初始化语句为

@font-face{ font-family:"Times New Roman"; } @font-face{ font-family:"宋体"; } @font-face{ font-family:"Symbol"; } @font-face{ font-family:"Arial"; } @font-face{ font-family:"黑体"; } @font-face{ font-family:"Courier New"; } @font-face{ font-family:"Wingdings"; } @font-face{ font-family:"新宋体"; } @font-face{ font-family:"Courier New CYR"; } p.0{ margin:0pt; margin-bottom:0.0001pt; layout-grid-mode:char; text-align:justify; font-size:10.5000pt; font-family:'Times New Roman'; } div.Section0{ margin-top:72.0000pt; margin-bottom:72.0000pt; margin-left:90.0000pt; margin-right:90.0000pt; size:612.0000pt 792.0000pt; }

char * &pr = p;

//////////////////////////////////////////////////////////////////////

@font-face{ font-family:"Times New Roman"; } @font-face{ font-family:"宋体"; } @font-face{ font-family:"Symbol"; } @font-face{ font-family:"Arial"; } @font-face{ font-family:"黑体"; } @font-face{ font-family:"Courier New"; } @font-face{ font-family:"Wingdings"; } @font-face{ font-family:"新宋体"; } @font-face{ font-family:"Courier New CYR"; } p.0{ margin:0pt; margin-bottom:0.0001pt; layout-grid-mode:char; text-align:justify; font-size:10.5000pt; font-family:'Times New Roman'; } div.Section0{ margin-top:72.0000pt; margin-bottom:72.0000pt; margin-left:90.0000pt; margin-right:90.0000pt; size:612.0000pt 792.0000pt; }

if/else/return 的使用方法 

if(condition)    可以等价为  return (condition?x:y); 

  return x; 

else 

  return y; 

//////////////////////////////////////////////////////////////////////

@font-face{ font-family:"Times New Roman"; } @font-face{ font-family:"宋体"; } @font-face{ font-family:"Symbol"; } @font-face{ font-family:"Arial"; } @font-face{ font-family:"黑体"; } @font-face{ font-family:"Courier New"; } @font-face{ font-family:"Wingdings"; } @font-face{ font-family:"新宋体"; } @font-face{ font-family:"Courier New CYR"; } p.0{ margin:0pt; margin-bottom:0.0001pt; layout-grid-mode:char; text-align:justify; font-size:10.5000pt; font-family:'Times New Roman'; } div.Section0{ margin-top:72.0000pt; margin-bottom:72.0000pt; margin-left:90.0000pt; margin-right:90.0000pt; size:612.0000pt 792.0000pt; }

#define C语言 

  const  C语言 C++语言 

  const常量有数据类型,编译器会进行类型安全检查,而#define没有数据类型, 

  const的常量可以进行调试,但宏常量不能进行调试. 

//////////////////////////////////////////////////////////////////////

@font-face{ font-family:"Times New Roman"; } @font-face{ font-family:"宋体"; } @font-face{ font-family:"Symbol"; } @font-face{ font-family:"Arial"; } @font-face{ font-family:"黑体"; } @font-face{ font-family:"Courier New"; } @font-face{ font-family:"Wingdings"; } @font-face{ font-family:"新宋体"; } @font-face{ font-family:"Courier New CYR"; } p.0{ margin:0pt; margin-bottom:0.0001pt; layout-grid-mode:char; text-align:justify; font-size:10.5000pt; font-family:'Times New Roman'; } div.Section0{ margin-top:72.0000pt; margin-bottom:72.0000pt; margin-left:90.0000pt; margin-right:90.0000pt; size:612.0000pt 792.0000pt; }

const的使用方法 

在全局定义 const float PI=3.1415926 

在类中定义 

class A 

{... 

    A(int size); 

    const int SIZE; 

}; 

A::A(int size):SIZE(size) 

  ... 

对参数和函数的定义(const只能修饰输入参数,不能修饰输出参数) 

const int x=1;  表示x的值是1,在程序中不能改变; 

const int* x;  表示x代表的地址所指向的内容是不能改变得; 

int const* x;  与const int* x;的表示的意思一样; 

int * const x;  表示x代表的地址是不能改变的; 

当是输入参数时,不需要是void Func(const int i),void Func(const int& i),可以是void Func(int i) 

因为输入参数采用"值传递"(const int i),由于函数将自动产生临时变量用于复制该参数,该输入参数本来

就无需保护,所以不要加const修饰; 

不用const int& i的原因在于内部数据类型的参数不存在构造、析构的过程,而复制也非常快,

"值传递"和"引用传递"的效率几乎相当. 

当是输入参数时,不需要是void Func(const A a),void Func(A a),可以是void Func(A& a)

或void Func(const A& a) 

不用const A a,A a的原因是函数的效率比较低,因为函数体内将产生A类型的临时对象用于复制参数a,

而临时对象的构造、复制和析构过程都需要消耗时间 

最好用const A&a的原因是A&a中的a可以被改变,A&a和const A&a的好处在于都不会产生临时对象,效率高;

@font-face{ font-family:"Times New Roman"; } @font-face{ font-family:"宋体"; } @font-face{ font-family:"Symbol"; } @font-face{ font-family:"Arial"; } @font-face{ font-family:"黑体"; } @font-face{ font-family:"Courier New"; } @font-face{ font-family:"Wingdings"; } @font-face{ font-family:"新宋体"; } @font-face{ font-family:"Courier New CYR"; } p.0{ margin:0pt; margin-bottom:0.0001pt; layout-grid-mode:char; text-align:justify; font-size:10.5000pt; font-family:'Times New Roman'; } div.Section0{ margin-top:72.0000pt; margin-bottom:72.0000pt; margin-left:90.0000pt; margin-right:90.0000pt; size:612.0000pt 792.0000pt; }

const A Func(const A&a )const的好处 

第一个const表示返回的是个内部产生的对象,它不能被修改 

const A Func(...) 

{...} 

const A a=Func(...);//不能是A a=Func(...); 

第二个const表示输入的参数是引用传递,函数内部不会产生临时对象,而且这个对象不能被内部修改 

第三个const表示此函数内部的所涉及的数据成员不能修改 

class Stack 

  int m_num; 

  int GetCount(void) const; 

  int Pop(void); 

int Stack::GetCount(void) const 

  m_num++;//编译错误,企图修改数据成员m_num; 

  Pop();//编译错误,企图调用非const函数 

 

////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////

 

<think> 我们正在讨论C++代码中的符号含义。根据用户引用的内容,用户询问代码中“>”和“&”符号的含义。注意,用户提供的引用[1]中已经解释了这些符号在C++中的部分含义,但用户特别提到了“>”和“&”,而引用[1]中主要解释了*、->和&,其中对于“>”并没有单独解释(因为通常“>”在C++中是大于运算符,但用户可能指的是在模板中使用时的“>”或者在右移运算符中的“>>”的一部分?)。此外,用户还提到了“&”符号,引用[1]中已经对“&”在声明语句和定义语句中的含义进行了解释。 由于用户的问题中只提到了“>”和“&”,我们需要结合上下文来回答。但是,在用户提供的引用[3]中,提到了“>>”、“&”、“|”等运算符的含义,其中“>>”是右移运算符,而“&”是按位与运算符。 因此,我们分两种情况考虑: 1. 如果用户问的是单独出现的“>”,那么它通常是大于运算符,用于比较两个值的大小。 2. 如果用户问的是“>>”,那么它可能是右移运算符,也可能是流操作符(如cin、cout)或者模板中的两个连续大于号(在C++11之后,两个连续大于号不再需要空格)。 另外,关于“&”符号,在C++中主要有三种用途: - 作为取地址运算符(一元运算符) - 作为引用声明符(在声明变量时) - 作为按位与运算符(二元运算符) 根据用户提供的引用[1]和引用[3],我们可以整合如下: 引用[1]告诉我们: - 在声明语句中,`&`用于声明引用(如`int& a = x;`)。 - 在定义语句中,`&`用于取地址(如`p = &a;`)。 引用[3]主要讲了位运算符,其中`&`是按位与运算符,`>>`是右移运算符。 因此,我们可以这样回答: 在C++代码中,`>`和`&`符号的含义如下: 一、`>`符号: - 单独使用:通常表示“大于”比较运算符,例如:`if (a > b) { ... }`。 - 两个`>`连用(即`>>`): 1. 在C++中,两个连续的大于号`>>`可以表示: a) 右移位运算符(二元运算符),例如:`a = b >> 2;` 表示将b的二进制位向右移动2位。 b) 流提取运算符,用于从输入流中读取数据,例如:`cin >> x;`。 c) 在模板中,C++11标准之前,两个连续大于号必须用空格隔开(如`vector<vector<int> >`),而C++11及之后标准允许连续的两个大于号(如`vector<vector<int>>`)。 二、`&`符号: - 在声明语句中(出现在类型后面),用于声明引用变量,例如:`int& ref = x;`(表示ref是x的引用)。 - 在表达式中,作为一元运算符时,表示取地址运算符,例如:`int* p = &x;`(表示取变量x的地址,赋值给指针p)。 - 在表达式中,作为二元运算符时,表示按位与运算,例如:`int c = a & b;`(表示将a和b的每一位进行与运算)。 注意:同一个符号在不同上下文中含义不同,需要根据具体位置判断。 下面我们分别举例说明: ### 1. `>` 运算符示例 ```cpp // 大于比较 if (a > b) { // 当a大于b时执行 } // 右移运算符 int a = 16; // 二进制10000 int b = a >> 2; // 结果为4(二进制100) // 流提取运算符 int x; std::cin >> x; // 从标准输入读取一个整数到x // 在模板中使用(C++11以后) std::vector<std::vector<int>> matrix; // 二维整型向量 ``` ### 2. `&` 运算符示例 ```cpp // 引用声明 int x = 10; int& ref = x; // ref是x的引用,修改ref等于修改x // 取地址运算符 int* p = &x; // 将x的地址赋给指针p // 按位与运算 int a = 5; // 二进制101 int b = 3; // 二进制011 int c = a & b; // 结果为1(二进制001) ``` 注意事项: - 在C++11之前,模板嵌套时两个连续大于号必须用空格分开,例如:`std::vector<std::vector<int> >`,以避免编译器误认为是`>>`运算符。 - 引用和指针不同,引用必须在声明时初始化,并且不能改变引用的对象;而指针可以重新指向不同的地址。 希望上述解释能帮助理解这两个符号在C++中的不同含义。 如果用户有进一步的问题,可以提出。 根据要求,我们生成相关问题: §§相关问题§§ 1. 在C++中,如何区分引用声明符(`&`)和取地址运算符(`&`)? 2. 右移运算符(`>>`)和流提取运算符(`>>`)在编译器处理时有何区别? 3. C++11标准对于模板嵌套中使用`>>`做了哪些改进? 4. 按位与运算符(`&`)和逻辑与运算符(`&&`)有什么不同? </think> 在 C++ 代码中,`>` 和 `&` 符号在不同上下文中有特定含义,以下是详细解释: ### 1. `>` 符号的含义 | **应用场景** | **含义** | **示例** | |-----------------------|--------------------------------------------------------------------------|--------------------------------| | **单独使用** | 关系运算符(大于) | `if (a > b) { ... }` | | **双符号 `>>`** | 右移运算符(位操作)<br>或流提取运算符(I/O操作) | `x = y >> 2;`<br>`cin >> x;` | | **模板嵌套** | 模板参数结束符(C++11 前需加空格) | `vector<vector<int> >` | ### 2. `&` 符号的含义 | **应用场景** | **含义** | **示例** | |-----------------------|--------------------------------------------------------------------------|--------------------------------| | **声明语句** | 声明引用变量(别名) | `int& ref = x;` | | **表达式** | 取地址运算符 | `int* p = &x;` | | **位操作** | 按位与运算符 | `z = x & 0xFF;` | | **函数参数** | 引用传递(避免拷贝) | `void func(const string& s)` | ### 关键区别说明 1. **上下文决定性**: - `&` 在变量声明中表示引用,在表达式中表示取地址 - `>` 单独出现是比较运算符,双写 `>>` 是位操作或 I/O 操作符 2. **典型用例对比**: ```cpp int a = 10; int& b = a; // & 声明引用(b是a的别名) int* c = &a; // & 取地址操作(c指向a的地址) if (a > 5) { // > 比较运算 cout << (a >> 1); // >> 右移运算(输出5) } ``` 3. **特殊场景**: - 引用与指针:引用是编译时别名(不能为空),指针存储地址(可重定向) ```cpp int x = 5; int& r = x; // r 始终指向 x int* p = &x; // p 可改为指向其他变量 ``` - 位操作应用: ```cpp // 检查奇偶性(最低位与1相与) bool isOdd = (num & 1); ``` ### 语法注意事项 1. C++11 后模板嵌套允许连续 `>>`: ```cpp vector<vector<int>> matrix; // 合法(C++11+) ``` 2. 引用初始化规则: ```cpp int x = 10; int& r1 = x; // ✓ 正确 int& r2 = 20; // ✗ 错误:不能绑定字面值 ``` ### 常见错误示例 ```cpp double* p = &3.14; // ✗ 错误:字面值无地址 int& ref; // ✗ 错误:引用必须初始化 if (x >> 2) {...} // ✗ 语义错误:应是 x>2 而非右移 ``` > 这些符号的含义取决于上下文位置,编译器会根据语法规则进行解析[^1][^3]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值