CPP和C学习笔记

20180926 12:37

gcc和g++的区别:GCC就代表 the GNU Compiler Collection,所以表示一堆编译器的合集。 g++则是GCC的c++编译器。https://www.zhihu.com/question/20940822

今天看到C语言的一段代码

1
2
3
4
5
6
7
8
9
#include<stdio.h>
int main(int argc, char* argv[]) {
if(argv == 0) return;
printString(argv);
return 0;
}
int printString(char* string) {
sprintf(string, "This is a test.\n");
}

这里为什么char* []类型可以转化为char*类型,于是一通研究,我在eclipse中写个类似的代码,点击运行,又报出了Error with command: gdb --version这个错误,去网上搜索,看到这篇文章https://www.jianshu.com/p/ce2d77d7d1c4,我还没有研究。我只是初次的调用brew install gdb,发现brew卡在了Updating Homebrew...这一步不动了,这又是为什么呢?
lisp qq群内有给出意见

知了就是知了 17:03:46
“ 舟亢 17:00:44
我是在研究C语言中char[] 转化为char的技术 “
c函数不支持传数组, 所以[]参数会自动转成 *, 除非数组放着struct里面
Gilgamish 17:04:21
C的数组在传递的过程中会退化成指针

关于brew update卡住的问题,网上有人说更换一下brew的源就可以了,不过我还没有试,暂时先不管它。
按照网上教程,我用brew下载了gdb之后,同时也给gdb配置了证书。这个时候debug C代码时,eclipse提示Failed to execute MI command:。我只是想写个c程序然后调试,但是eclipse配置不给力,还要google一大堆贴文,于是我武断地放弃eclipse,用xcode写c程序调试吧,不要忘了我的初衷只是调试c程序(而不是学习如何配置和使用eclipse)。

回到上边最初的问题,为什么char* []类型可以转化为char*类型。大概是这么理解的。

杨锋 2018/09/27 下午12:05
char * argv[] 是说argv是一个数组,数组每个元素是char*(其实应是一串char)

孙航 2018/09/27 下午12:07
扫噶

孙航 2018/09/27 下午12:07
扫戴斯乃

孙航 2018/09/27 下午12:09
总结一下是:char * argv[] 是指针数组,char*是个char类型的指针,上面小程序是,把指针数组的地址赋值给了char类型的指针

杨锋 2018/09/27 下午12:10
argv这个数组名的含义你了解了就好了。它是指向内存中这堆char的第一个char的地址,类型为数组类型,数组元素类型是char*指针类型。这句能理解吗?

孙航 2018/09/27 下午12:11
确认能理解

杨锋 2018/09/27 下午12:13
程序里调用函数的时候,把这个地址做为参数传进去,printString函数的参数名string指到这个地址

杨锋 2018/09/27 下午12:15
然后函数里把这个地址开始往后按照char*指针来用了。

孙航 2018/09/27 下午12:15
锋哥讲的,整个过程大脑里过了一遍

孙航 2018/09/27 下午12:16
确实想通了

但是后来我调试后想了下,argv它是指向内存中这堆char*的第一个的地址,类型为数组类型,数组元素类型是char*指针类型,而每个char*又指向一堆char。如果调用上述的sprintf,那么argv所指向的指针数组里的值会发生改变。
cpointerconvert

20180831 11:13

在网上看到了如下代码,那么friend ostream& operator<<(ostream &os, Complex const &that)是怎么理解呢?
Complex const &that中的const怎么理解呢?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Complex
{
public:
Complex(double r = 0, double i = 0) :m_r(r), m_i(i){}
friend ostream& operator<<(ostream &os, Complex const &that)
{
return os << that.m_r << "+"<<that.m_i << "i" ;
}
Complex(Complex const &that) :m_r(that.m_r), m_i(that.m_i)
{
cout << "拷贝构造函数" << &that << "->" << this << endl;
}
private:
double m_r, m_i;
};

20180831

C++中include时,有的带.h,有的不带,我上网查了一下原因。
统一C++各种后缀名,如.h、.hpp、.hxx等。标准化之前的头文件就是带后缀名的文
件,标准化后的头文件就是不带后缀名的文件。C++ 98 规定用户应使用新版头文件,对旧
版本头文件不在进行强制规范,但大多数编译器厂商依然提供旧版本头文件,以求向下兼
容。

另外,为了和C语言兼容,C++标准化过程中,原有C语言头文件标准化后,头文件名前带个
c字母,如cstdio、cstring、ctime、ctype等等

我们如果要用C++标准化了的C语言头文件,就得作如下的转换
#include <stdio.h> --> #include <cstdio>

C中
<.h>表示优先中系统目录中查找 该头文件 比如#include <stdio.h> 这是系统中的
.h”表示优先从当前目录中查找 该头文件 比如#include “head.h” 这是你自己写的

20180830 const char ptr、char const ptr、char * const ptr

const char ptr是指针指向的内容不可以更改;
char const
ptr同上;
char* const ptr是指针本身不可更改指向别的内容

20180830 C++移动语义

在尝试了解C++移动语义时,看到两篇帖子,感觉不错,日后好好看看
https://codinfox.github.io/dev/2014/06/03/move-semantic-perfect-forward/
https://www.zhihu.com/question/55936870
在看其中第一篇文章时,看到有C++11的“列表初始化”语法,我觉得需要研究一下列表初始化语法的含义

20180817 C++的模板

  • C++的模板类可以声明在头文件,定义也可以在头文件中;
  • 若定义不放到头文件中,需要创建一个tpp文件,定义放进去,然后在模板的头文件的末尾include这个tpp文件;
  • 若定义不放到头文件中,也可以在使用该模板的地方,显示声明模板类,比如template class A等;

20180813 C++的auto和decltype的学习

20180628

在C++的函数名后面有个const,在kotlin中也有const,那么它们分别的意义是什么呢?首先看一下kotlin中的const,https://www.cnblogs.com/liuliqianxiao/p/7253116.html这篇文章讲述了kotlin中的const,非常清晰。那么什么是C++函数名后面加const呢,比如

1
void func const{}

看到一篇文章上说,“若将类成员函数声明为const,则该函数不允许修改类的数据成员”

20180607

C++的语言有一些很怪异的,不知道为什么委员会要这么设计,比如函数指针void (*ptr) (void),比如函数指针数组void (*ptr[]) (void),还有C11中的_Generic泛型,

1
2
3
4
5
#define cbrt(X) _Generic((X), \
long double: cbrtl, \
default: cbrt, \
float: cbrtf \
)(X)

为什么(X)是一个assignment expression呢,或者为什么它是个controlling expression呢?