02-c提高01day

目录

一、目的

1、想多学习C知识

二、参考

1、(01)某马C++24期完整版

三、操作:一:01 typedef用法

1、总结:c语言中“#if 0 / #if 1 ... #endif”的作用:

1、总结:typedef用法

1、总结:typeid

1、(成功)运行效果:

四、操作:二:sizeof用法

1、(成功)int占用空间大小:4字节

1、(成功)double:占用空间8字节(int的2倍);char占用1字节;

1、(成功)struct:只有char时候,struct占用1字节空间

1、(成功)struct:只有int时候,struct占用4字节空间

1、(疑问-已解决)struct同时有int和char时候,占用8字节空间;这是为什么呢?

答:①、原来struct会多分配空间,允许你浪费

五、操作:三:栈区

1、(成功)栈区的内存自动申请释放、不需要程序手动管理+我们并不关心值是多少,因为局部变量a的内存已经被回收

2、(失败-未解决)printf输出乱码

①出现问题:printf乱码

①解决方法:一:失败:添加了\0还是不行

①解决方法:二:失败:修改编码,改为UTF-8:

①解决方法:三:失败:使用cout输出

六、操作:四:堆区

1、测试1(成功)堆的内存成员手动申请,手动释放+只要是连续的内存空间,都能使用下标的方式访问内存

①运行结果

2、测试2(失败-未解决-有自己的理解):

①运行结果:疑问:为什么这个可以输出内容是空

①为什么为空:理解1:因为test02函数中设置了一个char *p是空的,然后传递到了allocateSpace函数中,实参变为形参,此时的形参操作和test02函数中的实参char*p就没有关系了,

①为什么为空:理解2:验证理解1:所以我直接不运行allocateSpace函数了,输出还是空,因此我传递给allocate里面实参后,就和test02里面的char *p没有关系了,

3、测试3(成功-有自己的理解):二次指针

①运行结果:疑问:为什么这个和测试2不一样,输出内容不是空

①为什么不为空:理解1:因为test03函数时候将char *p的地址传递给allocateSpace02函数,allocateSpace02函数是对char *p的地址进行操作(别看是二级指针,其实就是对char *p地址的操作),所以只有test03函数生命周期结束后,才会清除char *p

七、操作:五:全局静态区

1、默认外部链接

1、全局区

1、静态全局变量是内部链接

1、内部链接和外部链接有什么区别?

1、全局静态变量和局部静态变量的区别?

1、测试1:静态区

1、头文件不要放定义,只能放声明

1、头文件不能参与编译,每一个.c文件,我们叫做一个编译单元;编译器独立编译每一个.c文件

1、静态区:

1、(失败-按照课程源码编写也是报错,不知道是什么情况)测试2:

①运行效果+自己代码

①课程源码


一、目的

1、想多学习C知识

 

二、参考

1、(01)某马C++24期完整版

 

三、操作:一:01 typedef用法

1、总结:c语言中“#if 0 / #if 1 ... #endif”的作用:

(1)code中定义的是一些调试版本的代码,此时code完全被编译器忽略。如果想让code生效,只需把#if 0改成#if 1 

(2)#if 0还有一个重要的用途就是用来当成注释,如果你想要注释的程序很长,这个时候#if 0是最好的,保证不会犯错误。
(但是林锐的书上说千万不要把#if 0 来当作块注释使用) #if 1可以让其间的变量成为局部变量。 

(3)这个结构表示你先前写好的code,现在用不上了,又不想删除,就用这个方法,比注释方便。

 

1、总结:typedef用法

typedef是在计算机编程语言中用来为复杂的声明定义简单的别名,它与宏定义有些差异。
它本身是一种存储类的关键字,与auto、extern、mutable、static、register等关键字不能出现在同一个表达式中。

 

1、总结:typeid

在c++中,typeid用于返回指针或引用所指对象的实际类型。

 

1、(成功)运行效果:


#include <iostream>

using namespace std;

/*
c语言中“#if 0 / #if 1 ... #endif”的作用:
(1)code中定义的是一些调试版本的代码,此时code完全被编译器忽略。如果想让code生效,只需把#if 0改成#if 1 

(2)#if 0还有一个重要的用途就是用来当成注释,如果你想要注释的程序很长,这个时候#if 0是最好的,保证不会犯错误。
(但是林锐的书上说千万不要把#if 0 来当作块注释使用) #if 1可以让其间的变量成为局部变量。 

(3)这个结构表示你先前写好的code,现在用不上了,又不想删除,就用这个方法,比注释方便。
*/

#if 0
struct Person 
{
	char name[64];
	int age;
};
/*
typedef是在计算机编程语言中用来为复杂的声明定义简单的别名,它与宏定义有些差异。
它本身是一种存储类的关键字,与auto、extern、mutable、static、register等关键字不能出现在同一个表达式中。
*/

typedef struct Persion myPersion;
#endif

typedef struct Person 
{
	char name[64];
	int age;
} myPerson;

void test01()
{
	myPerson p;
}

typedef char * PCHAR;

void test02()
{
	char *p1, *p2;

	//在c++中,typeid用于返回指针或引用所指对象的实际类型。
	cout << typeid(p1).name() << endl;
	cout << typeid(p2).name() << endl;
}

typedef int mytype_t;

//有利于程序的移植性
void test03()
{
	mytype_t a;
}

int main()
{
	//test01();
	test02();
	//test03();

	system("pause");
	return EXIT_SUCCESS;
}

 

四、操作:二:sizeof用法

1、(成功)int占用空间大小:4字节

1、(成功)double:占用空间8字节(int的2倍);char占用1字节;

1、(成功)struct:只有char时候,struct占用1字节空间

1、(成功)struct:只有int时候,struct占用4字节空间

 

1、(疑问-已解决)struct同时有int和char时候,占用8字节空间;这是为什么呢?

答:①、原来struct会多分配空间,允许你浪费

 

五、操作:三:栈区

1、(成功)栈区的内存自动申请释放、不需要程序手动管理+我们并不关心值是多少,因为局部变量a的内存已经被回收

 

2、(失败-未解决)printf输出乱码

①出现问题:printf乱码

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
char *getString()
{
	char str[] = "hello world!";

	return str;
}

void test02()
{
	char *s = NULL;

	s = getString();

	printf("s = %s\n", s);
}
int main()
{
	//Test01();
	test02();
	system("pause");
	return EXIT_SUCCESS;
}

①解决方法:一:失败:添加了\0还是不行

①解决方法:二:失败:修改编码,改为UTF-8:

①解决方法:三:失败:使用cout输出

 

六、操作:四:堆区

1、测试1(成功)堆的内存成员手动申请,手动释放+只要是连续的内存空间,都能使用下标的方式访问内存

①运行结果

#include <iostream>
#include <stdlib.h>
#include <stdio.h>
using namespace std;
//1、堆的内存成员手动申请,手动释放
int * getSpace()
{
	int *p = (int *)malloc(sizeof(int) * 5);
	if (NULL==p)
	{
		return NULL;
	}
	int j = 0;
	//只要是连续的内存空间,都能使用下标的方式访问内存
	for (int i = 0; i < 5;i++)
	{
		p[i] = 100 + i;
	}
	return p;
}

void test01()
{
	int *ret = getSpace();
	for (int i = 0; i < 5;++i)
	{
		printf("%d\n", ret[i]);
	}
	//用完堆内存,一定要释放
	free(ret);
	ret = NULL;
}

int main()
{
	test01();

	system("pause");
	return EXIT_SUCCESS;
}

 

2、测试2(失败-未解决-有自己的理解):

①运行结果:疑问:为什么这个可以输出内容是空

  • memset是计算机中C/C++语言初始化函数。作用是将某一块内存中的内容全部设置为指定的值, 这个函数通常为新申请的内存做初始化工作。
  • strcpy,即string copy(字符串复制)的缩写。strcpy是一种C语言的标准库函数,strcpy把含有'\0'结束符的字符串复制到另一个地址空间,返回值的类型为char*。

#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <stdlib.h>
#include <stdio.h>
using namespace std;
//2、定义变量的时候一定要初始化,很多的Bug产生都是由于没有初始化造成的
/*
memset:
memset是计算机中C/C++语言初始化函数。
作用是将某一块内存中的内容全部设置为指定的值, 这个函数通常为新申请的内存做初始化工作。
*/
/*
strcpy:
strcpy,即string copy(字符串复制)的缩写。
strcpy是一种C语言的标准库函数,strcpy把含有'\0'结束符的字符串复制到另一个地址空间,返回值的类型为char*。
*/
void allocateSpace(char *p)
{
	p =(char *) malloc(100);
	memset(p, 0, 100);
	strcpy(p, "hellow world!\0");
}

void test02()
{
	char *p = NULL;
	allocateSpace(p);
	printf("p=%s\n", p);
}

int main()
{
	//test01();
	test02();
	system("pause");
	return EXIT_SUCCESS;
}

①为什么为空:理解1:因为test02函数中设置了一个char *p是空的,然后传递到了allocateSpace函数中,实参变为形参,此时的形参操作和test02函数中的实参char*p就没有关系了,

①为什么为空:理解2:验证理解1:所以我直接不运行allocateSpace函数了,输出还是空,因此我传递给allocate里面实参后,就和test02里面的char *p没有关系了,

 

 

3、测试3(成功-有自己的理解):二次指针

①运行结果:疑问:为什么这个和测试2不一样,输出内容不是空

#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <stdlib.h>
#include <stdio.h>
using namespace std;
//测试3:
void allocateSpace02(char **p)
{
	char *temp = (char *)malloc(100);
	memset(temp, 0, 100);
	strcpy(temp, "hellow world!");
	*p = temp;
}

void test03()
{
	char *p = NULL;
	allocateSpace02(&p);
	printf("p=%s\n", p);
}

int main()
{
	//test01();
	//test02();
	test03();
	system("pause");
	return EXIT_SUCCESS;
}

①为什么不为空:理解1:因为test03函数时候将char *p的地址传递给allocateSpace02函数,allocateSpace02函数是对char *p的地址进行操作(别看是二级指针,其实就是对char *p地址的操作),所以只有test03函数生命周期结束后,才会清除char *p

 

七、操作:五:全局静态区

1、默认外部链接

 

1、全局区

 

1、静态全局变量是内部链接

 

1、内部链接和外部链接有什么区别?

  • 1、如果变量是内部链接的话,那么此变量只能在当前文件夹内被访问
  • 2、如果变量是外部链接的话,那么此变量可以被其他文件使用

 

1、全局静态变量和局部静态变量的区别?

  • 1、全局静态变量和局部静态变量都存储在静态区,都是在程序运行期间都是合法有效
  • 2、局部静态变量符号的可见范围仅限于当前函数内部,全局静态变量可见范围从定义到文件结尾
     

1、测试1:静态区

void test01()
{
	static int c = 30;//静态区
}

1、头文件不要放定义,只能放声明

 

1、头文件不能参与编译,每一个.c文件,我们叫做一个编译单元;编译器独立编译每一个.c文件

 

1、静态区:

①局部静态变量

 

1、(失败-按照课程源码编写也是报错,不知道是什么情况)测试2:

①运行效果+自己代码

#define _CR_SECURE_NO_WARNINGS
#include <stdlib.h>
#include <iostream>
#include <stdio.h>
#include <string.h>

extern int a=10;//默认外部链接
int a = 10;//全局区

//静态全局变量是内部链接
static int b = 20;//静态区

//头文件不能参与编译,每一个.c文件,我们叫做一个编译单元
//编译器独立编译每一个.c文件
void test02()
{
	//声明,表示告诉编译器这个符号是存在的,你让我先编译通过,让连接器去找到底这个符号在哪
	extern int g_a;
	printf("g_a=%d\n", g_a);
}

int main()
{
	//test01();
	test02();
	system("pause");
	return EXIT_SUCCESS;
}

 

①课程源码

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>


//extern int a = 10; 默认外部链接
int a = 10; //全局区
//静态全局变量是内部链接
static int b = 20; //静态区

//内部链接和外部链接有什么区别?
//1. 如果变量是内部链接的话,那么此变量只能在当前文件内访问
//2. 如果是变量是外部链接的话,那么此变量可以被其他文件使用


//1. 全局静态变量和局部静态变量都存储在静态区,都是在程序运行期间都是合法有效
//2. 局部静态变量符号的可见范围仅限于当前函数内部,全局静态变量可见范围从定义到文件结尾

//头文件不要放定义,只能放声明

void test01()
{
	static int c = 30; //静态区
}

//头文件不参与编译,每一个.c文件,我们叫做一个编译单元
//编译器独立编译每一个.c文件
void test02()
{
	//声明,表示告诉编译器这个符号是存在的,你让我先编译通过,让连接器去找到底这个符号在那
	extern int g_a;

	printf("g_a = %d\n", g_a);
}



int main(){

	test02();

	system("pause");
	return EXIT_SUCCESS;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值