文档章节

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

fzyz_sb
 fzyz_sb
发布于 2013/09/14 21:36
字数 1124
阅读 217
收藏 2

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

没有更多内容

加载失败,请刷新页面

加载更多

day122-20181020-英语流利阅读-待学习

蜘蛛侠新片《毒液》来袭!导演灵感来自哪? Roxy 2018-10-20 1.今日导读 你还记得漫威宇宙中飞檐走壁的蜘蛛侠小可爱吗?在刚过去的国庆黄金周里,索尼影业发行的漫威超级英雄蜘蛛侠系列大片《...

飞鱼说编程
19分钟前
2
0
美团点评Docker容器管理平台

美团点评容器平台简介 本文介绍美团点评的Docker容器集群管理平台(以下简称“容器平台”)。该平台始于2015年,是基于美团云的基础架构和组件而开发的Docker容器集群管理平台。目前该平台为...

Skqing
25分钟前
2
0
JDK8笔记

判断两个对象是否相等 Objects.equals(value1, value2)

呼呼南风
今天
1
0
OSChina 周六乱弹 —— 到底谁是小公猫……

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @莱布妮子:分享Trivium的单曲《Throes Of Perdition》 《Throes Of Perdition》- Trivium 手机党少年们想听歌,请使劲儿戳(这里) @小鱼丁:...

小小编辑
今天
364
5
基础选择器

注意:本教程参考自网上流传的李兴华老师的jquery开发框架视频,但是苦于没有相应的配套笔记,由我本人做了相应的整理. 本次学习的内容 学习jquery提供的各种选择器的使用,掌握了jquery选择...

江戸川
今天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部