IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C语言 第八周知识点随记 -> 正文阅读

[C++知识库]C语言 第八周知识点随记

指针

sizeof

  • 是一个运算符,给出某个类型或变量在内存中所占据的字节数
  • sizeof(int)
  • sizeof(double)
  • sizeof(i)
    一个int占据的是4个字节,一个double占据的是8个字节

取地址符 &

  • scanf("%d", &i);里面的&
  • 获得变量的地址,它的操作数必须是变量
    • int i ; printf("%x", &i); 获取i的地址,以16进制整数输出
  • 地址的大小是否与int相同取决于编译器
    • int i; printf("%p", &i); 获取i的地址,以地址(32/64位)输出

&不能取的地址

  • &不能对没有地址的东西取地址
    • &(a+b)
    • &(a++)
    • &(++a)

数组的地址

int a[10];

//假设a存放的地址为00000001
printf("%p\n", &a);	//输出的为数组a存放的地址 00000001
printf("%p\n", a);	//输出的为数组a存放的地址 00000001
printf("%p\n", a[0]);	//输出的为数组a中第一个单元a[0]存放的地址 00000001
printf("%p\n", a[1]);	//输出的为数组a中第二个单元a[1]存放的地址 00000005

指针变量 *p

  • 就是保存地址的变量
	int i;
	int \*p = &i;	//把i的地址给*p
	int\* p, q;	//定义一个变量*p,一个整型变量q
	int *p, q;	//同上

作为参数的指针

  • void f(int *p);
  • 在被调用的时候得到了某个变量的地址;
    • int i = 0; f(&i);
  • 在函数里面可以通过这个指针访问外面的这个i

访问某个地址上的变量

  • *是一个单目运算符,用来访问指针的值所表示的地址上的变量
  • 可以做右值也可以做左值
    • int k = *p;
    • *p = k +1;
void f(int *p);
void g(int k);

int main(void)
{
	int i = 6;	//输入一个整形变量为6
	printf("&i=%p\n", &i);	//读取i的地址,以变量地址的格式输出
	f(&i);	//根据i的地址,给出指针地址即其所指向的值
	g(i);	//用函数将i输出

	return 0;
}

void f(int *p)
{
	printf("p=%p\n",p);	//地址
	printf("*p=%d\n", *p);	//地址所指的值
	*p = 26;	//把p指针所指单元即i的值变为26(在函数中也可以访问函数外的i)
}

void g(int k)
{
	printf("k=%d\n",k);	//i的值
}

传入地址
为什么int i; scanf("%d",i);编译没有报错?

因为scanf会把i单做一个地址,它访问的是地址为i的内存单元。

传入函数的数组成了什么?

  • 函数参数表中的数组实际上是指针
  • sizeof(a) == sizeof(int*)
  • 但是可以用数组的运算符[]进行运算

因此以下四种函数原型是等价的

  • int sum(int *ar, int n);
  • int sum(int *, int);
  • int sum(int ar[], int n);
  • int sum(int [], int);

数组变量是特殊的指针

  • 数组变量本身表达地址,因此int a[10]; int *p=a //无需用&取地址变量
  • 但是数组单元表达的是变量,需要用&取地址
    • a == &a[0]
  • [] 运算符可以对数组做,也可以对指针做:
    • p[0] <==> a[0]
  • *运算符可以对指针做,也可以对数组做;
    • *a = 25;
  • 数组变量是地址为const的指针,所以不能被赋值
    int b[] --> int * const b
    // const b 是一个常数,不能被改变
    * const b 是常量指针
    不能做 int b[] = a
    

指针初始化
在学习过程中,我发现一个问题

int *p = &i; 	//可编译,并且让指针p指向i所在单元
int *p;
int i;
*p = i;	//编译报错
  • 疑问
    *p 是一个地址所指向的内容,&i是i这个变量所在的地址,这两个不同的东西怎么能做赋值?
  • 我的理解
    我的理解是:定义一个指针后必须进行初始化。初始定义指针变量的时候既要定义数据类型,要给他定义这个指针指在哪里,直接融在一起了。就成了int *p=&i。实际上应该拆成定义一个指针 int *p,这个指针是i所在的地址即p=&i。
  • 看了一些大佬的博客
    关于int*p=&a与int p;p=&a;与p = a;与&p的解惑
    根据大佬的博客,知道了指针初始化可以分为2种
  1. 定义时直接初始化
  2. 定义之后进行初始化

若在定义之后,没有初始化,对指针赋值,编译器会报错。由于int *p后,p指向的是一个随机的地址,那么这个地址上储存的值也是随机的,我们不能随意修改其值。否则有可能会造成系统紊乱。

字符

字符类型

  • char是一种整数,也是一种特殊的类型:字符。
  • 用单引号表示的字符字面量:'a', '1'
  • ''也是一个字符
  • printf和scanf里用%c来输入输出字符

逃逸字符

  • 用来表达无法印出来的控制字符或特殊字符,它由一个反斜杠“\”开头,后面跟上另一个字符,这两个字符合起来,组成了一个字符
printf("请分别输入身高的英尺和英寸,如输入\"5 7\"表示5英寸和7英寸:");

逃逸字符表

字符意义
\b回退一格
\t到下一个表格位
\n换行
\r回车
\"双引号
单引号
\反斜杠本身

回退:让下一个输出回到\b前一个的前面一个位置上去。如果不输出东西,结果不会影响;如果输出东西,\b之前输出的前一个会被盖掉。

shell
我们写的程序运行的时候有一个黑色的窗口,这个窗口也是别人写的程序,我们通常叫做shell。
不同的shell会对不同的控制字符做出特殊的反应。

字符串

字符串
字符串是一个字符数组。
“Hello”会被编译器变成一个字符数组放在某处,这个数组的长度是6,结尾还有表示结束的0。

  • 字符串以数组的形式存在,以数组或指针的形式访问
  • 更多的是以指针的形式
  • string.h里有很多处理字符串的函数

字符数组
char word[] = {‘H’, ‘e’, ‘l’, ‘l’, ‘o’, ‘!’, ‘\0’ };
hello数组
6个字符,数组总共由7个单元。

  • 以0(整数0)结尾的字符串

  • 0'\0'是一样的,但是和’0‘不同

  • 0标志字符串的结束,但它不是字符串的一部分

  • 计算字符串长度的时候不包含这个0

  • C语言的字符串是以字符数组的形态存在的

    • 不能通过运算符对字符串做运算
    • 可以通过数组的方式遍历字符串
    • 唯一特殊的地方是字符串字面量可以用来初始化字符数组

字符串常量

  • “Hello”
  • "Hello"会被编译器变成一个字符数组放在某处,这个数组的长度是6,还有表示结束的0
  • 两个相邻的字符串常量会被自动连接起来

字符串变量
char *str = “Hello”;
char word[] = “Hello”;
char line[10] = “Hello”;

char* s = “Hello, world!”;
s是一个指针,初始化为指向一个字符串常量
由于这个常量所在的地方,所以实际上s是const char * s, 但是由于历史的原因,编译器接受不带cosnt的写法
但是试图对s所指的字符串做写入会导致严重的后果
如果需要修改字符串,应该用数组:
char s[] = “Hello, world!”;

指针还是数组?

  • char *str = “Hello”;
  • 指针:这个字符串不知道在哪里
    • 处理参数
    • 动态分配空间
  • char word[] = “Hello”;
  • 数组:这个字符串在这里
    • 作为本地变量空间自动被回收
  • 如果要构造一个字符串 ——>数组
  • 如果要处理一个字符串 ——>指针

*char 是字符串吗?

  • 字符串可以表达为char *的形式
  • char*不一定是字符串
    • 本意是指向字符的指针,可能指向的是字符的数组(就像int*一样)
    • 只有它所指的字符数组有结尾的0,才能说它所指的是字符串

字符串计算

字符串赋值

  • char *t = “title”;
  • char *s;
  • s = t;
  • 并没有产生新的字符串,只是让指针s指向了t所指的字符串,对s的任何操作就是对t做的

字符串输入输出

- char string[8];
- scanf("%s",string);
- printf("%s",string);

写两个程序来测试一下

#include<stdio.h>
int main()
{
	char word[8];
	scanf("%s", word);
	printf("%s##", word);
	
	return 0;
}

在这个程序中,输入“Hello world!”,输出的结果只有Hello。原因是scanf读一个字符串,只能读到空格或者回车为止。

#include<stdio.h>
int main()
{
	char word[8];
	char word2[8];
	scanf("%s", word);
	scanf("%s", word2);
	printf("%s##%s##", word, word2);
	return 0;
}

在这个程序中,输入“Hello world!”,输出的结果是:Hello##world!##,即在word输入的是“Hello”,在word2种输入的是“world!”。

  • scanf读入一个单词(到空格、tab或回车为止)
  • scanf是不安全的,因为不知道读入的内容的长度

为了使scanf读入的内容放在字符数组中不越界,可以在%后加入要读入的字符数。如scanf("%7s", word);表示最多读入7个字符,小于7个字符是可以的。

#include<stdio.h>
int main()
{
	char word[8];
	char word2[8];
	scanf("%7s", word);
	scanf("%7s", word2);
	printf("%s##%s##", word, word2);
	return 0;
}
  1. 若输入123 12345678,输出结果为123##1234567##
  2. 若输入12345678,输出结果为1234567##8##
  • 在%和s之间的数字表示最多允许读入的字符的数量,这个数字应该比数组的大小小1

空字符串

  • char buffer[100] = “”;
    • 这是一个空的字符串,buffer[0] = = ‘\0’
  • char buffer[] = “”;
    -这个数组的长度只有1!

字符串函数

strlen

  • size_t strlen(const char *s);
  • 返回s的字符串长度(不包括结尾的0)

strcmp

  • int strcmp(const char *s1, const char *s2);
  • 比较两个字符串,返回:
    • 0:s1 == s2
    • 1:s1 > s2
    • -1:s1 < s2
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-10-08 20:22:12  更:2022-10-08 20:26:48 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 8:02:19-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码