文档章节

C和指针---第六章:指针

fzyz_sb
 fzyz_sb
发布于 2013/09/14 21:36
字数 1124
阅读 214
收藏 2
点赞 0
评论 0

6.1 内存和地址

1. 内存中的每个位置由一个独一无二的地址标识

2. 内存中的每个位置都包含一个值。

6.2 值和类型

我们不能通过检查一个值的位来判断它的类型。我们要看这个值如何被解释。

6.3 指针变量的内容

int a = 1;
int b = 2;
int *c = &a;
int *d = &b;
则c存储的是a的地址,d存储的是b的地址。

变量的值就是分配给该变量的内存位置所存储的数值。

6.6 NULL指针

NULL作为一个特殊的指针变量,表示不指向任何东西。要使一个指针变量为NULL,给它赋值0即可。

备注:

int a = 2;
int *b = &a;
中,指针变量指的是b,而不是*b,这点非常重要。

6.9 指针常量

假定变量a存储于位置100,则

*100 = 25;
的意思是把25赋值给a吗?实际上这条语句是非法的,因为字面值100的类型是整型,而间接访问操作只能作用于指针类型表达式。如果确定要把25存储于位置100,我们必须进行强制类型转换:
*(int *)100 = 25;
6.10 指针的指针
int a = 12;
int *b = &a;
int **c = &b;
c的类型是:指向整型的指针的指针。

6.12 实例

1. 字符串长度

#include <stdlib.h>

size_t strlen(char *string)
{
	int length = 0;
	while ( *string++ != '\0' ){
		length += 1;
	}

	return length;
}
2. 在字符串指针数组中进行单一字符的查找:
#include <stdio.h>

int find_char( char **strings, char value ){
	char *string = NULL;

	while ( ( string = *strings++ ) != NULL ){
		while ( *string != '\0' ){
			if ( *string++ == value ){
				return 1;
			}
		}
	}

	return 0;
}

int main(void)
{
	char *string1 = "hello";
	char *string2 = "world";
	char *string3 = "python";
	char *str[3] = {string1, string2, string3};
	char **strings = str;
	if (find_char(strings, 't')){
		printf("find it\n");
	}
	else{
		printf("not find it\n");
	}

	return 0;
}
3. 字符串查找的第二版本:
#include <stdio.h>
#include <assert.h>

int find_char( char **strings, char value ){
	assert( strings != NULL );

	while ( *strings != NULL ){
		while ( **strings != '\0' ){
			if ( *( *strings )++ == value){
				return 1;
			}
		}
		strings++;
	}

	return 0;
}

int main(void)
{
	char *string1 = "hello";
	char *string2 = "world";
	char *string3 = "python";
	char *str[3] = {string1, string2, string3};
	char **strings = str;
	if (find_char(strings, 't')){
		printf("find it\n");
	}
	else{
		printf("not find it\n");
	}

	return 0;
}
6.13 指针运算

例子:清除一个数组中的所有元素

1. 正向

#define N_VALUES 5
float	values[N_VALUES];
float	*vp = NULL;

for ( vp = &values[0]; vp < &values[N_VALUES]; ){
	*vp++ = 0;
}

2. 反向

#define N_VALUES 5
float	values[N_VALUES];
float	*vp = NULL;

for ( vp = &values[N_VALUES]; vp > &values[0]; ){
	*--vp = 0;
}
3. 有点错误的:
#define N_VALUES 5
float	values[N_VALUES];
float	*vp = NULL;

for ( vp = &values[N_VALUES - 1]; vp >= &values[0]; vp-- ){
	*vp = 0;
}
因为:标准允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针进行比较,但不允许与指向数组第一个元素之前的那个内存位置的指针进行比较。

习题:

1. 

#include <stdio.h>

char *find_char( char const *source, char const *chars){
	char *temp = NULL;
	while ( *chars++ != '\0' ){
		temp = source;
		while ( *source++ != '\0' ){
			if ( *chars == *source ){
				return source;
			}
		}
		source = temp;
	}

	return NULL;
}

int main(void)
{
	char *source = "abcdef";
	char *chars = "xrcqef";
	printf("%s\n", find_char( source, chars ));

	return 0;
}

程序输出:

2. 

#include <stdio.h>

int del_substr( char *str, char const *substr ){
	char *temp = NULL;
	while ( *str != NULL){
		while ( *str != *substr){
			str++;
		}
		temp = str;
		while ( ( *str != NULL ) && ( *str == *substr ) ){	//不要写 ( *str++ == *substr++ ),这样会导致'\0'也被判断过
			str++;
			substr++;
		}
		if ( NULL == *substr ){
			while ( *temp++ = *str++ ){
				;
			}
			*temp = '\0';
			return 1;
		}
	}

	return 0;
}

int main(void)
{
	char str[8] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', '\0'};
	char substr[4] = {'c', 'd', 'e', '\0'};
	if ( del_substr( str, substr ) ){
		printf("%s\n", str);
	}

	return 0;
}

程序输出:

3. 不知道如何反转字符串,在用指针的情况下。看了下答案后,发现自己把问题想复杂了:

#include <stdio.h>

void reverse_string( char *str )
{
	char *last_char;

	for ( last_char = str; *last_char != '\0'; last_char++ ){
		;
	}

	last_char--;

	while ( str < last_char ){
		char temp;

		temp = *str;
		*str++ = *last_char;
		*last_char-- = temp;
	}
}

int main(void)
{
	char str[6] = {'h', 'e', 'l', 'l', 'o', '\0'};
	reverse_string(str);
	printf("%s\n", str);

	return 0;
}
城西输出:

4.

#include <stdio.h>
#include <stdlib.h>

#define MAXLINE 1000

int main(void)
{
	int arr[MAXLINE];
	int i = 0;
	int j = 0;
	for ( i = 0; i < MAXLINE; i++ ){
		if ( !( i % 2 ) && ( 2 != i ) || ( i == 1 ) ){
			arr[i] = 0;
		}
		else{
			arr[i] = 1;
		}
	}
	for ( i = 3; i < MAXLINE / 2; i++ ){
		if ( !arr[i] ){
			continue;
		}
		for ( j = 2 * i; j < MAXLINE; j += i ){
			arr[j] = 0;
		}
	}
	for ( i = 0; i < MAXLINE; i++ ){
		if ( arr[i] ){
			printf("%d ", i);
		}
	}

	return 0;
}

程序输出:

6. 

#include <stdio.h>
#include <stdlib.h>


int primeNumCount(int arr[], int len){
	int count = 0;
	int i = 0;
	int j = 0;
	for ( i = 0; i < len; i++ ){
		if ( !( i % 2 ) && ( 2 != i ) || ( i == 1 ) ){
			arr[i] = 0;
		}
		else{
			arr[i] = 1;
		}
	}
	for ( i = 3; i < len / 2; i++ ){
		if ( !arr[i] ){
			continue;
		}
		for ( j = 2 * i; j < len; j += i ){
			arr[j] = 0;
		}
	}
	for ( i = 0; i < len; i++ ){
		if ( arr[i] ){
			count++;
		}
	}

	return count;
}

int main(void)
{
	int arr[100000];
	int i = 0;
	int preCount = 0;
	int curCount = 0;
	for ( i = 1000; i <= 100000; i += 1000 ){
		curCount = primeNumCount( arr, i );
		printf("%3d    ", curCount - preCount);
		preCount = curCount;
		if ( !( i % 8000 ) ){
			printf("\n");
		}
	}
	
	return 0;
}

程序输出:

分布挺均匀的。


© 著作权归作者所有

共有 人打赏支持
fzyz_sb
粉丝 408
博文 209
码字总数 447144
作品 0
武汉
程序员
《程序员面试宝典》精华 编程语言部分

《程序员面试宝典》精华 编程语言部分 正所谓取其精华,去其糟粕。本文谨记录下《程序员面试宝典》一些关键的知识点、易错点,对于一些虽然重要但书中没有解释清楚的地方不做记录。当然这里的...

modernizr
2014/08/11
410
2
《Beginning Linux Programming》读书笔记(四)

1, 读写空指针 先看第一种情况,printf试图访问空指针,以打印出字符串,而sprintf试图向空指针写入字符串,这时,linux会在GNU C函数库的帮助下,允许读空指针,但不允许写空指针。 复制代...

嗯哼9925
01/08
0
0
C++快速入门

只学过Java的我最近笔试接触到各种C++的题目,于是稍微恶补了一下C++的基础部分,以下内容是基于《21天学通C++》的部分读书笔记,按照章节写的。 第二章 C++程序的组成部分 ①#include 预处理...

waffle930
2016/10/02
56
0
阅读《C陷阱与缺陷》的知识增量

看完《C陷阱与缺陷》,忍不住要重新翻一下,记录一下与自己的惯性思维不符合的地方。记录的是知识的增量,是这几天的流量,而不是存量。 这本书是在ASCI C/C89订制之前写的,有些地方有疏漏。...

modernizr
2014/08/11
368
2
阅读《C陷阱与缺陷》的知识增量

看完《C陷阱与缺陷》,忍不住要重新翻一下,记录一下与自己的惯性思维不符合的地方。记录的是知识的增量,是这几天的流量,而不是存量。 这本书是在ASCI C/C89订制之前写的,有些地方有疏漏。...

modernizr
2014/06/30
613
7
入职学习(2)--一个程序员的成长史(22)

看了代是雄对这几个问题的回复之后,唐师傅叫代是雄先熟悉一下办公的电脑及一些办事流程,他要找一些资料作为培训计划中的材料。 代是雄先到公司的IT网站上去逛了一下,发现上面的东西相当的...

zhouzxi
2017/01/12
0
0
Head First C学习日志 第六章用堆进行动态存储

书中的例子是,在多座岛屿间规划航线,并记录,将岛屿作为节点,数据结构如下 typedef struct island { char *name; char *opens; char *closes; struct island *next;} island; 注意,递归结...

AlexTuan
2016/02/21
61
0
视觉SLAM十四讲 第六章程序出错(转载)

视觉SLAM十四讲 第六章程序出错(转载) 摘自:https://www.cnblogs.com/xueyuanaichiyu/p/7921382.html 问题: 首先贴出报错部分代码: 按照书上的例程编写代码,编译时报错(部分截图)如下...

bit_lgc
2017/12/13
0
0
《数据库索引设计与优化》笔记一

《数据库索引设计与优化》笔记一 码蜂笔记2017-09-289 阅读 索引数据库 第二章 表和索引结构 索引页和表页 目前页的大小一般是 或 的。页的大小决定了一个页可以存储多少个索引行、表行,以及...

码蜂笔记
2017/09/28
0
0
【整理】为什么在C/C++中总是对malloc的返回值进行强制转换

============= 文章1 ================ 首先要说的是,使用 malloc 函数,请包含 stdlib.h(C++ 中可以是 cstdlib),而不是 malloc.h 。因为 malloc.h 从来没有在 C 或者 C++ 标准中出现过!...

摩云飞
2013/05/07
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

页面输出JSON格式数据

package com.sysware.utils;import java.io.IOException;import javax.servlet.ServletResponse;import org.apache.log4j.Logger;import com.sysware.SyswareConstant;pub......

AK灬
21分钟前
0
0
springCloud-2.搭建Eureka Client的使用

1.使用IDEA,Spring Initializr创建 2.填写项目资料 3.选择spring boot版本,插件选择Cloud Discovery→Eureka Discovery 4.选择保存地址 5.修改application.yml eureka: client: s...

贺小康
24分钟前
0
0
CenOS 6.5 RPM 安装 elasticsearch 6.3.1

下载 wget --no-check-certificate https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.3.1.rpm...

阿白
27分钟前
0
0
1.4 创建虚拟机&1.5 安装CentOS7&1.6 配置ip(上)&1.7 配置ip(下)

1.4 创建虚拟机 知识点 虚拟机网络链接模式 桥连 直接将虚拟网卡桥接到一个物理网卡上面。需要手工为虚拟系统配置IP地址、子网掩码,而且还要和宿主机器处于同一网段,这样虚拟系统才能和宿主...

小丑鱼00
33分钟前
0
0
TrustAsia(亚洲诚信)助力看雪2018安全开发者峰会

2018年7月21日,看雪2018安全开发者峰会在北京国家会议中心圆满落下帷幕。拥有18年悠久历史的老牌安全技术社区——看雪学院联手国内最大开发者社区CSDN,汇聚业内顶尖的安全开发者和技术专家...

亚洲诚信
34分钟前
0
0
Spring注解介绍

@Resource、@AutoWired、@Qualifier 都用来注入对象。其中@Resource可以以 name 或 type 方式注入,@AutoWired只能以 type 方式注入,@Qualifier 只能以 name 方式注入。 但它们有一些细微区...

lqlm
44分钟前
0
0
32位汇编在64位Ubuntu上的汇编和连接

本教程使用的操作系统是Ubuntu Linux 18.04 LTS版本,汇编器是GNU AS(简称as),连接器是GNU LD(简称ld)。 以下是一段用于检测CPU品牌的汇编小程序(cpuid2.s): .section .dataoutput...

ryanliue
54分钟前
0
0
CentOS系统启动报错Failed to mount /sysroot解决方法

xfs_repair -v -L /dev/dm-0

Mr_Tea伯奕
今天
1
0
美团点评云真机平台实践

背景 随着美团点评业务越来越多,研发团队越来越庞大,对测试手机的需求显著增长。这对公司来说是一笔不小的开支,但现有测试手机资源分配不均,利用率也非常有限,导致各个团队开发、测试过...

美团技术团队
今天
0
0
eclipse SVN 项目重新定位

SVN 重新定位 1.方法一 首先:在Eclipse中选择Windows-> Show View->others 就会出现【SVN资源库/SVN Repositories】,选中后,点击确认; 然后:选中原有的地址,选择【重新定位/Relocate】...

qimh
今天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部